From 2c2291bbe03aec2dd6637a5311204f09ff6c58ba Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Wed, 7 Jan 2004 11:24:22 -0500 Subject: [PATCH] ENH: add new feature to ctest so that it can cmake, build and run a test executable --- Source/CMakeLists.txt | 502 ++++++++++++------- Source/cmCTest.cxx | 778 ++++++++++++++++++++++++++++- Source/cmCTest.h | 24 +- Source/cmSystemTools.cxx | 41 +- Source/cmSystemTools.h | 8 + Source/cmWin32ProcessExecution.cxx | 8 +- Source/cmake.cxx | 8 + Source/ctest.cxx | 281 +---------- 8 files changed, 1192 insertions(+), 458 deletions(-) diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 1260a5519..000691b0a 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -148,69 +148,125 @@ IF (NOT DART_ROOT) SET(MAKEPROGRAM ${CMAKE_MAKE_PROGRAM}) ENDIF (NOT DART_ROOT) -CONFIGURE_FILE( - ${CMake_SOURCE_DIR}/Source/cmaketest.h.in - ${CMake_BINARY_DIR}/Source/cmaketest.h ESCAPE_QUOTES) - -ADD_EXECUTABLE(cmaketest cmaketest.cxx) -TARGET_LINK_LIBRARIES(cmaketest CMakeLib) - IF(BUILD_TESTING) - ADD_TEST(CommandLineTest ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/CommandLineTest - ${CMake_BINARY_DIR}/Tests/CommandLineTest - CommandLineTest) + # This variable is set by cmake, however to + # test cmake we want to make sure that + # the ctest from this cmake is used for testing + # and not the ctest from the cmake building and testing + # cmake. + SET(CMAKE_CTEST_COMMAND "${EXECUTABLE_OUTPUT_PATH}/ctest") - ADD_TEST(CustomCommand ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/CustomCommand - ${CMake_BINARY_DIR}/Tests/CustomCommand - CustomCommand - ${CMake_BINARY_DIR}/Tests/CustomCommand/bin) + ADD_TEST(CommandLineTest ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/CommandLineTest" + "${CMake_BINARY_DIR}/Tests/CommandLineTest" + --build-two-config + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-project CommandLineTest + --test-command CommandLineTest) + + ADD_TEST(CustomCommand ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/CustomCommand" + "${CMake_BINARY_DIR}/Tests/CustomCommand" + --build-two-config + --build-generator ${CMAKE_GENERATOR} + --build-project CustomCommand + --build-makeprogram ${MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/CustomCommand/bin" + --test-command CustomCommand + ) - ADD_TEST(FindPackageTest ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/FindPackageTest - ${CMake_BINARY_DIR}/Tests/FindPackageTest - FindPackageTest) + ADD_TEST(FindPackageTest ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPackageTest" + "${CMake_BINARY_DIR}/Tests/FindPackageTest" + --build-two-config + --build-generator ${CMAKE_GENERATOR} + --build-project FindPackageTest + --build-makeprogram ${MAKEPROGRAM} + --test-command FindPackageTest) - ADD_TEST(SystemInformation ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/SystemInformation - ${CMake_BINARY_DIR}/Tests/SystemInformation - DumpInformation) + ADD_TEST(SystemInformation ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/SystemInformation" + "${CMake_BINARY_DIR}/Tests/SystemInformation" + --build-two-config + --build-generator ${CMAKE_GENERATOR} + --build-project DumpInformation + --build-makeprogram ${MAKEPROGRAM} + --test-command DumpInformation) - ADD_TEST(StringFileTest ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/StringFileTest - ${CMake_BINARY_DIR}/Tests/StringFileTest - StringFileTest) + ADD_TEST(StringFileTest ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/StringFileTest" + "${CMake_BINARY_DIR}/Tests/StringFileTest" + --build-two-config + --build-generator ${CMAKE_GENERATOR} + --build-project StringFileTest + --build-makeprogram ${MAKEPROGRAM} + --test-command StringFileTest) + + ADD_TEST(TryCompile ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/TryCompile" + "${CMake_BINARY_DIR}/Tests/TryCompile" + --build-generator ${CMAKE_GENERATOR} + --build-project TryCompile + --build-makeprogram ${MAKEPROGRAM} + --build-two-config + --test-command TryCompile) - ADD_TEST(TryCompile ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/TryCompile - ${CMake_BINARY_DIR}/Tests/TryCompile - TryCompile) + ADD_TEST(simple ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Simple" + "${CMake_BINARY_DIR}/Tests/Simple" + --build-generator ${CMAKE_GENERATOR} + --build-project Simple + --build-makeprogram ${MAKEPROGRAM} + --build-two-config + --test-command simple) - ADD_TEST(simple ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/Simple - ${CMake_BINARY_DIR}/Tests/Simple - simple) + ADD_TEST(conly ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/COnly" + "${CMake_BINARY_DIR}/Tests/COnly" + --build-generator ${CMAKE_GENERATOR} + --build-project conly + --build-makeprogram ${MAKEPROGRAM} + --build-two-config + --test-command conly) - ADD_TEST(conly ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/COnly - ${CMake_BINARY_DIR}/Tests/COnly - conly) + ADD_TEST(X11 ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/X11" + "${CMake_BINARY_DIR}/Tests/X11" + --build-generator ${CMAKE_GENERATOR} + --build-project UseX11 + --build-makeprogram ${MAKEPROGRAM} + --build-two-config + --test-command UseX11) - ADD_TEST(X11 ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/X11 - ${CMake_BINARY_DIR}/Tests/X11 - UseX11) + ADD_TEST(LoadedCommand ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/LoadCommand" + "${CMake_BINARY_DIR}/Tests/LoadCommand" + --build-generator ${CMAKE_GENERATOR} + --build-project LoadedCommand + --build-makeprogram ${MAKEPROGRAM} + --build-two-config + --test-command LoadedCommand) - ADD_TEST(LoadedCommand ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/LoadCommand - ${CMake_BINARY_DIR}/Tests/LoadCommand - LoadedCommand) - - ADD_TEST(LoadedCommandOneConfig ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/LoadCommand - ${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig - LoadedCommand ONLY_ONE_CONFIG) + ADD_TEST(LoadedCommandOneConfig ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/LoadCommand" + "${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig" + --build-generator ${CMAKE_GENERATOR} + --build-project LoadedCommand + --build-makeprogram ${MAKEPROGRAM} + --test-command LoadedCommand + ) # Como does not seem to support shared libraries. GET_FILENAME_COMPONENT(CMAKE_BASE_NAME ${CMAKE_CXX_COMPILER} NAME_WE) @@ -218,37 +274,62 @@ IF(BUILD_TESTING) SET(COMPILER_IS_COMO 1) ENDIF(CMAKE_BASE_NAME MATCHES "^como$") IF(NOT COMPILER_IS_COMO) - ADD_TEST(complex ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/Complex - ${CMake_BINARY_DIR}/Tests/Complex - complex - ${CMake_BINARY_DIR}/Tests/Complex/bin) + ADD_TEST(complex ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Complex" + "${CMake_BINARY_DIR}/Tests/Complex" + --build-two-config + --build-generator ${CMAKE_GENERATOR} + --build-project complex + --build-makeprogram ${MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Complex/bin" + --test-command complex + ) + + ADD_TEST(complexOneConfig ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Complex" + "${CMake_BINARY_DIR}/Tests/ComplexOneConfig" + --build-generator ${CMAKE_GENERATOR} + --build-project complex + --build-makeprogram ${MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/ComplexOneConfig/bin" + --test-command complex) - ADD_TEST(complexOneConfig ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/Complex - ${CMake_BINARY_DIR}/Tests/ComplexOneConfig - complex - ${CMake_BINARY_DIR}/Tests/ComplexOneConfig/bin ONLY_ONE_CONFIG) ENDIF(NOT COMPILER_IS_COMO) - ADD_TEST(Example ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Example - ${CMake_BINARY_DIR}/Example - helloDemo - ${CMake_BINARY_DIR}/Example/Demo - HELLO) + ADD_TEST(Example ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Example" + "${CMake_BINARY_DIR}/Example" + --build-generator ${CMAKE_GENERATOR} + --build-project HELLO + --build-makeprogram ${MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Example/Demo" + --test-command helloDemo + ) - ADD_TEST(testing ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/Testing - ${CMake_BINARY_DIR}/Tests/Testing - testing - ${CMake_BINARY_DIR}/Tests/Testing/bin) - - ADD_TEST(wrapping ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/Wrapping - ${CMake_BINARY_DIR}/Tests/Wrapping - wrapping - ${CMake_BINARY_DIR}/Tests/Wrapping/bin) + ADD_TEST(testing ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Testing" + "${CMake_BINARY_DIR}/Tests/Testing" + --build-generator ${CMAKE_GENERATOR} + --build-project testing + --build-makeprogram ${MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Testing/bin" + --test-command testing + ) + + ADD_TEST(wrapping ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Wrapping" + "${CMake_BINARY_DIR}/Tests/Wrapping" + --build-generator ${CMAKE_GENERATOR} + --build-project wrapping + --build-makeprogram ${MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin" + --test-command wrapping + ) INCLUDE ( ${CMAKE_ROOT}/Modules/FindQt.cmake ) MARK_AS_ADVANCED( @@ -258,119 +339,194 @@ IF(BUILD_TESTING) QT_UIC_EXE) IF (QT_FOUND) - ADD_TEST(qtwrapping ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/Wrapping - ${CMake_BINARY_DIR}/Tests/Wrapping - qtwrapping - ${CMake_BINARY_DIR}/Tests/Wrapping/bin - wrapping) + ADD_TEST(qtwrapping ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Wrapping" + "${CMake_BINARY_DIR}/Tests/Wrapping" + --build-generator ${CMAKE_GENERATOR} + --build-project Wrapping + --build-makeprogram ${MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin" + --test-command qtwrapping + ) ENDIF (QT_FOUND) - ADD_TEST(testdriver1 ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/TestDriver - ${CMake_BINARY_DIR}/Tests/TestDriver - TestDriverTest - ${CMake_BINARY_DIR}/Tests/Wrapping/bin - TestDriverTest test1) + ADD_TEST(testdriver1 ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/TestDriver" + "${CMake_BINARY_DIR}/Tests/TestDriver" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin" + --build-project TestDriverTest + --test-command TestDriverTest test1 + ) - ADD_TEST(testdriver2 ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/TestDriver - ${CMake_BINARY_DIR}/Tests/TestDriver - TestDriverTest - ${CMake_BINARY_DIR}/Tests/Wrapping/bin - TestDriverTest test2) + ADD_TEST(testdriver2 ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/TestDriver" + "${CMake_BINARY_DIR}/Tests/TestDriver" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin" + --build-project TestDriverTest + --test-command TestDriverTest test2 + ) - ADD_TEST(testdriver3 ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/TestDriver - ${CMake_BINARY_DIR}/Tests/TestDriver - TestDriverTest - ${CMake_BINARY_DIR}/Tests/Wrapping/bin - TestDriverTest subdir/test3) + ADD_TEST(testdriver3 ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/TestDriver" + "${CMake_BINARY_DIR}/Tests/TestDriver" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin" + --build-project TestDriverTest + --test-command TestDriverTest subdir/test3 + ) - ADD_TEST(dependency_w_libout ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/Dependency - ${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut - exec - ${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Exec - Dependency CMAKE_ARGS -DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Lib) + ADD_TEST(dependency_w_libout ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Dependency" + "${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut" + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Exec" + --build-project Dependency + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-options + -DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Lib + --test-command exec + ) - ADD_TEST(dependency_wo_lib_out ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/Dependency - ${CMake_BINARY_DIR}/Tests/Dependency/WOLibOut - exec - ${CMake_BINARY_DIR}/Tests/Dependency/WOLibOut/Exec - Dependency) - ADD_TEST(dependency2 ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/Dependency - ${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut - exec2 - ${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Exec2 - Dependency CMAKE_ARGS -DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Lib) + ADD_TEST(dependency_wo_lib_out ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Dependency" + "${CMake_BINARY_DIR}/Tests/Dependency/WOLibOut" + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Dependency/WOLibOut/Exec" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-project Dependency + --test-command exec + ) - ADD_TEST(dependency3 ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/Dependency - ${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut - exec3 - ${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Exec3 - Dependency CMAKE_ARGS -DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Lib) + ADD_TEST(dependency2 ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Dependency" + "${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut" + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Exec2" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-project Dependency + --build-options + -DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Lib + --test-command exec2 + ) - ADD_TEST(dependency4 ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/Dependency - ${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut - exec4 - ${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Exec4 - Dependency CMAKE_ARGS -DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Lib) + ADD_TEST(dependency3 ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Dependency" + "${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut" + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Exec3" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-project Dependency + --build-options + -DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Lib + --test-command exec3) - ADD_TEST(linkline ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/LinkLine - ${CMake_BINARY_DIR}/Tests/LinkLine - Exec - ${CMake_BINARY_DIR}/Tests/LinkLine - LinkLine) + ADD_TEST(dependency4 ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Dependency" + "${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut" + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Exec4" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-project Dependency + --build-options + -DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Dependency/WithLibOut/Lib + --test-command exec4 + ) - ADD_TEST(linkorder1 ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/LinkLineOrder - ${CMake_BINARY_DIR}/Tests/LinkLineOrder - Exec1 - ${CMake_BINARY_DIR}/Tests/LinkLineOrder - LinkLineOrder) + ADD_TEST(linkline ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/LinkLine" + "${CMake_BINARY_DIR}/Tests/LinkLine" + --build-exe-dir "${CMake_BINARY_DIR}/Tests/LinkLine" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-project Linkline + --test-command Exec + ) - ADD_TEST(linkorder2 ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/LinkLineOrder - ${CMake_BINARY_DIR}/Tests/LinkLineOrder - Exec2 - ${CMake_BINARY_DIR}/Tests/LinkLineOrder - LinkLineOrder) + ADD_TEST(linkorder1 ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/LinkLineOrder" + "${CMake_BINARY_DIR}/Tests/LinkLineOrder" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/LinkLineOrder" + --build-project LinkLineOrder + --test-command Exec1 + ) - ADD_TEST(curl ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Source/CTest/Curl - ${CMake_BINARY_DIR}/Tests/Curl - LIBCURL) + ADD_TEST(linkorder2 ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/LinkLineOrder" + "${CMake_BINARY_DIR}/Tests/LinkLineOrder" + --build-exe-dir "${CMake_BINARY_DIR}/Tests/LinkLineOrder" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-project LinkLineOrder + --test-command Exec2 + ) - ADD_TEST(kwsys ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Source/kwsys - ${CMake_BINARY_DIR}/Tests/kwsys - test1 - ${CMake_BINARY_DIR}/Tests/kwsys - kwsys) + ADD_TEST(curl ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Source/CTest/Curl" + "${CMake_BINARY_DIR}/Tests/Curl" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-project LIBCURL + --test-command LIBCURL) + + ADD_TEST(kwsys ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Source/kwsys" + "${CMake_BINARY_DIR}/Tests/kwsys" + --build-exe-dir "${CMake_BINARY_DIR}/Tests/kwsys" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-project kwsys + --test-command test1 + ) IF (APPLE) - ADD_TEST(objc++ ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/Objc++ - ${CMake_BINARY_DIR}/Tests/Objc++ - objc++) + ADD_TEST(objc++ ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Objc++" + "${CMake_BINARY_DIR}/Tests/Objc++" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-project objc++ + --test-command objc++ + ) ENDIF (APPLE) IF (CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE OR WXWINDOWS_INCLUDE_DIR) # Will be set if the wxwindows gui is on - ADD_TEST(UseWX ${EXECUTABLE_OUTPUT_PATH}/cmaketest - ${CMake_SOURCE_DIR}/Tests/UseWX - ${CMake_BINARY_DIR}/Tests/UseWX - UseWX - ${CMake_BINARY_DIR}/Tests/UseWX - UsewxWindows - CMAKE_ARGS -DCMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE:FILEPATH=${CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE}) + ADD_TEST(UseWX ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/UseWX" + "${CMake_BINARY_DIR}/Tests/UseWX" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${MAKEPROGRAM} + --build-exe-dir ${CMake_BINARY_DIR}/Tests/UseWX + --build-project UsewxWindows + --build-options CMAKE_ARGS -DCMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE:FILEPATH=${CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE} + --test-command UseWX + ) + + ENDIF (CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE OR WXWINDOWS_INCLUDE_DIR) IF(UNIX) diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 726f39fc6..bac7b388c 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -304,6 +304,7 @@ bool TryExecutable(const char *dir, const char *file, cmCTest::cmCTest() { + m_BuildTwoConfig = false; m_UseIncludeRegExp = false; m_UseExcludeRegExp = false; m_UseExcludeRegExpFirst = false; @@ -1961,7 +1962,7 @@ void cmCTest::ProcessDirectory(cmCTest::tm_VectorOfStrings &passed, } else if ( res == cmsysProcess_State_Error ) { - fprintf(stderr,"***Bad command\n"); + fprintf(stderr,"***Bad command %d\n", res); cres.m_Status = cmCTest::BAD_COMMAND; } else @@ -2818,6 +2819,27 @@ int cmCTest::RunMakeCommand(const char* command, std::string* output, int cmCTest::RunTest(std::vector argv, std::string* output, int *retVal) { + std::string cmd = argv[0]; + if(cmSystemTools::SameFile(argv[0], m_CTestSelf.c_str())) + { + cmCTest inst; + std::vector args; + for(int i =0; i < argv.size(); ++i) + { + if(argv[i]) + { + args.push_back(argv[i]); + } + } + *retVal = inst.Run(args, output); + if(m_Verbose) + { + std::cout << "Internal cmCTest object used to run test.\n"; + std::cout << *output << "\n"; + } + return cmsysProcess_State_Exited; + } + std::vector tempOutput; if ( output ) { @@ -2826,7 +2848,7 @@ int cmCTest::RunTest(std::vector argv, std::string* output, int *re cmsysProcess* cp = cmsysProcess_New(); cmsysProcess_SetCommand(cp, &*argv.begin()); - //std::cout << "Command is: " << argv[0] << std::endl; +// std::cout << "Command is: " << argv[0] << std::endl; if(cmSystemTools::GetRunCommandHideConsole()) { cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1); @@ -2876,7 +2898,6 @@ int cmCTest::RunTest(std::vector argv, std::string* output, int *re std::cout.flush(); } } - cmsysProcess_Delete(cp); return result; @@ -3396,6 +3417,756 @@ int cmCTest::GenerateNotesFile(const char* cfiles) return 0; } +int cmCTest::Run(std::vectorconst& args, std::string* output) +{ + this->FindRunningCMake(args[0].c_str()); + bool cmakeAndTest = false; + for(unsigned int i=1; i < args.size(); ++i) + { + std::string arg = args[i]; + if(arg.find("-C",0) == 0 && i < args.size() - 1) + { + i++; + this->m_ConfigType = args[i]; + } + + if( arg.find("-V",0) == 0 || arg.find("--verbose",0) == 0 ) + { + this->m_Verbose = true; + } + + if( arg.find("-N",0) == 0 || arg.find("--show-only",0) == 0 ) + { + this->m_ShowOnly = true; + } + + if( arg.find("-S",0) == 0 && i < args.size() - 1 ) + { + this->m_RunConfigurationScript = true; + i++; + this->m_ConfigurationScript = args[i]; + } + + if( arg.find("-D",0) == 0 && i < args.size() - 1 ) + { + this->m_DartMode = true; + i++; + std::string targ = args[i]; + if ( targ == "Experimental" ) + { + this->SetTestModel(cmCTest::EXPERIMENTAL); + this->SetTest("Start"); + this->SetTest("Configure"); + this->SetTest("Build"); + this->SetTest("Test"); + this->SetTest("Coverage"); + this->SetTest("Submit"); + } + else if ( targ == "ExperimentalStart" ) + { + this->SetTestModel(cmCTest::EXPERIMENTAL); + this->SetTest("Start"); + } + else if ( targ == "ExperimentalUpdate" ) + { + this->SetTestModel(cmCTest::EXPERIMENTAL); + this->SetTest("Update"); + } + else if ( targ == "ExperimentalConfigure" ) + { + this->SetTestModel(cmCTest::EXPERIMENTAL); + this->SetTest("Configure"); + } + else if ( targ == "ExperimentalBuild" ) + { + this->SetTestModel(cmCTest::EXPERIMENTAL); + this->SetTest("Build"); + } + else if ( targ == "ExperimentalTest" ) + { + this->SetTestModel(cmCTest::EXPERIMENTAL); + this->SetTest("Test"); + } + else if ( targ == "ExperimentalMemCheck" || targ == "ExperimentalPurify" ) + { + this->SetTestModel(cmCTest::EXPERIMENTAL); + this->SetTest("MemCheck"); + } + else if ( targ == "ExperimentalCoverage" ) + { + this->SetTestModel(cmCTest::EXPERIMENTAL); + this->SetTest("Coverage"); + } + else if ( targ == "ExperimentalSubmit" ) + { + this->SetTestModel(cmCTest::EXPERIMENTAL); + this->SetTest("Submit"); + } + else if ( targ == "Continuous" ) + { + this->SetTestModel(cmCTest::CONTINUOUS); + this->SetTest("Start"); + this->SetTest("Update"); + this->SetTest("Configure"); + this->SetTest("Build"); + this->SetTest("Test"); + this->SetTest("Coverage"); + this->SetTest("Submit"); + } + else if ( targ == "ContinuousStart" ) + { + this->SetTestModel(cmCTest::CONTINUOUS); + this->SetTest("Start"); + } + else if ( targ == "ContinuousUpdate" ) + { + this->SetTestModel(cmCTest::CONTINUOUS); + this->SetTest("Update"); + } + else if ( targ == "ContinuousConfigure" ) + { + this->SetTestModel(cmCTest::CONTINUOUS); + this->SetTest("Configure"); + } + else if ( targ == "ContinuousBuild" ) + { + this->SetTestModel(cmCTest::CONTINUOUS); + this->SetTest("Build"); + } + else if ( targ == "ContinuousTest" ) + { + this->SetTestModel(cmCTest::CONTINUOUS); + this->SetTest("Test"); + } + else if ( targ == "ContinuousMemCheck" || targ == "ContinuousPurify" ) + { + this->SetTestModel(cmCTest::CONTINUOUS); + this->SetTest("MemCheck"); + } + else if ( targ == "ContinuousCoverage" ) + { + this->SetTestModel(cmCTest::CONTINUOUS); + this->SetTest("Coverage"); + } + else if ( targ == "ContinuousSubmit" ) + { + this->SetTestModel(cmCTest::CONTINUOUS); + this->SetTest("Submit"); + } + else if ( targ == "Nightly" ) + { + this->SetTestModel(cmCTest::NIGHTLY); + this->SetTest("Start"); + this->SetTest("Update"); + this->SetTest("Configure"); + this->SetTest("Build"); + this->SetTest("Test"); + this->SetTest("Coverage"); + this->SetTest("Submit"); + } + else if ( targ == "NightlyStart" ) + { + this->SetTestModel(cmCTest::NIGHTLY); + this->SetTest("Start"); + } + else if ( targ == "NightlyUpdate" ) + { + this->SetTestModel(cmCTest::NIGHTLY); + this->SetTest("Update"); + } + else if ( targ == "NightlyConfigure" ) + { + this->SetTestModel(cmCTest::NIGHTLY); + this->SetTest("Configure"); + } + else if ( targ == "NightlyBuild" ) + { + this->SetTestModel(cmCTest::NIGHTLY); + this->SetTest("Build"); + } + else if ( targ == "NightlyTest" ) + { + this->SetTestModel(cmCTest::NIGHTLY); + this->SetTest("Test"); + } + else if ( targ == "NightlyMemCheck" || targ == "NightlyPurify" ) + { + this->SetTestModel(cmCTest::NIGHTLY); + this->SetTest("MemCheck"); + } + else if ( targ == "NightlyCoverage" ) + { + this->SetTestModel(cmCTest::NIGHTLY); + this->SetTest("Coverage"); + } + else if ( targ == "NightlySubmit" ) + { + this->SetTestModel(cmCTest::NIGHTLY); + this->SetTest("Submit"); + } + else if ( targ == "MemoryCheck" ) + { + this->SetTestModel(cmCTest::EXPERIMENTAL); + this->SetTest("Start"); + this->SetTest("Configure"); + this->SetTest("Build"); + this->SetTest("MemCheck"); + this->SetTest("Coverage"); + this->SetTest("Submit"); + } + else if ( targ == "NightlyMemoryCheck" ) + { + this->SetTestModel(cmCTest::NIGHTLY); + this->SetTest("Start"); + this->SetTest("Update"); + this->SetTest("Configure"); + this->SetTest("Build"); + this->SetTest("MemCheck"); + this->SetTest("Coverage"); + this->SetTest("Submit"); + } + } + + if( ( arg.find("-T",0) == 0 ) && + (i < args.size() -1) ) + { + this->m_DartMode = true; + i++; + this->SetTest(args[i].c_str()); + } + + if( ( arg.find("-M",0) == 0 || arg.find("--test-model",0) == 0 ) && + (i < args.size() -1) ) + { + i++; + std::string const& str = args[i]; + if ( str == "NIGHTLY" || str == "nightly" || str == "Nightly" ) + { + this->SetTestModel(cmCTest::NIGHTLY); + } + else if ( str == "CONTINUOUS" || str == "continuous" || + str == "Continuous" ) + { + this->SetTestModel(cmCTest::CONTINUOUS); + std::cout << "Continuous" << std::endl; + } + else + { + this->SetTestModel(cmCTest::EXPERIMENTAL); + } + } + + if(arg.find("-R",0) == 0 && i < args.size() - 1) + { + this->m_UseIncludeRegExp = true; + i++; + this->m_IncludeRegExp = args[i]; + } + + if(arg.find("-E",0) == 0 && i < args.size() - 1) + { + this->m_UseExcludeRegExp = true; + i++; + this->m_ExcludeRegExp = args[i]; + this->m_UseExcludeRegExpFirst = this->m_UseIncludeRegExp ? false : true; + } + + if(arg.find("-A",0) == 0 && i < args.size() - 1) + { + this->m_DartMode = true; + this->SetTest("Notes"); + i++; + this->SetNotesFiles(args[i].c_str()); + } + + // --build-and-test options + if(arg.find("--build-and-test",0) == 0 && i < args.size() - 1) + { + cmakeAndTest = true; + if(i+2 < args.size()) + { + i++; + m_SourceDir = args[i]; + i++; + m_BinaryDir = args[i]; + // dir must exist before CollapseFullPath is called + cmSystemTools::MakeDirectory(m_BinaryDir.c_str()); + m_BinaryDir = cmSystemTools::CollapseFullPath(m_BinaryDir.c_str()); + m_SourceDir = cmSystemTools::CollapseFullPath(m_SourceDir.c_str()); + } + else + { + std::cerr << "--build-and-test must have source and binary dir\n"; + } + } + if(arg.find("--build-target",0) == 0 && i < args.size() - 1) + { + i++; + m_BuildTarget = args[i]; + } + if(arg.find("--build-two-config",0) == 0 && i < args.size() - 1) + { + m_BuildTwoConfig = true; + } + if(arg.find("--build-exe-dir",0) == 0 && i < args.size() - 1) + { + i++; + m_ExecutableDirectory = args[i]; + } + if(arg.find("--build-generator",0) == 0 && i < args.size() - 1) + { + i++; + m_BuildGenerator = args[i]; + } + if(arg.find("--build-project",0) == 0 && i < args.size() - 1) + { + i++; + m_BuildProject = args[i]; + } + if(arg.find("--build-makeprogram",0) == 0 && i < args.size() - 1) + { + i++; + m_BuildMakeProgram = args[i]; + } + if(arg.find("--build-noclean",0) == 0 && i < args.size() - 1) + { + m_BuildNoClean = true; + } + if(arg.find("--build-options",0) == 0 && i < args.size() - 1) + { + ++i; + bool done = false; + while(i < args.size() && !done) + { + m_BuildOptions.push_back(args[i]); + if(i+1 < args.size() + && (args[i+1] == "--build-target" || args[i+1] == "--test-command")) + { + done = true; + } + else + { + ++i; + } + } + if(i < args.size()) + { + --i; + } + } + if(arg.find("--test-command",0) == 0 && i < args.size() - 1) + { + ++i; + m_TestCommand = args[i]; + while(i+1 < args.size()) + { + ++i; + m_TestCommandArgs.push_back(args[i]); + } + } + } + + if(cmakeAndTest) + { + return this->RunCMakeAndTest(output); + } + + int res; + // call process directory + if (this->m_RunConfigurationScript) + { + res = this->RunConfigurationScript(); + } + else + { + this->Initialize(); + res = this->ProcessTests(); + this->Finalize(); + } + return res; +} + +void cmCTest::FindRunningCMake(const char* arg0) +{ + // Find our own executable. + std::vector failures; + m_CTestSelf = arg0; + cmSystemTools::ConvertToUnixSlashes(m_CTestSelf); + failures.push_back(m_CTestSelf); + m_CTestSelf = cmSystemTools::FindProgram(m_CTestSelf.c_str()); + if(!cmSystemTools::FileExists(m_CTestSelf.c_str())) + { + failures.push_back(m_CTestSelf); + m_CTestSelf = "/usr/local/bin/ctest"; + } + if(!cmSystemTools::FileExists(m_CTestSelf.c_str())) + { + failures.push_back(m_CTestSelf); + cmOStringStream msg; + msg << "CTEST can not find the command line program cmake.\n"; + msg << " argv[0] = \"" << arg0 << "\"\n"; + msg << " Attempted paths:\n"; + std::vector::iterator i; + for(i=failures.begin(); i != failures.end(); ++i) + { + msg << " \"" << i->c_str() << "\"\n"; + } + cmSystemTools::Error(msg.str().c_str()); + } + std::string dir; + std::string file; + if(cmSystemTools::SplitProgramPath(m_CTestSelf.c_str(), + dir, + file, + true)) + { + m_CMakeSelf = dir += "/cmake"; + m_CMakeSelf += cmSystemTools::GetExecutableExtension(); + if(!cmSystemTools::FileExists(m_CMakeSelf.c_str())) + { + cmOStringStream msg; + failures.push_back(m_CMakeSelf); + msg << "CTEST can not find the command line program cmake.\n"; + msg << " argv[0] = \"" << arg0 << "\"\n"; + msg << " Attempted path:\n"; + msg << " \"" << m_CMakeSelf.c_str() << "\"\n"; + cmSystemTools::Error(msg.str().c_str()); + } + } +} + +void CMakeMessageCallback(const char* m, const char* title, bool& nomore, void* s) +{ + std::string* out = (std::string*)s; + *out += m; + *out += "\n"; +} + +void CMakeStdoutCallback(const char* m, int len, void* s) +{ + std::string* out = (std::string*)s; + out->append(m, len); +} + +int cmCTest::RunCMakeAndTest(std::string* outstring) +{ + cmSystemTools::ResetErrorOccuredFlag(); + std::string cmakeOutString; + cmSystemTools::SetErrorCallback(CMakeMessageCallback, &cmakeOutString); + cmSystemTools::SetStdoutCallback(CMakeStdoutCallback, &cmakeOutString); + cmOStringStream out; + cmake cm; + // default to the build type of ctest itself + if(m_ConfigType.size() == 0) + { +#ifdef CMAKE_INTDIR + m_ConfigType = CMAKE_INTDIR; +#endif + } + + std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); + out << "Internal cmake changing into directory: " << m_BinaryDir << "\n"; + if (!cmSystemTools::FileIsDirectory(m_BinaryDir.c_str())) + { + cmSystemTools::MakeDirectory(m_BinaryDir.c_str()); + } + cmSystemTools::ChangeDirectory(m_BinaryDir.c_str()); + std::vector args; + args.push_back(m_CMakeSelf); + args.push_back(m_SourceDir); + if(m_BuildGenerator.size()) + { + std::string generator = "-G"; + generator += m_BuildGenerator; + args.push_back(generator); + } + + int k; + for(k=0; k < m_BuildOptions.size(); ++k) + { + args.push_back(m_BuildOptions[k]); + } + if (cm.Run(args) != 0) + { + std::cerr << "Error: cmake execution failed\n"; + // return to the original directory + cmSystemTools::ChangeDirectory(cwd.c_str()); + return 1; + } + if(m_BuildTwoConfig) + { + if (cm.Run(args) != 0) + { + std::cerr << "Error: cmake execution failed\n"; + // return to the original directory + cmSystemTools::ChangeDirectory(cwd.c_str()); + return 1; + } + } + cmSystemTools::SetErrorCallback(0, 0); + if(outstring) + { + *outstring += cmakeOutString; + } + else + { + std::cout << cmakeOutString << "\n"; + } + + cmListFileCache::GetInstance()->ClearCache(); + if(m_BuildMakeProgram.size() == 0) + { + std::cerr << "Error: cmake does not have a valid MAKEPROGRAM\n"; + std::cerr << "Did you specify a --build-makeprogram and a --build-generator?\n"; + } + int retVal = 0; + int ret = 0; + + std::string makeCommand = cmSystemTools::ConvertToOutputPath(m_BuildMakeProgram.c_str()); + std::string lowerCaseCommand = cmSystemTools::LowerCase(makeCommand); + // if msdev is the make program then do the following + // MSDEV 6.0 + if(lowerCaseCommand.find("msdev") != std::string::npos) + { + // if there are spaces in the makeCommand, assume a full path + // and convert it to a path with no spaces in it as the + // RunSingleCommand does not like spaces +#if defined(_WIN32) && !defined(__CYGWIN__) + if(makeCommand.find(' ') != std::string::npos) + { + cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand); + } +#endif + makeCommand += " "; + makeCommand += m_BuildProject; + makeCommand += ".dsw /MAKE \"ALL_BUILD - "; + makeCommand += m_ConfigType; + if(m_BuildNoClean) + { + makeCommand += "\" /BUILD"; + } + else + { + makeCommand += "\" /REBUILD"; + } + } + // MSDEV 7.0 .NET + else if (lowerCaseCommand.find("devenv") != std::string::npos) + { +#if defined(_WIN32) && !defined(__CYGWIN__) + if(makeCommand.find(' ') != std::string::npos) + { + cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand); + } +#endif + makeCommand += " "; + makeCommand += m_BuildProject; + makeCommand += ".sln "; + if(m_BuildNoClean) + { + makeCommand += "/build "; + } + else + { + makeCommand += "/rebuild "; + } + makeCommand += m_ConfigType + " /project ALL_BUILD"; + } + else if (lowerCaseCommand.find("make") != std::string::npos) + { + // assume a make sytle program + // clean first + if(!m_BuildNoClean) + { + std::string cleanCommand = makeCommand; + cleanCommand += " clean"; + out << "Running make clean command: " << cleanCommand.c_str() << " ...\n"; + retVal = 0; + std::string output; + if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), &output, &retVal) || + retVal) + { + out << "Error: " << cleanCommand.c_str() << " execution failed\n"; + out << output.c_str() << "\n"; + // return to the original directory + cmSystemTools::ChangeDirectory(cwd.c_str()); + out << "Return value: " << retVal << std::endl; + if(outstring) + { + *outstring = out.str(); + } + else + { + std::cerr << out << "\n"; + } + return 1; + } + } + + if(m_BuildTarget.size()) + { + makeCommand += " "; + makeCommand += m_BuildTarget; + } + } + + // command line make program + + out << "Running make command: " << makeCommand.c_str() << " ...\n"; + retVal = 0; + std::string output; + if (!cmSystemTools::RunSingleCommand(makeCommand.c_str(), &output, &retVal, 0, false)) + { + out << "Error: " << makeCommand.c_str() << " execution failed\n"; + out << output.c_str() << "\n"; + // return to the original directory + cmSystemTools::ChangeDirectory(cwd.c_str()); + out << "Return value: " << retVal << std::endl; + if(outstring) + { + *outstring = out.str(); + } + else + { + std::cerr << out << "\n"; + } + return 1; + } + if ( retVal ) + { + cmSystemTools::Error("Building of project failed\n"); + if(outstring) + { + *outstring += output; + *outstring += "\n"; + } + else + { + std::cout << output << "\n"; + } + // return to the original directory + cmSystemTools::ChangeDirectory(cwd.c_str()); + ret = 1; + } + + if(outstring) + { + *outstring += output; + } + +// now run the compiled test if we can find it + // See if the executable exists as written. + std::vector failed; + std::string fullPath; + if(cmSystemTools::FileExists(m_TestCommand.c_str())) + { + fullPath = cmSystemTools::CollapseFullPath(m_TestCommand.c_str()); + } + else + { + failed.push_back(m_TestCommand); + } + std::string tryPath = m_TestCommand; + tryPath += cmSystemTools::GetExecutableExtension(); + if(cmSystemTools::FileExists(tryPath.c_str())) + { + fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str()); + } + else + { + failed.push_back(tryPath); + } + // try the Debug extension + tryPath = m_ConfigType + "/"; + tryPath += cmSystemTools::GetFilenameName(m_TestCommand); + if(cmSystemTools::FileExists(tryPath.c_str())) + { + fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str()); + } + else + { + failed.push_back(tryPath); + } + tryPath += cmSystemTools::GetExecutableExtension(); + if(cmSystemTools::FileExists(tryPath.c_str())) + { + fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str()); + } + else + { + failed.push_back(tryPath); + } + tryPath = m_ExecutableDirectory; + tryPath += "/"; + tryPath += m_TestCommand; + tryPath += cmSystemTools::GetExecutableExtension(); + if(cmSystemTools::FileExists(tryPath.c_str())) + { + fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str()); + } + else + { + failed.push_back(tryPath); + } + tryPath = m_ExecutableDirectory; + tryPath += "/"; + tryPath += m_ConfigType + "/"; + tryPath += m_TestCommand; + tryPath += cmSystemTools::GetExecutableExtension(); + if(cmSystemTools::FileExists(tryPath.c_str())) + { + fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str()); + } + else + { + failed.push_back(tryPath); + } + if(!cmSystemTools::FileExists(fullPath.c_str())) + { + out << "Could not find path to executable, perhaps it was not built: " << + m_TestCommand << "\n"; + out << "tried to find it in these places:\n"; + for(unsigned int i=0; i < failed.size(); ++i) + { + out << failed[i] << "\n"; + } + if(outstring) + { + *outstring += out.str(); + } + else + { + std::cerr << out.str(); + } + // return to the original directory + cmSystemTools::ChangeDirectory(cwd.c_str()); + return 1; + } + + std::vector testCommand; + testCommand.push_back(fullPath.c_str()); + for(int k=0; k < m_TestCommandArgs.size(); ++k) + { + out << m_TestCommandArgs[k].c_str() << "\n"; + testCommand.push_back(m_TestCommandArgs[k].c_str()); + } + testCommand.push_back(0); + std::string outs; + int retval = 0; + out << "Running test executable: " << fullPath << "\n"; + this->RunTest(testCommand, &outs, &retval); + out << outs << "\n"; + if(outstring) + { + *outstring += out.str(); + } + else + { + std::cout << out.str() << "\n"; + } + return retval; +} + void cmCTest::SetNotesFiles(const char* notes) { if ( !notes ) @@ -3404,4 +4175,3 @@ void cmCTest::SetNotesFiles(const char* notes) } m_NotesFiles = notes; } - diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 6f740c917..e07d0e140 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -26,6 +26,9 @@ class cmCTest public: typedef std::vector tm_VectorOfStrings; + ///! Process Command line arguments + int Run(std::vectorconst&, std::string* output = 0); + /** * Run a dashboard using a specified confiuration script */ @@ -289,6 +292,21 @@ private: int m_CompatibilityMode; + // information for the --build-and-test options + std::string m_ExecutableDirectory; + std::string m_CMakeSelf; + std::string m_CTestSelf; + std::string m_SourceDir; + std::string m_BinaryDir; + std::string m_BuildGenerator; + std::string m_BuildMakeProgram; + std::string m_BuildProject; + std::string m_BuildTarget; + std::vector m_BuildOptions; + std::string m_TestCommand; + std::vector m_TestCommandArgs; + bool m_BuildTwoConfig; + bool m_BuildNoClean; std::string m_NotesFiles; //! Reread the configuration file @@ -335,8 +353,12 @@ private: bool ProcessMemCheckValgrindOutput(const std::string& str, std::string& log, int* results); bool ProcessMemCheckPurifyOutput(const std::string& str, std::string& log, int* results); - //! Initialize memory checking subsystem. + ///! Run CMake and build a test and then run it as a single test. + int RunCMakeAndTest(std::string* output); + ///! Initialize memory checking subsystem. bool InitializeMemoryChecking(); + ///! Find the running cmake + void FindRunningCMake(const char* arg0); }; #endif diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 06ba069cc..87a33a0c8 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -64,7 +64,9 @@ const char* cmSystemTools::GetWindows9xComspecSubstitute() } void (*cmSystemTools::s_ErrorCallback)(const char*, const char*, bool&, void*); +void (*cmSystemTools::s_StdoutCallback)(const char*, int len, void*); void* cmSystemTools::s_ErrorCallbackClientData = 0; +void* cmSystemTools::s_StdoutCallbackClientData = 0; // replace replace with with as many times as it shows up in source. // write the result into source. @@ -221,6 +223,37 @@ void cmSystemTools::SetErrorCallback(ErrorCallback f, void* clientData) s_ErrorCallbackClientData = clientData; } +void cmSystemTools::SetStdoutCallback(StdoutCallback f, void* clientData) +{ + s_StdoutCallback = f; + s_StdoutCallbackClientData = clientData; +} + +void cmSystemTools::Stdout(const char* s) +{ + if(s_StdoutCallback) + { + (*s_StdoutCallback)(s, strlen(s), s_StdoutCallbackClientData); + } + else + { + std::cout << s; + std::cout << std::flush; + } +} + +void cmSystemTools::Stdout(const char* s, int length) +{ + if(s_StdoutCallback) + { + (*s_StdoutCallback)(s, length, s_StdoutCallbackClientData); + } + else + { + std::cout.write(s, length); + } +} + void cmSystemTools::Message(const char* m1, const char *title) { if(s_DisableMessages) @@ -411,7 +444,7 @@ bool cmSystemTools::RunSingleCommand( } if(verbose) { - std::cout.write(data, length); + cmSystemTools::Stdout(data, length); } } @@ -590,7 +623,9 @@ bool RunCommandViaPopen(const char* command, char buffer[BUFFER_SIZE]; if(verbose) { - std::cout << "running " << command << std::endl; + cmSystemTools::Stdout("running "); + cmSystemTools::Stdout(command); + cmSystemTools::Stdout("\n"); } fflush(stdout); fflush(stderr); @@ -604,7 +639,7 @@ bool RunCommandViaPopen(const char* command, { if(verbose) { - std::cout << buffer << std::flush; + cmSystemTools::Stdout(buffer); } output += buffer; fgets(buffer, BUFFER_SIZE, cpipe); diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 939d178d6..4c5e4252e 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -81,6 +81,12 @@ public: */ static void Message(const char* m, const char* title=0); + ///! Send a string to stdout + static void Stdout(const char* s); + static void Stdout(const char* s, int length); + typedef void (*StdoutCallback)(const char*, int length, void*); + static void SetStdoutCallback(StdoutCallback, void* clientData=0); + ///! Return true if there was an error at any point. static bool GetErrorOccuredFlag() { @@ -258,7 +264,9 @@ private: static bool s_DisableMessages; static bool s_DisableRunCommandOutput; static ErrorCallback s_ErrorCallback; + static StdoutCallback s_StdoutCallback; static void* s_ErrorCallbackClientData; + static void* s_StdoutCallbackClientData; static std::string s_Windows9xComspecSubstitute; }; diff --git a/Source/cmWin32ProcessExecution.cxx b/Source/cmWin32ProcessExecution.cxx index ddd1b4985..ba736dba4 100644 --- a/Source/cmWin32ProcessExecution.cxx +++ b/Source/cmWin32ProcessExecution.cxx @@ -220,7 +220,7 @@ bool cmWin32ProcessExecution::BorlandRunCommand( output += buf; if (verbose) { - std::cout << buf << std::flush; + cmSystemTools::Stdout(buf); } } } @@ -230,7 +230,7 @@ bool cmWin32ProcessExecution::BorlandRunCommand( output += buf; if(verbose) { - std::cout << buf << std::flush; + cmSystemTools::Stdout(buf); } } @@ -791,7 +791,7 @@ bool cmWin32ProcessExecution::PrivateClose(int /* timeout */) buffer[len] = 0; if ( m_Verbose ) { - std::cout << buffer << std::flush; + cmSystemTools::Stdout(buffer); } output += buffer; have_some = true; @@ -803,7 +803,7 @@ bool cmWin32ProcessExecution::PrivateClose(int /* timeout */) buffer[len] = 0; if ( m_Verbose ) { - std::cout << buffer << std::flush; + cmSystemTools::Stdout(buffer); } output += buffer; have_some = true; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 19172f9b5..92ff2d78f 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -532,6 +532,14 @@ int cmake::AddCMakePaths(const char *arg0) editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) + "/CMakeSetup" + cmSystemTools::GetFilenameExtension(cMakeSelf); } + std::string ctestCommand = cmSystemTools::GetFilenamePath(cMakeSelf) + + "/ctest" + cmSystemTools::GetFilenameExtension(cMakeSelf); + if(cmSystemTools::FileExists(ctestCommand.c_str())) + { + this->m_CacheManager->AddCacheEntry + ("CMAKE_CTEST_COMMAND", ctestCommand.c_str(), + "Path to ctest program executable.", cmCacheManager::INTERNAL); + } if(cmSystemTools::FileExists(editCacheCommand.c_str())) { this->m_CacheManager->AddCacheEntry diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 86abcdf7a..07b61cf0a 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -122,284 +122,19 @@ int main (int argc, char *argv[]) } } - cmCTest inst; - // look at the args +#ifdef _WIN32 + std::string comspec = "cmw9xcom.exe"; + cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str()); +#endif + cmCTest inst; + // copy the args to a vector std::vector args; for(int i =0; i < argc; ++i) { args.push_back(argv[i]); } - -#ifdef _WIN32 - std::string comspec = "cmw9xcom.exe"; - cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str()); -#endif - - for(unsigned int i=1; i < args.size(); ++i) - { - std::string arg = args[i]; - if(arg.find("-C",0) == 0 && i < args.size() - 1) - { - inst.m_ConfigType = args[i+1]; - } - - if( arg.find("-V",0) == 0 || arg.find("--verbose",0) == 0 ) - { - inst.m_Verbose = true; - } - - if( arg.find("-N",0) == 0 || arg.find("--show-only",0) == 0 ) - { - inst.m_ShowOnly = true; - } - - if( arg.find("-S",0) == 0 && i < args.size() - 1 ) - { - inst.m_RunConfigurationScript = true; - inst.m_ConfigurationScript = args[i+1]; - } - - if( arg.find("-D",0) == 0 && i < args.size() - 1 ) - { - inst.m_DartMode = true; - std::string targ = args[i+1]; - if ( targ == "Experimental" ) - { - inst.SetTestModel(cmCTest::EXPERIMENTAL); - inst.SetTest("Start"); - inst.SetTest("Configure"); - inst.SetTest("Build"); - inst.SetTest("Test"); - inst.SetTest("Coverage"); - inst.SetTest("Submit"); - } - else if ( targ == "ExperimentalStart" ) - { - inst.SetTestModel(cmCTest::EXPERIMENTAL); - inst.SetTest("Start"); - } - else if ( targ == "ExperimentalUpdate" ) - { - inst.SetTestModel(cmCTest::EXPERIMENTAL); - inst.SetTest("Update"); - } - else if ( targ == "ExperimentalConfigure" ) - { - inst.SetTestModel(cmCTest::EXPERIMENTAL); - inst.SetTest("Configure"); - } - else if ( targ == "ExperimentalBuild" ) - { - inst.SetTestModel(cmCTest::EXPERIMENTAL); - inst.SetTest("Build"); - } - else if ( targ == "ExperimentalTest" ) - { - inst.SetTestModel(cmCTest::EXPERIMENTAL); - inst.SetTest("Test"); - } - else if ( targ == "ExperimentalMemCheck" || targ == "ExperimentalPurify" ) - { - inst.SetTestModel(cmCTest::EXPERIMENTAL); - inst.SetTest("MemCheck"); - } - else if ( targ == "ExperimentalCoverage" ) - { - inst.SetTestModel(cmCTest::EXPERIMENTAL); - inst.SetTest("Coverage"); - } - else if ( targ == "ExperimentalSubmit" ) - { - inst.SetTestModel(cmCTest::EXPERIMENTAL); - inst.SetTest("Submit"); - } - else if ( targ == "Continuous" ) - { - inst.SetTestModel(cmCTest::CONTINUOUS); - inst.SetTest("Start"); - inst.SetTest("Update"); - inst.SetTest("Configure"); - inst.SetTest("Build"); - inst.SetTest("Test"); - inst.SetTest("Coverage"); - inst.SetTest("Submit"); - } - else if ( targ == "ContinuousStart" ) - { - inst.SetTestModel(cmCTest::CONTINUOUS); - inst.SetTest("Start"); - } - else if ( targ == "ContinuousUpdate" ) - { - inst.SetTestModel(cmCTest::CONTINUOUS); - inst.SetTest("Update"); - } - else if ( targ == "ContinuousConfigure" ) - { - inst.SetTestModel(cmCTest::CONTINUOUS); - inst.SetTest("Configure"); - } - else if ( targ == "ContinuousBuild" ) - { - inst.SetTestModel(cmCTest::CONTINUOUS); - inst.SetTest("Build"); - } - else if ( targ == "ContinuousTest" ) - { - inst.SetTestModel(cmCTest::CONTINUOUS); - inst.SetTest("Test"); - } - else if ( targ == "ContinuousMemCheck" || targ == "ContinuousPurify" ) - { - inst.SetTestModel(cmCTest::CONTINUOUS); - inst.SetTest("MemCheck"); - } - else if ( targ == "ContinuousCoverage" ) - { - inst.SetTestModel(cmCTest::CONTINUOUS); - inst.SetTest("Coverage"); - } - else if ( targ == "ContinuousSubmit" ) - { - inst.SetTestModel(cmCTest::CONTINUOUS); - inst.SetTest("Submit"); - } - else if ( targ == "Nightly" ) - { - inst.SetTestModel(cmCTest::NIGHTLY); - inst.SetTest("Start"); - inst.SetTest("Update"); - inst.SetTest("Configure"); - inst.SetTest("Build"); - inst.SetTest("Test"); - inst.SetTest("Coverage"); - inst.SetTest("Submit"); - } - else if ( targ == "NightlyStart" ) - { - inst.SetTestModel(cmCTest::NIGHTLY); - inst.SetTest("Start"); - } - else if ( targ == "NightlyUpdate" ) - { - inst.SetTestModel(cmCTest::NIGHTLY); - inst.SetTest("Update"); - } - else if ( targ == "NightlyConfigure" ) - { - inst.SetTestModel(cmCTest::NIGHTLY); - inst.SetTest("Configure"); - } - else if ( targ == "NightlyBuild" ) - { - inst.SetTestModel(cmCTest::NIGHTLY); - inst.SetTest("Build"); - } - else if ( targ == "NightlyTest" ) - { - inst.SetTestModel(cmCTest::NIGHTLY); - inst.SetTest("Test"); - } - else if ( targ == "NightlyMemCheck" || targ == "NightlyPurify" ) - { - inst.SetTestModel(cmCTest::NIGHTLY); - inst.SetTest("MemCheck"); - } - else if ( targ == "NightlyCoverage" ) - { - inst.SetTestModel(cmCTest::NIGHTLY); - inst.SetTest("Coverage"); - } - else if ( targ == "NightlySubmit" ) - { - inst.SetTestModel(cmCTest::NIGHTLY); - inst.SetTest("Submit"); - } - else if ( targ == "MemoryCheck" ) - { - inst.SetTestModel(cmCTest::EXPERIMENTAL); - inst.SetTest("Start"); - inst.SetTest("Configure"); - inst.SetTest("Build"); - inst.SetTest("MemCheck"); - inst.SetTest("Coverage"); - inst.SetTest("Submit"); - } - else if ( targ == "NightlyMemoryCheck" ) - { - inst.SetTestModel(cmCTest::NIGHTLY); - inst.SetTest("Start"); - inst.SetTest("Update"); - inst.SetTest("Configure"); - inst.SetTest("Build"); - inst.SetTest("MemCheck"); - inst.SetTest("Coverage"); - inst.SetTest("Submit"); - } - } - - if( ( arg.find("-T",0) == 0 ) && - (i < args.size() -1) ) - { - inst.m_DartMode = true; - inst.SetTest(args[i+1].c_str()); - } - - if( ( arg.find("-M",0) == 0 || arg.find("--test-model",0) == 0 ) && - (i < args.size() -1) ) - { - std::string& str = args[i+1]; - if ( str == "NIGHTLY" || str == "nightly" || str == "Nightly" ) - { - inst.SetTestModel(cmCTest::NIGHTLY); - } - else if ( str == "CONTINUOUS" || str == "continuous" || - str == "Continuous" ) - { - inst.SetTestModel(cmCTest::CONTINUOUS); - std::cout << "Continuous" << std::endl; - } - else - { - inst.SetTestModel(cmCTest::EXPERIMENTAL); - } - } - - if(arg.find("-R",0) == 0 && i < args.size() - 1) - { - inst.m_UseIncludeRegExp = true; - inst.m_IncludeRegExp = args[i+1]; - } - - if(arg.find("-E",0) == 0 && i < args.size() - 1) - { - inst.m_UseExcludeRegExp = true; - inst.m_ExcludeRegExp = args[i+1]; - inst.m_UseExcludeRegExpFirst = inst.m_UseIncludeRegExp ? false : true; - } - - if(arg.find("-A",0) == 0 && i < args.size() - 1) - { - inst.m_DartMode = true; - inst.SetTest("Notes"); - inst.SetNotesFiles(argv[i+1]); - } - } - - // call process directory - int res; - if (inst.m_RunConfigurationScript) - { - res = inst.RunConfigurationScript(); - } - else - { - inst.Initialize(); - res = inst.ProcessTests(); - inst.Finalize(); - } - - return res; + // run ctest + return inst.Run(args); }