ENH: add re run cmake if inputs change

This commit is contained in:
Bill Hoffman 2005-02-28 15:07:13 -05:00
parent 46fc2dc0cd
commit b7ef8149e8
2 changed files with 107 additions and 74 deletions

View File

@ -25,7 +25,6 @@
//TODO //TODO
// add a group for Sources Headers, and other cmake group stuff // add a group for Sources Headers, and other cmake group stuff
// add rebuild when cmake changes
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmGlobalXCodeGenerator::cmGlobalXCodeGenerator() cmGlobalXCodeGenerator::cmGlobalXCodeGenerator()
@ -227,6 +226,10 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
commandLines.push_back(makecommand); commandLines.push_back(makecommand);
mf->AddUtilityCommand("XCODE_DEPEND_HELPER", false, no_output, no_depends, mf->AddUtilityCommand("XCODE_DEPEND_HELPER", false, no_output, no_depends,
commandLines); commandLines);
// Add Re-Run CMake rules
this->CreateReRunCMakeFile(root);
// now make the allbuild depend on all the non-utility targets // now make the allbuild depend on all the non-utility targets
// in the project // in the project
for(std::vector<cmLocalGenerator*>::iterator i = gens.begin(); for(std::vector<cmLocalGenerator*>::iterator i = gens.begin();
@ -249,7 +252,6 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
{ {
target.AddUtility("XCODE_DEPEND_HELPER"); target.AddUtility("XCODE_DEPEND_HELPER");
} }
if(target.IsInAll()) if(target.IsInAll())
{ {
allbuild->AddUtility(target.GetName()); allbuild->AddUtility(target.GetName());
@ -259,6 +261,37 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
} }
//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::CreateReRunCMakeFile(cmLocalGenerator* root)
{
cmMakefile* mf = root->GetMakefile();
std::vector<std::string> lfiles = mf->GetListFiles();
// sort the array
std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>());
std::vector<std::string>::iterator new_end =
std::unique(lfiles.begin(), lfiles.end());
lfiles.erase(new_end, lfiles.end());
std::string dir = mf->GetHomeOutputDirectory();
m_CurrentReRunCMakeMakefile = dir;
m_CurrentReRunCMakeMakefile += "/CMakeScripts";
cmSystemTools::MakeDirectory(m_CurrentReRunCMakeMakefile.c_str());
m_CurrentReRunCMakeMakefile += "/ReRunCMake.make";
cmGeneratedFileStream makefileStream(m_CurrentReRunCMakeMakefile.c_str());
makefileStream << "# Generated by CMake, DO NOT EDIT\n";
makefileStream << "cmake.check_cache: ";
for(std::vector<std::string>::const_iterator i = lfiles.begin();
i != lfiles.end(); ++i)
{
makefileStream << "\\\n" << *i;
}
std::string cmake = mf->GetRequiredDefinition("CMAKE_COMMAND");
makefileStream << "\n\t" << this->ConvertToRelativeForMake(cmake.c_str())
<< " -H" << this->ConvertToRelativeForMake(
mf->GetHomeDirectory())
<< " -B" << this->ConvertToRelativeForMake(
mf->GetHomeOutputDirectory()) << "\n";
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::ClearXCodeObjects() void cmGlobalXCodeGenerator::ClearXCodeObjects()
{ {
@ -370,7 +403,7 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname) bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname)
{ {
if(tname == "ALL_BUILD" || tname == "XCODE_DEPEND_HELPER" || if(tname == "ALL_BUILD" || tname == "XCODE_DEPEND_HELPER" ||
tname == "install" || tname == "RUN_TESTS") tname == "install" || tname == "RUN_TESTS" )
{ {
if(m_TargetDoneSet.find(tname) != m_TargetDoneSet.end()) if(m_TargetDoneSet.find(tname) != m_TargetDoneSet.end())
{ {
@ -492,6 +525,35 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
} }
} }
//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateBuildPhase(const char* name,
const char* name2,
cmTarget& cmtarget,
const std::vector<cmCustomCommand>&
commands)
{
if(commands.size() == 0 && strcmp(name, "CMake ReRun") != 0)
{
return 0;
}
cmXCodeObject* buildPhase =
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
buildPhase->AddAttribute("buildActionMask",
this->CreateString("2147483647"));
cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
buildPhase->AddAttribute("files", buildFiles);
buildPhase->AddAttribute("name",
this->CreateString(name));
buildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
this->CreateString("0"));
buildPhase->AddAttribute("shellPath",
this->CreateString("/bin/sh"));
this->AddCommandsToBuildPhase(buildPhase, cmtarget, commands,
name2);
return buildPhase;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases, void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
cmXCodeObject* cmXCodeObject*
@ -520,80 +582,29 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
commands.push_back(*(*i)->GetCustomCommand()); commands.push_back(*(*i)->GetCustomCommand());
} }
} }
std::vector<cmCustomCommand> reruncom;
cmXCodeObject* cmakeReRunPhase = this->CreateBuildPhase("CMake ReRun",
"cmakeReRunPhase",
cmtarget, reruncom);
buildPhases->AddObject(cmakeReRunPhase);
// create prebuild phase // create prebuild phase
cmXCodeObject* cmakeRulesBuildPhase = 0; cmXCodeObject* cmakeRulesBuildPhase =
if(commands.size()) this->CreateBuildPhase("CMake Rules",
{ "cmakeRulesBuildPhase",
cmakeRulesBuildPhase = cmtarget, commands);
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
cmakeRulesBuildPhase->AddAttribute("buildActionMask",
this->CreateString("2147483647"));
cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
cmakeRulesBuildPhase->AddAttribute("files", buildFiles);
cmakeRulesBuildPhase->AddAttribute("name",
this->CreateString("CMake Rules"));
cmakeRulesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
this->CreateString("0"));
cmakeRulesBuildPhase->AddAttribute("shellPath",
this->CreateString("/bin/sh"));
this->AddCommandsToBuildPhase(cmakeRulesBuildPhase, cmtarget, commands,
"cmakeRulesCommands");
}
// create prebuild phase // create prebuild phase
cmXCodeObject* preBuildPhase = 0; cmXCodeObject* preBuildPhase = this->CreateBuildPhase("CMake PreBuild Rules",
if(prebuild.size()) "preBuildCommands",
{ cmtarget, prebuild);
preBuildPhase =
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
preBuildPhase->AddAttribute("buildActionMask",
this->CreateString("2147483647"));
cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
preBuildPhase->AddAttribute("files", buildFiles);
preBuildPhase->AddAttribute("name",
this->CreateString("CMake PreBuild Rules"));
preBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
this->CreateString("0"));
preBuildPhase->AddAttribute("shellPath", this->CreateString("/bin/sh"));
this->AddCommandsToBuildPhase(preBuildPhase, cmtarget, prebuild,
"preBuildCommands");
}
// create prebuild phase // create prebuild phase
cmXCodeObject* preLinkPhase = 0; cmXCodeObject* preLinkPhase = this->CreateBuildPhase("CMake PreLink Rules",
if(prelink.size()) "preLinkCommands",
{ cmtarget, prelink);
preLinkPhase =
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
preLinkPhase->AddAttribute("buildActionMask",
this->CreateString("2147483647"));
cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
preLinkPhase->AddAttribute("files", buildFiles);
preLinkPhase->AddAttribute("name",
this->CreateString("CMake PreLink Rules"));
preLinkPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
this->CreateString("0"));
preLinkPhase->AddAttribute("shellPath", this->CreateString("/bin/sh"));
this->AddCommandsToBuildPhase(preLinkPhase, cmtarget, prelink,
"preLinkCommands");
}
// create prebuild phase // create prebuild phase
cmXCodeObject* postBuildPhase = 0; cmXCodeObject* postBuildPhase =
if(postbuild.size()) this->CreateBuildPhase("CMake PostBuild Rules",
{ "postBuildPhase",
postBuildPhase = cmtarget, postbuild);
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
postBuildPhase->AddAttribute("buildActionMask",
this->CreateString("2147483647"));
cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
postBuildPhase->AddAttribute("files", buildFiles);
postBuildPhase->AddAttribute("name",
this->CreateString("CMake PostBuild Rules"));
postBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
this->CreateString("0"));
postBuildPhase->AddAttribute("shellPath", this->CreateString("/bin/sh"));
this->AddCommandsToBuildPhase(postBuildPhase, cmtarget, postbuild,
"postBuildCommands");
}
// the order here is the order they will be built in // the order here is the order they will be built in
if(preBuildPhase) if(preBuildPhase)
{ {
@ -633,6 +644,21 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
const & commands, const & commands,
const char* name) const char* name)
{ {
if(strcmp(name, "cmakeReRunPhase") == 0)
{
std::string cdir = m_CurrentMakefile->GetHomeOutputDirectory();
cdir = this->ConvertToRelativeForMake(cdir.c_str());
std::string makecmd = "make -C ";
makecmd += cdir;?
makecmd += " -f ";
makecmd +=
this->ConvertToRelativeForMake(m_CurrentReRunCMakeMakefile.c_str());
cmSystemTools::ReplaceString(makecmd, "\\ ", "\\\\ ");
buildphase->AddAttribute("shellScript",
this->CreateString(makecmd.c_str()));
return;
}
std::string dir = m_CurrentMakefile->GetCurrentOutputDirectory(); std::string dir = m_CurrentMakefile->GetCurrentOutputDirectory();
dir += "/CMakeScripts"; dir += "/CMakeScripts";
cmSystemTools::MakeDirectory(dir.c_str()); cmSystemTools::MakeDirectory(dir.c_str());
@ -1183,7 +1209,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
if(bset) if(bset)
{ {
bset->AddAttribute("LIBRARY_SEARCH_PATHS", bset->AddAttribute("LIBRARY_SEARCH_PATHS",
this->CreateString(linkDirs.c_str())); this->CreateString(linkDirs.c_str()));
} }
// now add the link libraries // now add the link libraries
for(std::vector<cmStdString>::iterator lib = linkItems.begin(); for(std::vector<cmStdString>::iterator lib = linkItems.begin();
@ -1222,6 +1248,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
else else
{ {
std::cerr << "Error Utility: " << i->c_str() << "\n"; std::cerr << "Error Utility: " << i->c_str() << "\n";
std::cerr << "cmtarget " << t << "\n";
std::cerr << "Is on the target " << cmtarget->GetName() << "\n"; std::cerr << "Is on the target " << cmtarget->GetName() << "\n";
std::cerr << "But it has no xcode target created yet??\n"; std::cerr << "But it has no xcode target created yet??\n";
std::cerr << "Current project is " std::cerr << "Current project is "

View File

@ -123,6 +123,11 @@ private:
bool SpecialTargetEmitted(std::string const& tname); bool SpecialTargetEmitted(std::string const& tname);
void AddExtraTargets(cmLocalGenerator* root, void AddExtraTargets(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& gens); std::vector<cmLocalGenerator*>& gens);
cmXCodeObject* CreateBuildPhase(const char* name,
const char* name2,
cmTarget& cmtarget,
const std::vector<cmCustomCommand>&);
void CreateReRunCMakeFile(cmLocalGenerator* root);
private: private:
std::vector<cmXCodeObject*> m_XCodeObjects; std::vector<cmXCodeObject*> m_XCodeObjects;
cmXCodeObject* m_RootObject; cmXCodeObject* m_RootObject;
@ -136,6 +141,7 @@ private:
std::set<cmStdString> m_TargetDoneSet; std::set<cmStdString> m_TargetDoneSet;
bool m_DoneAllBuild; bool m_DoneAllBuild;
bool m_DoneXCodeHack; bool m_DoneXCodeHack;
std::string m_CurrentReRunCMakeMakefile;
std::string m_CurrentXCodeHackMakefile; std::string m_CurrentXCodeHackMakefile;
std::string m_OutputDir; std::string m_OutputDir;
std::vector<std::string> m_CurrentOutputDirectoryComponents; std::vector<std::string> m_CurrentOutputDirectoryComponents;