diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index 6beeb3d96..251207122 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -223,37 +223,36 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, std::string* out ) { + // copy the executable out of the CMakeFiles/ directory, so it is not + // removed at the end of TRY_RUN and the user can run it manually + // on the target platform. + std::string copyDest = this->Makefile->GetHomeOutputDirectory(); + copyDest += "/"; + copyDest += cmSystemTools::GetFilenameWithoutExtension( + this->OutputFile.c_str()); + copyDest += "-"; + copyDest += this->RunResultVariable; + copyDest += cmSystemTools::GetFilenameExtension(this->OutputFile.c_str()); + cmSystemTools::CopyFileAlways(this->OutputFile.c_str(), copyDest.c_str()); + + std::string resultFileName = this->Makefile->GetHomeOutputDirectory(); + resultFileName += "/TryRunResults.cmake"; + + std::string detailsString = "For details see "; + detailsString += resultFileName; std::string internalRunOutputName = this->RunResultVariable+"__" +this->CompileResultVariable+"__TRYRUN_OUTPUT"; bool error = false; - std::string info = "Source file: "; - info += srcFile + "\n"; - info += "Run arguments: "; - info += runArgs; - info += "\n"; - info += " Called from: " + this->Makefile->GetListFileStack(); if (this->Makefile->GetDefinition(this->RunResultVariable.c_str()) == 0) { // if the variables doesn't exist, create it with a helpful error text // and mark it as advanced std::string comment; - comment += "Run result of TRY_RUN().\n" - "This variable should indicate whether the executable would " - "have been able to run if it was executed on its target " - "platform.\n" - "If it would have been able to run, enter the exit code here " - "(in many cases 0 for success). If not, enter " - "\"FAILED_TO_RUN\" here."; - if (out!=0) - { - comment += "If it was able to run, also check the variable "; - comment += internalRunOutputName; - comment += " and set it appropriately."; - } - comment += "\n"; - comment += info; + comment += "Run result of TRY_RUN(), indicates whether the executable " + "would have been able to run on its target platform.\n"; + comment += detailsString; this->Makefile->AddCacheDefinition(this->RunResultVariable.c_str(), "PLEASE_FILL_OUT-FAILED_TO_RUN", comment.c_str(), @@ -277,21 +276,9 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, // if the variables doesn't exist, create it with a helpful error text // and mark it as advanced std::string comment; - comment += "Output of TRY_RUN().\n" - "This variable should contain the text, which the executable " - "run by TRY_RUN() would have printed on stdout and stderr, " - "if it was executed on its target platform.\n" - "The accompanying variable "; - comment += this->RunResultVariable; - comment += " indicates whether the executable would have been able to " - "run and its exit code." - "If the executable would not have been able to run, set "; - comment += internalRunOutputName; - comment += " empty. Otherwise check if the output is evaluated by the " - "calling CMake code. If this is the case, check the source " - "file what it would have printed if called with the given " - "arguments.\n"; - comment += info; + comment+="Output of TRY_RUN(), contains the text, which the executable " + "would have printed on stdout and stderr on its target platform.\n"; + comment += detailsString; this->Makefile->AddCacheDefinition(internalRunOutputName.c_str(), "PLEASE_FILL_OUT-NOTFOUND", @@ -311,9 +298,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, if (error) { static bool firstTryRun = true; - std::string fileName = this->Makefile->GetHomeOutputDirectory(); - fileName += "/TryRunResults.cmake"; - std::ofstream file(fileName.c_str(), + std::ofstream file(resultFileName.c_str(), firstTryRun ? std::ios::out : std::ios::app); if ( file ) { @@ -331,24 +316,36 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, std::string comment ="\n"; comment += this->RunResultVariable; comment += "\nindicates whether the executable would have been able to " - "run if it was\n" - "executed on its target platform. If it would have been able to " - "run, set it to\n" - "the exit code (in many cases 0 for success). If not, enter " - "\"FAILED_TO_RUN\".\n\n"; + "run if it was\n" + "executed on its target platform. If so, set "; + comment += this->RunResultVariable; + comment += " to\n" + "the exit code (in many cases 0 for success), otherwise " + "enter \"FAILED_TO_RUN\".\n"; if (out!=0) { comment += internalRunOutputName; comment += "\ncontains the text, which the executable " - " would have printed on stdout and stderr.\n" - "If the executable would not have been able to run, set it empty.\n" - "Otherwise check if the output is evaluated by the " - "calling CMake code. If so,\n" - "check what the source file would have printed when called with " - "the given arguments.\n\n"; + "would have printed on stdout and stderr.\n" + "If the executable would not have been able to run, set "; + comment += internalRunOutputName; + comment += " empty.\n" + "Otherwise check if the output is evaluated by the " + "calling CMake code. If so,\n" + "check what the source file would have printed when called " + "with the given arguments.\n"; } - - comment += info; + comment += "The "; + comment += this->CompileResultVariable; + comment += " variable holds the build result for this TRY_RUN().\n\n" + "Source file : "; + comment += srcFile + "\n"; + comment += "Executable : "; + comment += copyDest + "\n"; + comment += "Run arguments : "; + comment += runArgs; + comment += "\n"; + comment += " Called from: " + this->Makefile->GetListFileStack(); cmsys::SystemTools::ReplaceString(comment, "\n", "\n# "); file << comment << "\n\n"; @@ -374,7 +371,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, { errorMessage += " " + internalRunOutputName + " (advanced)\n"; } - errorMessage += info; + errorMessage += detailsString; cmSystemTools::Error(errorMessage.c_str()); return; } diff --git a/Tests/TryCompile/CMakeLists.txt b/Tests/TryCompile/CMakeLists.txt index a39f7c902..e3b495848 100644 --- a/Tests/TryCompile/CMakeLists.txt +++ b/Tests/TryCompile/CMakeLists.txt @@ -1,5 +1,29 @@ PROJECT(TryCompile) +MACRO(TEST_ASSERT value msg) + IF (NOT ${value}) + MESSAGE (SEND_ERROR "Assertion failure:" ${msg} ) + ENDIF (NOT ${value}) +ENDMACRO(TEST_ASSERT) + +MACRO(TEST_FAIL value msg) + IF (${value}) + MESSAGE (SEND_ERROR "Failing test succeeded:" ${msg} ) + ENDIF (${value}) +ENDMACRO(TEST_FAIL) + +MACRO(TEST_EXPECT_EXACT command expected) + IF(NOT "x${result}" STREQUAL "x${expected}") + MESSAGE(SEND_ERROR "${CMAKE_CURRENT_LIST_LINE}: TEST \"${command}\" failed: \"${result}\" expected: \"${expected}\"") + ENDIF(NOT "x${result}" STREQUAL "x${expected}") +ENDMACRO(TEST_EXPECT_EXACT command expected) + +MACRO(TEST_EXPECT_CONTAINS command expected) + IF(NOT "${result}" MATCHES "${expected}") + MESSAGE(SEND_ERROR "${CMAKE_CURRENT_LIST_LINE}: TEST \"${command}\" failed: \"${result}\" expected: \"${expected}\"") + ENDIF(NOT "${result}" MATCHES "${expected}") +ENDMACRO(TEST_EXPECT_CONTAINS command expected) + # try to compile a file that should compile # also check that COPY_FILE works TRY_COMPILE(SHOULD_PASS @@ -135,3 +159,35 @@ ENDIF("${COMPILE_OUTPUT}" MATCHES "hello world") IF(NOT "${RUN_OUTPUT}" MATCHES "hello world") MESSAGE(SEND_ERROR " RUN_OUTPUT didn't contain \"hello world\": \"${RUN_OUTPUT}\"") ENDIF(NOT "${RUN_OUTPUT}" MATCHES "hello world") + +####################################################################### +# +# also test that the CHECK_C_SOURCE_COMPILES, CHECK_CXX_SOURCE_COMPILES +# CHECK_C_SOURCE_RUNS and CHECK_CXX_SOURCE_RUNS macros work + +INCLUDE(CheckCSourceCompiles) +INCLUDE(CheckCXXSourceCompiles) +INCLUDE(CheckCSourceRuns) +INCLUDE(CheckCXXSourceRuns) + +CHECK_C_SOURCE_COMPILES("I dont build" C_BUILD_SHOULD_FAIL) +CHECK_C_SOURCE_COMPILES("int main() {return 0;}" C_BUILD_SHOULD_WORK) +CHECK_C_SOURCE_RUNS("int main() {return 1;}" C_RUN_SHOULD_FAIL) +CHECK_C_SOURCE_RUNS("int main() {return 0;}" C_RUN_SHOULD_WORK) + +TEST_FAIL(C_BUILD_SHOULD_FAIL "CHECK_C_SOURCE_COMPILES() succeeded, but should have failed") +TEST_ASSERT(C_BUILD_SHOULD_WORK "CHECK_C_SOURCE_COMPILES() failed") +TEST_FAIL(C_RUN_SHOULD_FAIL "CHECK_C_SOURCE_RUNS() succeeded, but should have failed") +TEST_ASSERT(C_RUN_SHOULD_WORK "CHECK_C_SOURCE_RUNS() failed") + +CHECK_CXX_SOURCE_COMPILES("I dont build" CXX_BUILD_SHOULD_FAIL) +CHECK_CXX_SOURCE_COMPILES("int main() {return 0;}" CXX_BUILD_SHOULD_WORK) +CHECK_CXX_SOURCE_RUNS("int main() {return 2;}" CXX_RUN_SHOULD_FAIL) +CHECK_CXX_SOURCE_RUNS("int main() {return 0;}" CXX_RUN_SHOULD_WORK) + +TEST_FAIL(CXX_BUILD_SHOULD_FAIL "CHECK_CXX_SOURCE_COMPILES() succeeded, but should have failed") +TEST_ASSERT(CXX_BUILD_SHOULD_WORK "CHECK_CXX_SOURCE_COMPILES() failed") +TEST_FAIL(CXX_RUN_SHOULD_FAIL "CHECK_CXX_SOURCE_RUNS() succeeded, but should have failed") +TEST_ASSERT(CXX_RUN_SHOULD_WORK "CHECK_CXX_SOURCE_RUNS() failed") + +