From 12dc64c7f5a6ee7a83e010fbb4df36eb3080b864 Mon Sep 17 00:00:00 2001 From: Andy Cedilnik Date: Thu, 23 Feb 2006 10:07:24 -0500 Subject: [PATCH] ENH: Add a notion of a global target --- Source/cmGlobalGenerator.cxx | 159 +++++++++++++++++++++++ Source/cmGlobalGenerator.h | 15 +++ Source/cmLocalUnixMakefileGenerator3.cxx | 115 ++++++---------- 3 files changed, 214 insertions(+), 75 deletions(-) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index c3145c6c4..51481b7b3 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -671,8 +671,36 @@ void cmGlobalGenerator::Generate() { // For each existing cmLocalGenerator unsigned int i; + + // Consolidate global targets + cmTargets globalTargets; + this->CreateDefaultGlobalTargets(&globalTargets); for (i = 0; i < m_LocalGenerators.size(); ++i) { + cmTargets* targets = &(m_LocalGenerators[i]->GetMakefile()->GetTargets()); + cmTargets::iterator tarIt; + for ( tarIt = targets->begin(); tarIt != targets->end(); ++ tarIt ) + { + if ( tarIt->second.GetType() == cmTarget::GLOBAL_TARGET ) + { + globalTargets[tarIt->first] = tarIt->second; + } + } + } + { + cmTargets::iterator tarIt; + std::cout << "Global targets:" << std::endl; + for ( tarIt = globalTargets.begin(); tarIt != globalTargets.end(); ++ tarIt ) + { + std::cout << "* " << tarIt->first.c_str() << std::endl; + } + } + + // Generate project files + for (i = 0; i < m_LocalGenerators.size(); ++i) + { + cmTargets* targets = &(m_LocalGenerators[i]->GetMakefile()->GetTargets()); + targets->insert(globalTargets.begin(), globalTargets.end()); m_LocalGenerators[i]->Generate(); m_LocalGenerators[i]->GenerateInstallRules(); m_LocalGenerators[i]->GenerateTestFiles(); @@ -1186,6 +1214,137 @@ void cmGlobalGenerator::SetupTests() } } +void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) +{ + cmMakefile* mf = m_LocalGenerators[0]->GetMakefile(); + // CPack + cmCustomCommandLines cpackCommandLines; + std::vector depends; + cmCustomCommandLine singleLine; + cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.end()); + singleLine.erase(singleLine.begin(), singleLine.end()); + depends.erase(depends.begin(), depends.end()); + singleLine.push_back(this->GetCMakeInstance()->GetCPackCommand()); + singleLine.push_back("--config"); + std::string configFile = mf->GetStartOutputDirectory();; + configFile += "/CPackConfig.cmake"; + singleLine.push_back(configFile); + cpackCommandLines.push_back(singleLine); + (*targets)[this->GetPackageTargetName()] + = this->CreateGlobalTarget(this->GetPackageTargetName(), + "Run CPack packaging tool...", &cpackCommandLines, depends); + + // Test + cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.end()); + singleLine.erase(singleLine.begin(), singleLine.end()); + depends.erase(depends.begin(), depends.end()); + singleLine.push_back(this->GetCMakeInstance()->GetCTestCommand()); + singleLine.push_back("--force-new-ctest-process"); + cpackCommandLines.push_back(singleLine); + (*targets)[this->GetPackageTargetName()] + = this->CreateGlobalTarget(this->GetPackageTargetName(), + "Running tests...", &cpackCommandLines, depends); + + //Edit Cache + cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.end()); + singleLine.erase(singleLine.begin(), singleLine.end()); + depends.erase(depends.begin(), depends.end()); + // Use CMAKE_EDIT_COMMAND for the edit_cache rule if it is defined. + // Otherwise default to the interactive command-line interface. + if(mf->GetDefinition("CMAKE_EDIT_COMMAND")) + { + singleLine.push_back("$(CMAKE_EDIT_COMMAND)"); + singleLine.push_back("-H$(CMAKE_SOURCE_DIR)"); + singleLine.push_back("-B$(CMAKE_BINARY_DIR)"); + cpackCommandLines.push_back(singleLine); + (*targets)[this->GetEditCacheTargetName()] = + this->CreateGlobalTarget( + this->GetEditCacheTargetName(), "Running CMake cache editor...", + &cpackCommandLines, depends); + } + else + { + singleLine.push_back("$(CMAKE_COMMAND)"); + singleLine.push_back("-H$(CMAKE_SOURCE_DIR)"); + singleLine.push_back("-B$(CMAKE_BINARY_DIR)"); + singleLine.push_back("-i"); + cpackCommandLines.push_back(singleLine); + (*targets)[this->GetEditCacheTargetName()] = + this->CreateGlobalTarget( + this->GetEditCacheTargetName(), "Running interactive CMake command-line interface...", + &cpackCommandLines, depends); + } + + //Rebuild Cache + cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.end()); + singleLine.erase(singleLine.begin(), singleLine.end()); + depends.erase(depends.begin(), depends.end()); + singleLine.push_back("$(CMAKE_COMMAND)"); + singleLine.push_back("-H$(CMAKE_SOURCE_DIR)"); + singleLine.push_back("-B$(CMAKE_BINARY_DIR)"); + cpackCommandLines.push_back(singleLine); + (*targets)[this->GetRebuildCacheTargetName()] = + this->CreateGlobalTarget( + this->GetRebuildCacheTargetName(), "Running CMake to regenerate build system...", + &cpackCommandLines, depends); + + //Install + std::string cmd; + cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.end()); + singleLine.erase(singleLine.begin(), singleLine.end()); + depends.erase(depends.begin(), depends.end()); + depends.push_back("preinstall"); + if(mf->GetDefinition("CMake_BINARY_DIR")) + { + // We are building CMake itself. We cannot use the original + // executable to install over itself. + cmd = mf->GetDefinition("EXECUTABLE_OUTPUT_PATH"); + cmd += "/"; + cmd += "cmake"; + } + else + { + cmd = "$(CMAKE_COMMAND)"; + } + singleLine.push_back(cmd.c_str()); + singleLine.push_back("-P"); + singleLine.push_back("cmake_install.cmake"); + cpackCommandLines.push_back(singleLine); + const char* noall = + mf->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY"); + bool dependsOnAll = false; + if(!noall || cmSystemTools::IsOff(noall)) + { + dependsOnAll = true; + } + (*targets)[this->GetInstallTargetName()] = + this->CreateGlobalTarget( + this->GetInstallTargetName(), "Install the project...", + &cpackCommandLines, depends, dependsOnAll); +} + +cmTarget cmGlobalGenerator::CreateGlobalTarget( + const char* name, const char* message, + const cmCustomCommandLines* commandLines, + std::vector depends, + bool depends_on_all /* = false */) +{ + // Package + cmTarget target; + target.SetType(cmTarget::GLOBAL_TARGET, name); + target.SetInAll(false); + + // Store the custom command in the target. + cmCustomCommand cc(0, depends, *commandLines, 0, 0); + target.GetPostBuildCommands().push_back(cc); + target.SetProperty("EchoString", message); + if ( depends_on_all ) + { + target.SetProperty("DependsOnAll", "ON"); + } + return target; +} + //---------------------------------------------------------------------------- void cmGlobalGenerator::AppendDirectoryForConfig(const char*, std::string&) { diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 0899152b5..12a0163d0 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -20,6 +20,8 @@ #include "cmStandardIncludes.h" +#include "cmTarget.h" // For cmTargets + class cmake; class cmMakefile; class cmLocalGenerator; @@ -111,6 +113,7 @@ public: return this->m_CMakeInstance; }; void SetConfiguredFilesPath(const char* s){m_ConfiguredFilesPath = s;} + cmLocalGenerator* GetLocalGenerator(int p) { return m_LocalGenerators[p];} void GetLocalGenerators(std::vector&g) { g = m_LocalGenerators;} void AddLocalGenerator(cmLocalGenerator *lg); @@ -160,6 +163,18 @@ protected: void ConfigureRelativePaths(); void SetupTests(); + void CreateDefaultGlobalTargets(cmTargets* targets); + cmTarget CreateGlobalTarget(const char* name, const char* message, + const cmCustomCommandLines* commandLines, + std::vector depends, bool depends_on_all = false); + + virtual const char* GetInstallTargetName() { return "install"; } + virtual const char* GetPreinstallTargetName() { return "preinstall"; } + virtual const char* GetTestTargetName() { return "test"; } + virtual const char* GetPackageTargetName() { return "package"; } + virtual const char* GetEditCacheTargetName() { return "edit_cache"; } + virtual const char* GetRebuildCacheTargetName() { return "rebuild_cache"; } + bool m_ForceUnixPaths; cmStdString m_FindMakeProgramFile; cmStdString m_ConfiguredFilesPath; diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index d421b4be3..6fda8fa32 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -1250,41 +1250,50 @@ void cmLocalUnixMakefileGenerator3 no_commands, true); } - // Write special "test" target to run ctest. - if(m_Makefile->IsOn("CMAKE_TESTING_ENABLED")) + // Write all global targets + cmTargets* targets = &(m_Makefile->GetTargets()); + cmTargets::iterator glIt; + for ( glIt = targets->begin(); glIt != targets->end(); ++ glIt ) { - std::string ctest; - if(m_Makefile->GetDefinition("CMake_BINARY_DIR")) + if ( glIt->second.GetType() == cmTarget::GLOBAL_TARGET ) { - // We are building CMake itself. Use the ctest that comes with - // this version of CMake instead of the one used to build it. - ctest = m_ExecutableOutputPath; - ctest += "ctest"; - ctest += cmSystemTools::GetExecutableExtension(); - ctest = this->Convert(ctest.c_str(),START_OUTPUT,SHELL); - ctest += " --force-new-ctest-process"; + std::string targetString = "Special rule for the target " + glIt->first; + std::vector commands; + std::vector depends; + + const char* text = glIt->second.GetProperty("EchoString"); + if ( !text ) + { + text = "Running external command ..."; + } + const char* dependsOnAll = glIt->second.GetProperty("DependsOnAll"); + if ( dependsOnAll || cmSystemTools::IsOn(dependsOnAll) ) + { + depends.push_back("all"); + } + this->AppendEcho(commands, text); + size_t cc; + std::cout << "Target: " << text << std::endl; + for ( cc = 0; cc < depends.size(); ++ cc ) + { + std::cout << " Depends [" << depends[cc].c_str() << "]" << std::endl; + } + + // Utility targets store their rules in pre- and post-build commands. + this->AppendCustomDepends(depends, glIt->second.GetPreBuildCommands()); + this->AppendCustomDepends(depends, glIt->second.GetPostBuildCommands()); + std::cout << "Target: " << text << std::endl; + for ( cc = 0; cc < depends.size(); ++ cc ) + { + std::cout << " Depends [" << depends[cc].c_str() << "]" << std::endl; + } + this->AppendCustomCommands(commands, glIt->second.GetPreBuildCommands()); + this->AppendCustomCommands(commands, glIt->second.GetPostBuildCommands()); + this->WriteMakeRule(ruleFileStream, targetString.c_str(), glIt->first.c_str(), depends, commands, false); } - else - { - // We are building another project. Use the ctest that comes with - // the CMake building it. - ctest = m_Makefile->GetRequiredDefinition("CMAKE_COMMAND"); - ctest = cmSystemTools::GetFilenamePath(ctest.c_str()); - ctest += "/"; - ctest += "ctest"; - ctest += cmSystemTools::GetExecutableExtension(); - ctest = this->ConvertToOutputForExisting(ctest.c_str()); - } - std::vector no_depends; - std::vector commands; - this->AppendEcho(commands, "Running tests..."); - ctest += " $(ARGS)"; - commands.push_back(ctest); - this->WriteMakeRule(ruleFileStream, - "Special rule to drive testing with ctest.", - "test", no_depends, commands, true); } + // Write special "install" target to run cmake_install.cmake script. { std::vector depends; @@ -1307,7 +1316,7 @@ void cmLocalUnixMakefileGenerator3 commands.push_back(cmd); this->WriteMakeRule(ruleFileStream, "Special rule to run installation script.", - "install", depends, commands, true); + "old_install", depends, commands, true); commands.clear(); depends.clear(); @@ -1330,50 +1339,6 @@ void cmLocalUnixMakefileGenerator3 "preinstall", depends, commands, true); } - // Write special "rebuild_cache" target to re-run cmake. - { - std::vector no_depends; - std::vector commands; - this->AppendEcho(commands, "Running CMake to regenerate build system..."); - commands.push_back( - "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)"); - this->WriteMakeRule(ruleFileStream, - "Special rule to re-run CMake using make.", - "rebuild_cache", - no_depends, - commands, true); - } - - // Use CMAKE_EDIT_COMMAND for the edit_cache rule if it is defined. - // Otherwise default to the interactive command-line interface. - if(m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND")) - { - std::vector no_depends; - std::vector commands; - this->AppendEcho(commands, "Running CMake cache editor..."); - commands.push_back( - "$(CMAKE_EDIT_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)"); - this->WriteMakeRule(ruleFileStream, - "Special rule to re-run CMake cache editor using make.", - "edit_cache", - no_depends, - commands, true); - } - else - { - std::vector no_depends; - std::vector commands; - this->AppendEcho(commands, - "Running interactive CMake command-line interface..."); - commands.push_back( - "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) -i"); - this->WriteMakeRule(ruleFileStream, - "Special rule to re-run CMake cache editor using make.", - "edit_cache", - no_depends, - commands, true); - } - this->WriteSpecialTargetsTop(ruleFileStream); std::vector depends;