Commit 12dc64c7 authored by Andy Cedilnik's avatar Andy Cedilnik
Browse files

ENH: Add a notion of a global target

parent ea556462
......@@ -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<std::string> 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<std::string> 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&)
{
......
......@@ -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<cmLocalGenerator *>&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<std::string> 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;
......
......@@ -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";
}
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::string targetString = "Special rule for the target " + glIt->first;
std::vector<std::string> commands;
std::vector<std::string> 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);
}
std::vector<std::string> no_depends;
std::vector<std::string> 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<std::string> 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<std::string> no_depends;
std::vector<std::string> 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<std::string> no_depends;
std::vector<std::string> 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<std::string> no_depends;
std::vector<std::string> 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<std::string> depends;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment