diff options
-rw-r--r-- | Source/CTest/cmCTestTestHandler.cxx | 5 | ||||
-rw-r--r-- | Source/cmAddTestCommand.cxx | 17 | ||||
-rw-r--r-- | Source/cmAddTestCommand.h | 5 | ||||
-rw-r--r-- | Source/cmTest.cxx | 6 | ||||
-rw-r--r-- | Tests/CMakeLists.txt | 13 | ||||
-rw-r--r-- | Tests/TestsWorkingDirectory/CMakeLists.txt | 52 | ||||
-rw-r--r-- | Tests/TestsWorkingDirectory/main.c | 66 |
7 files changed, 162 insertions, 2 deletions
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 6eec3c8..6d1af2d 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -2192,7 +2192,6 @@ bool cmCTestTestHandler::SetTestsProperties( { rtit->Labels.push_back(*crit); } - } if ( key == "MEASUREMENT" ) { @@ -2221,6 +2220,10 @@ bool cmCTestTestHandler::SetTestsProperties( std::string(crit->c_str()))); } } + if ( key == "WORKING_DIRECTORY" ) + { + rtit->Directory = val; + } } } } diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx index 923206d..11ca9e7 100644 --- a/Source/cmAddTestCommand.cxx +++ b/Source/cmAddTestCommand.cxx @@ -74,6 +74,7 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args) { std::string name; std::vector<std::string> configurations; + std::string working_directory; std::vector<std::string> command; // Read the arguments. @@ -81,6 +82,7 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args) DoingName, DoingCommand, DoingConfigs, + DoingWorkingDirectory, DoingNone }; Doing doing = DoingName; @@ -104,6 +106,15 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args) } doing = DoingConfigs; } + else if(args[i] == "WORKING_DIRECTORY") + { + if(!working_directory.empty()) + { + this->SetError(" may be given at most one WORKING_DIRECTORY."); + return false; + } + doing = DoingWorkingDirectory; + } else if(doing == DoingName) { name = args[i]; @@ -117,6 +128,11 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args) { configurations.push_back(args[i]); } + else if(doing == DoingWorkingDirectory) + { + working_directory = args[i]; + doing = DoingNone; + } else { cmOStringStream e; @@ -154,6 +170,7 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args) cmTest* test = this->Makefile->CreateTest(name.c_str()); test->SetOldStyle(false); test->SetCommand(command); + test->SetProperty("WORKING_DIRECTORY", working_directory.c_str()); this->Makefile->AddTestGenerator(new cmTestGenerator(test, configurations)); return true; diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h index 1cc86c4..edaf12c 100644 --- a/Source/cmAddTestCommand.h +++ b/Source/cmAddTestCommand.h @@ -69,12 +69,15 @@ public: "in the binary tree.\n" "\n" " add_test(NAME <name> [CONFIGURATIONS [Debug|Release|...]]\n" + " [WORKING_DIRECTORY dir]\n" " COMMAND <command> [arg1 [arg2 ...]])\n" "If COMMAND specifies an executable target (created by " "add_executable) it will automatically be replaced by the location " "of the executable created at build time. " "If a CONFIGURATIONS option is given then the test will be executed " - "only when testing under one of the named configurations." + "only when testing under one of the named configurations. " + "If a WORKING_DIRECTORY option is given then the test will be executed " + "in the given directory." "\n" "Arguments after COMMAND may use \"generator expressions\" with the " "syntax \"$<...>\". " diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx index 4e9b973..c25a8b6 100644 --- a/Source/cmTest.cxx +++ b/Source/cmTest.cxx @@ -196,4 +196,10 @@ void cmTest::DefineProperties(cmake *cm) "If set to true, this will invert the pass/fail flag of the test.", "This property can be used for tests that are expected to fail and " "return a non zero return code."); + + cm->DefineProperty + ("WORKING_DIRECTORY", cmProperty::TEST, + "The directory from which the test executable will be called.", + "If this is not set it is called from the directory the test executable " + "is located in."); } diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 7409b0b..289e632 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1114,6 +1114,19 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleGeneratorTest") ENDIF(APPLE AND CTEST_TEST_CPACK) + ADD_TEST(TestsWorkingDirectory ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/TestsWorkingDirectory" + "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project TestsWorkingDirectoryProj + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory" + --force-new-ctest-process + --test-command ${CMAKE_CTEST_COMMAND} -V + ) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory") + # Make sure CTest can handle a test with no newline in output. ADD_TEST(CTest.NoNewline ${CMAKE_CMAKE_COMMAND} -E echo_append "This line has no newline!") diff --git a/Tests/TestsWorkingDirectory/CMakeLists.txt b/Tests/TestsWorkingDirectory/CMakeLists.txt new file mode 100644 index 0000000..01e6650 --- /dev/null +++ b/Tests/TestsWorkingDirectory/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 2.6) +project(TestsWorkingDirectoryProj) + +add_executable(WorkingDirectory main.c) + +enable_testing() + +set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin") + +add_test(NAME WorkingDirectory1 COMMAND WorkingDirectory) +set_tests_properties(WorkingDirectory1 PROPERTIES + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + PASS_REGULAR_EXPRESSION "Working directory: -->${CMAKE_BINARY_DIR}<--" +) + +string(REGEX REPLACE "/[^/]*$" "" _parent_dir "${CMAKE_BINARY_DIR}") + +add_test(NAME WorkingDirectory2 COMMAND WorkingDirectory) +set_tests_properties(WorkingDirectory2 PROPERTIES + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/.." + PASS_REGULAR_EXPRESSION "Working directory: -->${_parent_dir}<--" +) + +get_filename_component(_default_cwd "${EXECUTABLE_OUTPUT_PATH}" PATH) + +# FIXME: How to deal with /debug, /release, etc. with VS or XCode? +if(${CMAKE_GENERATOR} MATCHES "Makefiles") +add_test(WorkingDirectory3 ${EXECUTABLE_OUTPUT_PATH}/WorkingDirectory) +set_tests_properties(WorkingDirectory3 PROPERTIES + PASS_REGULAR_EXPRESSION "Working directory: -->${_default_cwd}<--" +) +endif() + +add_test(NAME WorkingDirectory4 WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND WorkingDirectory) +set_tests_properties(WorkingDirectory4 PROPERTIES + PASS_REGULAR_EXPRESSION "Working directory: -->${CMAKE_BINARY_DIR}<--" +) + +string(REGEX REPLACE "/[^/]*$" "" _parent_dir "${CMAKE_BINARY_DIR}") + +add_test(NAME WorkingDirectory5 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/.. COMMAND WorkingDirectory) +set_tests_properties(WorkingDirectory5 PROPERTIES + PASS_REGULAR_EXPRESSION "Working directory: -->${_parent_dir}<--" +) + +# FIXME: How to deal with /debug, /release, etc. with VS or XCode? +if(${CMAKE_GENERATOR} MATCHES "Makefiles") +add_test(WorkingDirectory6 ${EXECUTABLE_OUTPUT_PATH}/WorkingDirectory WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/..) +set_tests_properties(WorkingDirectory6 PROPERTIES + PASS_REGULAR_EXPRESSION "Working directory: -->${_default_cwd}<--" +) +endif() diff --git a/Tests/TestsWorkingDirectory/main.c b/Tests/TestsWorkingDirectory/main.c new file mode 100644 index 0000000..ad5eb30 --- /dev/null +++ b/Tests/TestsWorkingDirectory/main.c @@ -0,0 +1,66 @@ +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__)) + +#include <io.h> +#include <direct.h> + +#if defined(__WATCOMC__) +#include <direct.h> +#define _getcwd getcwd +#endif + +static const char* Getcwd(char* buf, unsigned int len) +{ + const char* ret = _getcwd(buf, len); + char* p = NULL; + if(!ret) + { + fprintf(stderr, "No current working directory.\n"); + abort(); + } + // make sure the drive letter is capital + if(strlen(buf) > 1 && buf[1] == ':') + { + buf[0] = toupper(buf[0]); + } + for(p = buf; *p; ++p) + { + if(*p == '\\') + { + *p = '/'; + } + } + return ret; +} + +#else +#include <sys/types.h> +#include <fcntl.h> +#include <unistd.h> + +static const char* Getcwd(char* buf, unsigned int len) +{ + const char* ret = getcwd(buf, len); + if(!ret) + { + fprintf(stderr, "No current working directory\n"); + abort(); + } + return ret; +} + +#endif + +int main(int argc, char *argv[]) +{ + char buf[2048]; + const char *cwd = Getcwd(buf, sizeof(buf)); + + fprintf(stdout, "Working directory: -->%s<--", cwd); + + return 0; +} |