diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 3f4cdb776..118bf2f1e 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -131,6 +131,25 @@ IF(BUILD_TESTING) wrapping ${CMake_BINARY_DIR}/Tests/Wrapping/bin) + ADD_TEST(testdriver1 ${CMake_BINARY_DIR}/Source/cmaketest + ${CMake_SOURCE_DIR}/Tests/TestDriver + ${CMake_BINARY_DIR}/Tests/TestDriver + TestDriverTest + ${CMake_BINARY_DIR}/Tests/Wrapping/bin + TestDriverTest test1) + ADD_TEST(testdriver2 ${CMake_BINARY_DIR}/Source/cmaketest + ${CMake_SOURCE_DIR}/Tests/TestDriver + ${CMake_BINARY_DIR}/Tests/TestDriver + TestDriverTest + ${CMake_BINARY_DIR}/Tests/Wrapping/bin + TestDriverTest test2) + ADD_TEST(testdriver3 ${CMake_BINARY_DIR}/Source/cmaketest + ${CMake_SOURCE_DIR}/Tests/TestDriver + ${CMake_BINARY_DIR}/Tests/TestDriver + TestDriverTest + ${CMake_BINARY_DIR}/Tests/Wrapping/bin + TestDriverTest test3) + ENDIF (DART_ROOT) ENDIF(BUILD_TESTING) diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 48e2dfe49..4cec8ae08 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -33,6 +33,7 @@ #include "cmCableWrapTclCommand.cxx" #include "cmConfigureFileCommand.cxx" #include "cmConfigureGccXmlCommand.cxx" +#include "cmCreateTestSourceList.cxx" #include "cmElseCommand.cxx" #include "cmEnableTestingCommand.cxx" #include "cmEndForEachCommand.cxx" @@ -99,6 +100,7 @@ void GetPredefinedCommands(std::list& commands) commands.push_back(new cmCableWrapTclCommand); commands.push_back(new cmConfigureFileCommand); commands.push_back(new cmConfigureGccXmlCommand); + commands.push_back(new cmCreateTestSourceList); commands.push_back(new cmElseCommand); commands.push_back(new cmEnableTestingCommand); commands.push_back(new cmEndForEachCommand); diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx new file mode 100644 index 000000000..12096e65a --- /dev/null +++ b/Source/cmCreateTestSourceList.cxx @@ -0,0 +1,129 @@ +/*========================================================================= + + Program: Insight Segmentation & Registration Toolkit + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Insight Consortium. All rights reserved. + See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmCreateTestSourceList.h" + + +// cmCreateTestSourceList +bool cmCreateTestSourceList::InitialPass(std::vector const& argsIn) +{ + if (argsIn.size() < 5) + { + this->SetError("called with wrong number of arguments."); + return false; + } + std::vector args; + cmSystemTools::ExpandListArguments(argsIn, args); + + std::vector::iterator i = args.begin(); + const char* sourceList = i->c_str(); + ++i; + std::string driver = m_Makefile->GetCurrentOutputDirectory(); + driver += "/"; + driver += *i; + driver += ".cxx"; + ++i; + std::vector::iterator testsBegin = i; + std::ofstream fout(driver.c_str()); + if(!fout) + { + std::string err = "Could not create file "; + err += driver; + err += " for cmCreateTestSourceList command."; + this->SetError(err.c_str()); + return false; + } + // Create the test driver file + fout << "#include \n"; + fout << "#include \n"; + fout << "// forward declare test functions\n"; + for(i = testsBegin; i != args.end(); ++i) + { + fout << "int " << *i << "(int, char**);\n"; + } + fout << "// Create map \n"; + fout << "typedef int (*MainFuncPointer)(int , char**);\n"; + fout << "struct functionMapEntry\n" + << "{\n" + << "const char* name;\n" + << "MainFuncPointer func;\n" + << "};\n\n"; + fout << "functionMapEntry cmakeGeneratedFunctionMapEntries[] = {\n"; + int numTests = 0; + for(i = testsBegin; i != args.end(); ++i) + { + fout << "{\"" << *i << "\", " << *i << "},\n"; + numTests++; + } + fout << "};\n"; + fout << "int main(int ac, char** av)\n" + << "{\n"; + fout << " int NumTests = " << numTests << ";\n"; + fout << " int i;\n"; + fout << " if(ac < 2)\n"; + fout << " {\n"; + fout << " printf(\"Available tests:\\n\");\n"; + fout << " for(i =0; i < NumTests; ++i)\n"; + fout << " {\n"; + fout << " printf(\"%d. %s\\n\", i, cmakeGeneratedFunctionMapEntries[i].name);\n"; + fout << " }\n"; + fout << " printf(\"To run a test, enter the test number: \");\n"; + fout << " int testNum = 0;\n"; + fout << " scanf(\"%d\", &testNum);\n"; + fout << " if(testNum >= NumTests)\n"; + fout << " {\n"; + fout << " printf(\"%d is an invalid test number.\\n\", testNum);\n"; + fout << " return -1;\n"; + fout << " }\n"; + fout << " return (*cmakeGeneratedFunctionMapEntries[testNum].func)(ac-1, av+1);\n"; + fout << " }\n"; + fout << " for(i =0; i < NumTests; ++i)\n"; + fout << " {\n"; + fout << " if(strcmp(cmakeGeneratedFunctionMapEntries[i].name, av[1]) == 0)\n"; + fout << " {\n"; + fout << " return (*cmakeGeneratedFunctionMapEntries[i].func)(ac-1, av+1);\n"; + fout << " }\n"; + fout << " }\n"; + fout << " printf(\"Available tests:\\n\");\n"; + fout << " for(i =0; i < NumTests; ++i)\n"; + fout << " {\n"; + fout << " printf(\"%d. %s\\n\", i, cmakeGeneratedFunctionMapEntries[i].name);\n"; + fout << " }\n"; + fout << " printf(\"Failed: %s is an invalid test name.\\n\", av[1]);\n"; + fout << " return -1;\n"; + fout << "}\n"; + fout.close(); + // create the source list + cmSourceFile cfile; + cfile.SetIsAnAbstractClass(false); + cfile.SetName(args[1].c_str(), m_Makefile->GetCurrentOutputDirectory(), + "cxx", false); + m_Makefile->AddSource(cfile, sourceList); + + for(i = testsBegin; i != args.end(); ++i) + { + cmSourceFile cfile; + cfile.SetIsAnAbstractClass(false); + cfile.SetName(i->c_str(), m_Makefile->GetCurrentDirectory(), + "cxx", false); + m_Makefile->AddSource(cfile, sourceList); + } + + return true; +} + + + diff --git a/Source/cmCreateTestSourceList.h b/Source/cmCreateTestSourceList.h new file mode 100644 index 000000000..3d78b9370 --- /dev/null +++ b/Source/cmCreateTestSourceList.h @@ -0,0 +1,84 @@ +/*========================================================================= + + Program: Insight Segmentation & Registration Toolkit + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Insight Consortium. All rights reserved. + See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmCreateTestSourceList_h +#define cmCreateTestSourceList_h + +#include "cmStandardIncludes.h" +#include "cmCommand.h" + +/** \class cmCreateTestSourceList + * \brief + * + */ + +class cmCreateTestSourceList : public cmCommand +{ +public: + /** + * This is a virtual constructor for the command. + */ + virtual cmCommand* Clone() + { + return new cmCreateTestSourceList; + } + + /** + * This is called when the command is first encountered in + * the CMakeLists.txt file. + */ + virtual bool InitialPass(std::vector const& args); + + /** + * This determines if the command gets propagated down + * to makefiles located in subdirectories. + */ + virtual bool IsInherited() {return true;} + + /** + * The name of the command as specified in CMakeList.txt. + */ + virtual const char* GetName() {return "CREATE_TEST_SOURCELIST";} + + /** + * Succinct documentation. + */ + virtual const char* GetTerseDocumentation() + { + return "Create a test driver and source list for building test programs."; + } + + /** + * More documentation. + */ + virtual const char* GetFullDocumentation() + { + return + "CREATE_TEST_SOURCELIST(SourceListName DriverName test1 test2 test3" + "The list of source files needed to build the testdriver will be in SourceListName.\n" + "DriverName.cxx is the name of the test driver program.\n" + "The rest of the arguments consist of a list of test source files, can be " + "; separated. Each test source file should have a function in it that " + "is the same name as the file with no extension (foo.cxx should have int foo();) " + "DriverName.cxx will be able to call each of the tests by name on the command line."; + } + + cmTypeMacro(cmCreateTestSourceList, cmCommand); +}; + + + +#endif diff --git a/Source/cmaketest.cxx b/Source/cmaketest.cxx index 521c96554..cf13f5e1d 100644 --- a/Source/cmaketest.cxx +++ b/Source/cmaketest.cxx @@ -86,12 +86,23 @@ int main (int argc, char *argv[]) std::string generator = "-G"; generator += CMAKE_GENERATOR; args.push_back(generator); - + + std::vector progArgs; if(argc > 6) { - for (int j = 6; j < argc ; j++) + if(strcmp(argv[6] , "CMAKE_ARGS") == 0) { - args.push_back(argv[j]); + for (int j = 7; j < argc ; j++) + { + args.push_back(argv[j]); + } + } + else + { + for(int j = 6; j < argc; j++) + { + progArgs.push_back(argv[j]); + } } } @@ -254,6 +265,12 @@ int main (int argc, char *argv[]) return 1; } fullPath = cmSystemTools::ConvertToOutputPath(fullPath.c_str()); + for(std::vector::iterator p = progArgs.begin(); + p != progArgs.end(); ++p) + { + fullPath += " "; + fullPath += *p; + } std::cout << "Running test executable: " << fullPath.c_str() << "\n"; int ret = 0; if (!cmSystemTools::RunCommand(fullPath.c_str(), output, ret, 0, true)) diff --git a/Tests/TestDriver/CMakeLists.txt b/Tests/TestDriver/CMakeLists.txt new file mode 100644 index 000000000..0b3d07f1f --- /dev/null +++ b/Tests/TestDriver/CMakeLists.txt @@ -0,0 +1,4 @@ +PROJECT(TestDriverTest) +CREATE_TEST_SOURCELIST(testSrcs TestDriverTest test1 test2 test3) +ADD_EXECUTABLE(TestDriverTest testSrcs) + diff --git a/Tests/TestDriver/test1.cxx b/Tests/TestDriver/test1.cxx new file mode 100644 index 000000000..40aa8d7d2 --- /dev/null +++ b/Tests/TestDriver/test1.cxx @@ -0,0 +1,8 @@ +#include +int test1(int ac, char** av) +{ + printf("test1\n"); + for(int i =0; i < ac; i++) + printf("arg %d is %s\n", ac, av[i]); + return 0; +} diff --git a/Tests/TestDriver/test2.cxx b/Tests/TestDriver/test2.cxx new file mode 100644 index 000000000..2c1f2af1b --- /dev/null +++ b/Tests/TestDriver/test2.cxx @@ -0,0 +1,8 @@ +#include +int test2(int ac, char** av) +{ + printf("test2\n"); + for(int i =0; i < ac; i++) + printf("arg %d is %s\n", ac, av[i]); + return 0; +} diff --git a/Tests/TestDriver/test3.cxx b/Tests/TestDriver/test3.cxx new file mode 100644 index 000000000..b6bcd91dc --- /dev/null +++ b/Tests/TestDriver/test3.cxx @@ -0,0 +1,8 @@ +#include +int test3(int ac, char** av) +{ + printf("test3\n"); + for(int i =0; i < ac; i++) + printf("arg %d is %s\n", ac, av[i]); + return 0; +}