diff options
author | Robert Maynard <rmaynard@nvidia.com> | 2022-08-31 14:14:29 (GMT) |
---|---|---|
committer | Robert Maynard <rmaynard@nvidia.com> | 2022-09-07 19:08:41 (GMT) |
commit | 0c141b0393de6fccbef5ab54e93c70720345ed92 (patch) | |
tree | cd9e71e56595f115868155c366e9aae0f517d73b | |
parent | ecfc63a9b0e73b2c9525a4ba65ceb22759ab00fd (diff) | |
download | CMake-0c141b0393de6fccbef5ab54e93c70720345ed92.zip CMake-0c141b0393de6fccbef5ab54e93c70720345ed92.tar.gz CMake-0c141b0393de6fccbef5ab54e93c70720345ed92.tar.bz2 |
try_compile: Record output location instead of reverse computing it
Fixes #23887, #23942, #20163, #18288
-rw-r--r-- | Source/cmCoreTryCompile.cxx | 85 | ||||
-rw-r--r-- | Source/cmCoreTryCompile.h | 3 | ||||
-rw-r--r-- | Tests/RunCMake/Configure/CopyFileABI-override.cmake (renamed from Tests/RunCMake/Configure/FailCopyFileABI-override.cmake) | 3 | ||||
-rw-r--r-- | Tests/RunCMake/Configure/CopyFileABI-stdout.txt (renamed from Tests/RunCMake/Configure/FailCopyFileABI-stdout.txt) | 2 | ||||
-rw-r--r-- | Tests/RunCMake/Configure/CopyFileABI.cmake (renamed from Tests/RunCMake/Configure/FailCopyFileABI.cmake) | 2 | ||||
-rw-r--r-- | Tests/RunCMake/Configure/FailCopyFileABI-check.cmake | 14 | ||||
-rw-r--r-- | Tests/RunCMake/Configure/RunCMakeTest.cmake | 2 | ||||
-rw-r--r-- | Tests/RunCMake/try_compile/BuildType.cmake | 6 | ||||
-rw-r--r-- | Tests/RunCMake/try_compile/BuildTypeAsFlag.cmake | 7 | ||||
-rw-r--r-- | Tests/RunCMake/try_compile/OutputDirAsFlag.cmake | 7 | ||||
-rw-r--r-- | Tests/RunCMake/try_compile/old_and_new_signature_tests.cmake | 3 |
11 files changed, 65 insertions, 69 deletions
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 0a6c359..654c9a3 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -13,6 +13,7 @@ #include <cmext/string_view> #include "cmsys/Directory.hxx" +#include "cmsys/FStream.hxx" #include "cmArgumentParser.h" #include "cmExportTryCompileFileGenerator.h" @@ -694,6 +695,17 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, } 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 honorStandard = true; @@ -935,7 +947,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, if (this->SrcFileSignature) { std::string copyFileErrorMessage; - this->FindOutputFile(targetName, targetType); + this->FindOutputFile(targetName); if ((res == 0) && 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, - cmStateEnums::TargetType targetType) +void cmCoreTryCompile::FindOutputFile(const std::string& targetName) { this->FindErrorMessage.clear(); this->OutputFile.clear(); std::string tmpOutputFile = "/"; - if (targetType == cmStateEnums::EXECUTABLE) { - tmpOutputFile += targetName; - tmpOutputFile += - this->Makefile->GetSafeDefinition("CMAKE_EXECUTABLE_SUFFIX"); - } else // if (targetType == cmStateEnums::STATIC_LIBRARY) - { - tmpOutputFile += - this->Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_PREFIX"); - tmpOutputFile += targetName; - tmpOutputFile += - this->Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"); - } + tmpOutputFile += targetName; - // a list of directories where to search for the compilation result - // at first directly in the binary dir - std::vector<std::string> searchDirs; - searchDirs.emplace_back(); - - cmValue config = - 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)); + if (this->Makefile->GetGlobalGenerator()->IsMultiConfig()) { + tmpOutputFile += "_DEBUG"; } - 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)); + tmpOutputFile += "_loc"; + + std::string command = cmStrCat(this->BinaryDirectory, tmpOutputFile); + if (!cmSystemTools::FileExists(command)) { + std::ostringstream emsg; + emsg << "Unable to find the recorded try_compile output location:\n"; + emsg << cmStrCat(" ", command, "\n"); + this->FindErrorMessage = emsg.str(); + return; } - 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; - } + 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; - emsg << "Unable to find the executable at any of:\n"; - emsg << cmWrap(" " + this->BinaryDirectory, searchDirs, tmpOutputFile, "\n") - << "\n"; - this->FindErrorMessage = emsg.str(); + this->OutputFile = cmSystemTools::CollapseFullPath(outputFileLocation); } diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h index b483f0f..729aa9f 100644 --- a/Source/cmCoreTryCompile.h +++ b/Source/cmCoreTryCompile.h @@ -94,8 +94,7 @@ public: TryCompileCode. The result is stored in OutputFile. If nothing is found, the error message is stored in FindErrorMessage. */ - void FindOutputFile(const std::string& targetName, - cmStateEnums::TargetType targetType); + void FindOutputFile(const std::string& targetName); std::string BinaryDirectory; std::string OutputFile; diff --git a/Tests/RunCMake/Configure/FailCopyFileABI-override.cmake b/Tests/RunCMake/Configure/CopyFileABI-override.cmake index c633555..67f6ed5 100644 --- a/Tests/RunCMake/Configure/FailCopyFileABI-override.cmake +++ b/Tests/RunCMake/Configure/CopyFileABI-override.cmake @@ -1,5 +1,6 @@ # 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) if(NOT in_try_compile) set(CMAKE_EXECUTABLE_SUFFIX .missing) diff --git a/Tests/RunCMake/Configure/FailCopyFileABI-stdout.txt b/Tests/RunCMake/Configure/CopyFileABI-stdout.txt index 92fe233..6a856a4 100644 --- a/Tests/RunCMake/Configure/FailCopyFileABI-stdout.txt +++ b/Tests/RunCMake/Configure/CopyFileABI-stdout.txt @@ -1,4 +1,4 @@ -- Detecting C compiler ABI info --- Detecting C compiler ABI info - failed.* +-- Detecting C compiler ABI info - done.* -- Configuring done -- Generating done diff --git a/Tests/RunCMake/Configure/FailCopyFileABI.cmake b/Tests/RunCMake/Configure/CopyFileABI.cmake index 74efd97..4eee100 100644 --- a/Tests/RunCMake/Configure/FailCopyFileABI.cmake +++ b/Tests/RunCMake/Configure/CopyFileABI.cmake @@ -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) diff --git a/Tests/RunCMake/Configure/FailCopyFileABI-check.cmake b/Tests/RunCMake/Configure/FailCopyFileABI-check.cmake deleted file mode 100644 index db0cb0a..0000000 --- a/Tests/RunCMake/Configure/FailCopyFileABI-check.cmake +++ /dev/null @@ -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() diff --git a/Tests/RunCMake/Configure/RunCMakeTest.cmake b/Tests/RunCMake/Configure/RunCMakeTest.cmake index 9fd4499..750fa3c 100644 --- a/Tests/RunCMake/Configure/RunCMakeTest.cmake +++ b/Tests/RunCMake/Configure/RunCMakeTest.cmake @@ -1,9 +1,9 @@ include(RunCMake) run_cmake(ContinueAfterError) +run_cmake(CopyFileABI) run_cmake(CustomTargetAfterError) run_cmake(ErrorLogs) -run_cmake(FailCopyFileABI) # Use a single build tree for a few tests without cleaning. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/RerunCMake-build) diff --git a/Tests/RunCMake/try_compile/BuildType.cmake b/Tests/RunCMake/try_compile/BuildType.cmake new file mode 100644 index 0000000..f2709f8 --- /dev/null +++ b/Tests/RunCMake/try_compile/BuildType.cmake @@ -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" + ) diff --git a/Tests/RunCMake/try_compile/BuildTypeAsFlag.cmake b/Tests/RunCMake/try_compile/BuildTypeAsFlag.cmake new file mode 100644 index 0000000..e9384c7 --- /dev/null +++ b/Tests/RunCMake/try_compile/BuildTypeAsFlag.cmake @@ -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" + ) diff --git a/Tests/RunCMake/try_compile/OutputDirAsFlag.cmake b/Tests/RunCMake/try_compile/OutputDirAsFlag.cmake new file mode 100644 index 0000000..5c4dca5 --- /dev/null +++ b/Tests/RunCMake/try_compile/OutputDirAsFlag.cmake @@ -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" + ) diff --git a/Tests/RunCMake/try_compile/old_and_new_signature_tests.cmake b/Tests/RunCMake/try_compile/old_and_new_signature_tests.cmake index e156e12..f80d445 100644 --- a/Tests/RunCMake/try_compile/old_and_new_signature_tests.cmake +++ b/Tests/RunCMake/try_compile/old_and_new_signature_tests.cmake @@ -11,6 +11,9 @@ run_cmake(BadSources2) run_cmake(EmptyValueArgs) run_cmake(EmptyListArgs) run_cmake(TryRunArgs) +run_cmake(BuildType) +run_cmake(BuildTypeAsFlag) +run_cmake(OutputDirAsFlag) run_cmake(EnvConfig) |