ENH: add tests for check_c_source_runs(), check_cxx_source_runs(),

check_c_source_compiles() and check_cxx_source_compiles()
-TRY_RUN in crosscompiling mode: copy the created executables to
CMAKE_BINARY_DIR so the user can run them manually on the target

Alex
This commit is contained in:
Alexander Neundorf 2007-07-31 14:52:01 -04:00
parent 7beee2df48
commit 67672b814a
2 changed files with 106 additions and 53 deletions

View File

@ -223,37 +223,36 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
std::string* out 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+"__" std::string internalRunOutputName = this->RunResultVariable+"__"
+this->CompileResultVariable+"__TRYRUN_OUTPUT"; +this->CompileResultVariable+"__TRYRUN_OUTPUT";
bool error = false; 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 (this->Makefile->GetDefinition(this->RunResultVariable.c_str()) == 0)
{ {
// if the variables doesn't exist, create it with a helpful error text // if the variables doesn't exist, create it with a helpful error text
// and mark it as advanced // and mark it as advanced
std::string comment; std::string comment;
comment += "Run result of TRY_RUN().\n" comment += "Run result of TRY_RUN(), indicates whether the executable "
"This variable should indicate whether the executable would " "would have been able to run on its target platform.\n";
"have been able to run if it was executed on its target " comment += detailsString;
"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;
this->Makefile->AddCacheDefinition(this->RunResultVariable.c_str(), this->Makefile->AddCacheDefinition(this->RunResultVariable.c_str(),
"PLEASE_FILL_OUT-FAILED_TO_RUN", "PLEASE_FILL_OUT-FAILED_TO_RUN",
comment.c_str(), 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 // if the variables doesn't exist, create it with a helpful error text
// and mark it as advanced // and mark it as advanced
std::string comment; std::string comment;
comment += "Output of TRY_RUN().\n" comment+="Output of TRY_RUN(), contains the text, which the executable "
"This variable should contain the text, which the executable " "would have printed on stdout and stderr on its target platform.\n";
"run by TRY_RUN() would have printed on stdout and stderr, " comment += detailsString;
"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;
this->Makefile->AddCacheDefinition(internalRunOutputName.c_str(), this->Makefile->AddCacheDefinition(internalRunOutputName.c_str(),
"PLEASE_FILL_OUT-NOTFOUND", "PLEASE_FILL_OUT-NOTFOUND",
@ -311,9 +298,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
if (error) if (error)
{ {
static bool firstTryRun = true; static bool firstTryRun = true;
std::string fileName = this->Makefile->GetHomeOutputDirectory(); std::ofstream file(resultFileName.c_str(),
fileName += "/TryRunResults.cmake";
std::ofstream file(fileName.c_str(),
firstTryRun ? std::ios::out : std::ios::app); firstTryRun ? std::ios::out : std::ios::app);
if ( file ) if ( file )
{ {
@ -331,24 +316,36 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
std::string comment ="\n"; std::string comment ="\n";
comment += this->RunResultVariable; comment += this->RunResultVariable;
comment += "\nindicates whether the executable would have been able to " comment += "\nindicates whether the executable would have been able to "
"run if it was\n" "run if it was\n"
"executed on its target platform. If it would have been able to " "executed on its target platform. If so, set ";
"run, set it to\n" comment += this->RunResultVariable;
"the exit code (in many cases 0 for success). If not, enter " comment += " to\n"
"\"FAILED_TO_RUN\".\n\n"; "the exit code (in many cases 0 for success), otherwise "
"enter \"FAILED_TO_RUN\".\n";
if (out!=0) if (out!=0)
{ {
comment += internalRunOutputName; comment += internalRunOutputName;
comment += "\ncontains the text, which the executable " comment += "\ncontains the text, which the executable "
" would have printed on stdout and stderr.\n" "would have printed on stdout and stderr.\n"
"If the executable would not have been able to run, set it empty.\n" "If the executable would not have been able to run, set ";
"Otherwise check if the output is evaluated by the " comment += internalRunOutputName;
"calling CMake code. If so,\n" comment += " empty.\n"
"check what the source file would have printed when called with " "Otherwise check if the output is evaluated by the "
"the given arguments.\n\n"; "calling CMake code. If so,\n"
"check what the source file would have printed when called "
"with the given arguments.\n";
} }
comment += "The ";
comment += info; 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# "); cmsys::SystemTools::ReplaceString(comment, "\n", "\n# ");
file << comment << "\n\n"; file << comment << "\n\n";
@ -374,7 +371,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
{ {
errorMessage += " " + internalRunOutputName + " (advanced)\n"; errorMessage += " " + internalRunOutputName + " (advanced)\n";
} }
errorMessage += info; errorMessage += detailsString;
cmSystemTools::Error(errorMessage.c_str()); cmSystemTools::Error(errorMessage.c_str());
return; return;
} }

View File

@ -1,5 +1,29 @@
PROJECT(TryCompile) 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 # try to compile a file that should compile
# also check that COPY_FILE works # also check that COPY_FILE works
TRY_COMPILE(SHOULD_PASS TRY_COMPILE(SHOULD_PASS
@ -135,3 +159,35 @@ ENDIF("${COMPILE_OUTPUT}" MATCHES "hello world")
IF(NOT "${RUN_OUTPUT}" MATCHES "hello world") IF(NOT "${RUN_OUTPUT}" MATCHES "hello world")
MESSAGE(SEND_ERROR " RUN_OUTPUT didn't contain \"hello world\": \"${RUN_OUTPUT}\"") MESSAGE(SEND_ERROR " RUN_OUTPUT didn't contain \"hello world\": \"${RUN_OUTPUT}\"")
ENDIF(NOT "${RUN_OUTPUT}" MATCHES "hello world") 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")