diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 446729ea6..a12ac2b48 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -383,6 +383,87 @@ void cmMakefile::GenerateMakefile() } // now do the generation m_MakefileGenerator->GenerateMakefile(); + + // generate any testing files + this->GenerateTestfile(); +} + +void cmMakefile::GenerateTestfile() +{ + if (m_Tests.empty() && this->GetSubDirectories().empty()) + { + return; + } + + // Create a full path filename for output Testfile + std::string fname; + fname = this->GetCurrentOutputDirectory(); + fname += "/"; + fname += "Testfile"; + + // Open the output Testfile + std::ofstream fout(fname.c_str()); + if (!fout) + { + cmSystemTools::Error("Error Writing ", fname.c_str()); + return; + } + + fout << "# CMake generated Testfile for " << std::endl + << "#\tSource directory: " + << this->GetCurrentDirectory() + << std::endl + << "#\tBuild directory: " << this->GetCurrentOutputDirectory() + << std::endl + << "# " << std::endl + << "# This file replicates the SUBDIRS() and ADD_TEST() commands from the source" + << std::endl + << "# tree CMakeLists.txt file, skipping any SUBDIRS() or ADD_TEST() commands" + << std::endl + << "# that are excluded by CMake control structures, i.e. IF() commands." + << std::endl + << "#" + << std::endl << std::endl; + + // write out the subdirs for the current directory + if (!this->GetSubDirectories().empty()) + { + fout << "SUBDIRS("; + const std::vector& subdirs = this->GetSubDirectories(); + std::vector::const_iterator i = subdirs.begin(); + fout << (*i).c_str(); + ++i; + for(; i != subdirs.end(); ++i) + { + fout << " " << (*i).c_str(); + } + fout << ")" << std::endl << std::endl;; + } + + + // write out each test + std::vector >::iterator testIt; + std::vector::iterator it; + + // for each test + for (testIt = m_Tests.begin(); testIt != m_Tests.end(); ++testIt) + { + if (!(*testIt).empty()) + { + // for each arg in the test + fout << "ADD_TEST("; + it = (*testIt).begin(); + fout << (*it).c_str(); + ++it; + for (; it != (*testIt).end(); ++it) + { + fout << " " << (*it).c_str(); + } + fout << ")" << std::endl; + } + } + + fout << std::endl; } void cmMakefile::AddSource(cmSourceFile& cmfile, const char *srclist) @@ -489,6 +570,11 @@ void cmMakefile::AddDefinition(const char* name, bool value) } } +void cmMakefile::AddTest(const std::vector &args) +{ + m_Tests.push_back(args); +} + void cmMakefile::SetProjectName(const char* p) { m_ProjectName = p; diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 8e1db98fc..fccd7793f 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -110,6 +110,17 @@ public: * Produce the output makefile. */ void GenerateMakefile(); + + /** + * Produce the output testfile. This produces a file in the build directory + * called Testfile with a syntax similar to CMakeLists.txt. It contains + * the SUBDIRS() and ADD_TEST() commands from the source CMakeLists.txt + * file with CMake variables expanded. Only the subdirs and tests + * within the valid control structures are replicated in Testfile + * (i.e. SUBDIRS() and ADD_TEST() commands within IF() commands that are + * not entered by CMake are not replicated in Testfile). + */ + void GenerateTestfile(); /** * Print the object state to std::cout. @@ -211,6 +222,11 @@ public: */ void AddDefinition(const char* name, bool); + /** + * Add a test to the build. + */ + void AddTest(const std::vector &args); + /** * Specify the name of the project for this build. */ @@ -510,7 +526,9 @@ protected: std::vector m_Utilities; std::vector m_UtilityDirectories; std::vector m_ListFiles; // list of command files loaded - + std::vector > m_Tests; // list of tests and args + + cmTarget::LinkLibraries m_LinkLibraries; std::string m_IncludeFileRegularExpression;