mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-20 12:53:55 +08:00
try_compile: Record output location instead of reverse computing it
Fixes #23887, #23942, #20163, #18288
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
#include <cmext/string_view>
|
#include <cmext/string_view>
|
||||||
|
|
||||||
#include "cmsys/Directory.hxx"
|
#include "cmsys/Directory.hxx"
|
||||||
|
#include "cmsys/FStream.hxx"
|
||||||
|
|
||||||
#include "cmArgumentParser.h"
|
#include "cmArgumentParser.h"
|
||||||
#include "cmExportTryCompileFileGenerator.h"
|
#include "cmExportTryCompileFileGenerator.h"
|
||||||
@@ -694,6 +695,17 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
|
|||||||
}
|
}
|
||||||
fprintf(fout, ")\n");
|
fprintf(fout, ")\n");
|
||||||
|
|
||||||
|
/* Write out the output location of the target we are building */
|
||||||
|
std::string perConfigGenex;
|
||||||
|
if (this->Makefile->GetGlobalGenerator()->IsMultiConfig()) {
|
||||||
|
perConfigGenex = "_$<UPPER_CASE:$<CONFIG>>";
|
||||||
|
}
|
||||||
|
fprintf(fout,
|
||||||
|
"file(GENERATE OUTPUT "
|
||||||
|
"\"${CMAKE_BINARY_DIR}/%s%s_loc\"\n",
|
||||||
|
targetName.c_str(), perConfigGenex.c_str());
|
||||||
|
fprintf(fout, " CONTENT $<TARGET_FILE:%s>)\n", targetName.c_str());
|
||||||
|
|
||||||
bool warnCMP0067 = false;
|
bool warnCMP0067 = false;
|
||||||
bool honorStandard = true;
|
bool honorStandard = true;
|
||||||
|
|
||||||
@@ -935,7 +947,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
|
|||||||
|
|
||||||
if (this->SrcFileSignature) {
|
if (this->SrcFileSignature) {
|
||||||
std::string copyFileErrorMessage;
|
std::string copyFileErrorMessage;
|
||||||
this->FindOutputFile(targetName, targetType);
|
this->FindOutputFile(targetName);
|
||||||
|
|
||||||
if ((res == 0) && arguments.CopyFileTo) {
|
if ((res == 0) && arguments.CopyFileTo) {
|
||||||
std::string const& copyFile = *arguments.CopyFileTo;
|
std::string const& copyFile = *arguments.CopyFileTo;
|
||||||
@@ -1035,62 +1047,37 @@ void cmCoreTryCompile::CleanupFiles(std::string const& binDir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmCoreTryCompile::FindOutputFile(const std::string& targetName,
|
void cmCoreTryCompile::FindOutputFile(const std::string& targetName)
|
||||||
cmStateEnums::TargetType targetType)
|
|
||||||
{
|
{
|
||||||
this->FindErrorMessage.clear();
|
this->FindErrorMessage.clear();
|
||||||
this->OutputFile.clear();
|
this->OutputFile.clear();
|
||||||
std::string tmpOutputFile = "/";
|
std::string tmpOutputFile = "/";
|
||||||
if (targetType == cmStateEnums::EXECUTABLE) {
|
|
||||||
tmpOutputFile += targetName;
|
tmpOutputFile += targetName;
|
||||||
tmpOutputFile +=
|
|
||||||
this->Makefile->GetSafeDefinition("CMAKE_EXECUTABLE_SUFFIX");
|
if (this->Makefile->GetGlobalGenerator()->IsMultiConfig()) {
|
||||||
} else // if (targetType == cmStateEnums::STATIC_LIBRARY)
|
tmpOutputFile += "_DEBUG";
|
||||||
{
|
|
||||||
tmpOutputFile +=
|
|
||||||
this->Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_PREFIX");
|
|
||||||
tmpOutputFile += targetName;
|
|
||||||
tmpOutputFile +=
|
|
||||||
this->Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX");
|
|
||||||
}
|
}
|
||||||
|
tmpOutputFile += "_loc";
|
||||||
|
|
||||||
// a list of directories where to search for the compilation result
|
std::string command = cmStrCat(this->BinaryDirectory, tmpOutputFile);
|
||||||
// at first directly in the binary dir
|
if (!cmSystemTools::FileExists(command)) {
|
||||||
std::vector<std::string> searchDirs;
|
std::ostringstream emsg;
|
||||||
searchDirs.emplace_back();
|
emsg << "Unable to find the recorded try_compile output location:\n";
|
||||||
|
emsg << cmStrCat(" ", command, "\n");
|
||||||
cmValue config =
|
this->FindErrorMessage = emsg.str();
|
||||||
this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
|
|
||||||
// if a config was specified try that first
|
|
||||||
if (cmNonempty(config)) {
|
|
||||||
std::string tmp = cmStrCat('/', *config);
|
|
||||||
searchDirs.emplace_back(std::move(tmp));
|
|
||||||
}
|
|
||||||
searchDirs.emplace_back("/Debug");
|
|
||||||
|
|
||||||
// handle app-bundles (for targeting apple-platforms)
|
|
||||||
std::string app = "/" + targetName + ".app";
|
|
||||||
if (cmNonempty(config)) {
|
|
||||||
std::string tmp = cmStrCat('/', *config, app);
|
|
||||||
searchDirs.emplace_back(std::move(tmp));
|
|
||||||
}
|
|
||||||
std::string tmp = "/Debug" + app;
|
|
||||||
searchDirs.emplace_back(std::move(tmp));
|
|
||||||
searchDirs.emplace_back(std::move(app));
|
|
||||||
|
|
||||||
searchDirs.emplace_back("/Development");
|
|
||||||
|
|
||||||
for (std::string const& sdir : searchDirs) {
|
|
||||||
std::string command = cmStrCat(this->BinaryDirectory, sdir, tmpOutputFile);
|
|
||||||
if (cmSystemTools::FileExists(command)) {
|
|
||||||
this->OutputFile = cmSystemTools::CollapseFullPath(command);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string outputFileLocation;
|
||||||
|
cmsys::ifstream ifs(command.c_str());
|
||||||
|
cmSystemTools::GetLineFromStream(ifs, outputFileLocation);
|
||||||
|
if (!cmSystemTools::FileExists(outputFileLocation)) {
|
||||||
|
std::ostringstream emsg;
|
||||||
|
emsg << "Recorded try_compile output location doesn't exist:\n";
|
||||||
|
emsg << cmStrCat(" ", outputFileLocation, "\n");
|
||||||
|
this->FindErrorMessage = emsg.str();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream emsg;
|
this->OutputFile = cmSystemTools::CollapseFullPath(outputFileLocation);
|
||||||
emsg << "Unable to find the executable at any of:\n";
|
|
||||||
emsg << cmWrap(" " + this->BinaryDirectory, searchDirs, tmpOutputFile, "\n")
|
|
||||||
<< "\n";
|
|
||||||
this->FindErrorMessage = emsg.str();
|
|
||||||
}
|
}
|
||||||
|
@@ -94,8 +94,7 @@ public:
|
|||||||
TryCompileCode. The result is stored in OutputFile. If nothing is found,
|
TryCompileCode. The result is stored in OutputFile. If nothing is found,
|
||||||
the error message is stored in FindErrorMessage.
|
the error message is stored in FindErrorMessage.
|
||||||
*/
|
*/
|
||||||
void FindOutputFile(const std::string& targetName,
|
void FindOutputFile(const std::string& targetName);
|
||||||
cmStateEnums::TargetType targetType);
|
|
||||||
|
|
||||||
std::string BinaryDirectory;
|
std::string BinaryDirectory;
|
||||||
std::string OutputFile;
|
std::string OutputFile;
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
# Change the executable suffix that try_compile will use for
|
# Change the executable suffix that try_compile will use for
|
||||||
# COPY_FILE but not inside the test project. This forces failure.
|
# COPY_FILE but not inside the test project, to verify
|
||||||
|
# we can handle envs that try and break everything
|
||||||
get_property(in_try_compile GLOBAL PROPERTY IN_TRY_COMPILE)
|
get_property(in_try_compile GLOBAL PROPERTY IN_TRY_COMPILE)
|
||||||
if(NOT in_try_compile)
|
if(NOT in_try_compile)
|
||||||
set(CMAKE_EXECUTABLE_SUFFIX .missing)
|
set(CMAKE_EXECUTABLE_SUFFIX .missing)
|
@@ -1,4 +1,4 @@
|
|||||||
-- Detecting C compiler ABI info
|
-- Detecting C compiler ABI info
|
||||||
-- Detecting C compiler ABI info - failed.*
|
-- Detecting C compiler ABI info - done.*
|
||||||
-- Configuring done
|
-- Configuring done
|
||||||
-- Generating done
|
-- Generating done
|
@@ -1,2 +1,2 @@
|
|||||||
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/FailCopyFileABI-override.cmake)
|
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/CopyFileABI-override.cmake)
|
||||||
enable_language(C)
|
enable_language(C)
|
@@ -1,14 +0,0 @@
|
|||||||
set(log "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/CMakeError.log")
|
|
||||||
if(EXISTS "${log}")
|
|
||||||
file(READ "${log}" error_log)
|
|
||||||
else()
|
|
||||||
set(error_log "")
|
|
||||||
endif()
|
|
||||||
string(REPLACE "\r\n" "\n" regex "Cannot copy output executable.*
|
|
||||||
to destination specified by COPY_FILE:.*
|
|
||||||
Unable to find the executable at any of:
|
|
||||||
.*\\.missing")
|
|
||||||
if(NOT error_log MATCHES "${regex}")
|
|
||||||
string(REGEX REPLACE "\n" "\n " error_log " ${error_log}")
|
|
||||||
set(RunCMake_TEST_FAILED "Log file:\n ${log}\ndoes not have expected COPY_FILE failure message:\n${error_log}")
|
|
||||||
endif()
|
|
@@ -1,9 +1,9 @@
|
|||||||
include(RunCMake)
|
include(RunCMake)
|
||||||
|
|
||||||
run_cmake(ContinueAfterError)
|
run_cmake(ContinueAfterError)
|
||||||
|
run_cmake(CopyFileABI)
|
||||||
run_cmake(CustomTargetAfterError)
|
run_cmake(CustomTargetAfterError)
|
||||||
run_cmake(ErrorLogs)
|
run_cmake(ErrorLogs)
|
||||||
run_cmake(FailCopyFileABI)
|
|
||||||
|
|
||||||
# Use a single build tree for a few tests without cleaning.
|
# Use a single build tree for a few tests without cleaning.
|
||||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/RerunCMake-build)
|
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/RerunCMake-build)
|
||||||
|
6
Tests/RunCMake/try_compile/BuildType.cmake
Normal file
6
Tests/RunCMake/try_compile/BuildType.cmake
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
enable_language(C)
|
||||||
|
set(CMAKE_BUILD_TYPE RelWithDebInfo)
|
||||||
|
|
||||||
|
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
|
||||||
|
COPY_FILE "${CMAKE_CURRENT_BINARY_DIR}/out.bin"
|
||||||
|
)
|
7
Tests/RunCMake/try_compile/BuildTypeAsFlag.cmake
Normal file
7
Tests/RunCMake/try_compile/BuildTypeAsFlag.cmake
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
enable_language(C)
|
||||||
|
set(CMAKE_BUILD_TYPE RelWithDebInfo)
|
||||||
|
|
||||||
|
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
|
||||||
|
COPY_FILE "${CMAKE_CURRENT_BINARY_DIR}/out.bin"
|
||||||
|
CMAKE_FLAGS "-DCMAKE_BUILD_TYPE=Release"
|
||||||
|
)
|
7
Tests/RunCMake/try_compile/OutputDirAsFlag.cmake
Normal file
7
Tests/RunCMake/try_compile/OutputDirAsFlag.cmake
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
enable_language(C)
|
||||||
|
set(CMAKE_BUILD_TYPE RelWithDebInfo)
|
||||||
|
|
||||||
|
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
|
||||||
|
COPY_FILE "${CMAKE_CURRENT_BINARY_DIR}/out.bin"
|
||||||
|
CMAKE_FLAGS "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=bin"
|
||||||
|
)
|
@@ -11,6 +11,9 @@ run_cmake(BadSources2)
|
|||||||
run_cmake(EmptyValueArgs)
|
run_cmake(EmptyValueArgs)
|
||||||
run_cmake(EmptyListArgs)
|
run_cmake(EmptyListArgs)
|
||||||
run_cmake(TryRunArgs)
|
run_cmake(TryRunArgs)
|
||||||
|
run_cmake(BuildType)
|
||||||
|
run_cmake(BuildTypeAsFlag)
|
||||||
|
run_cmake(OutputDirAsFlag)
|
||||||
|
|
||||||
run_cmake(EnvConfig)
|
run_cmake(EnvConfig)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user