summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/cmCustomCommand.h4
-rw-r--r--Source/cmGlobalGenerator.cxx18
-rw-r--r--Source/cmGlobalGenerator.h2
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx2
-rw-r--r--Source/cmGlobalVisualStudio6Generator.cxx5
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx3
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx167
-rw-r--r--Source/cmGlobalXCodeGenerator.h9
-rw-r--r--Source/cmLocalGenerator.cxx39
-rw-r--r--Source/cmLocalGenerator.h14
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx6
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx96
-rw-r--r--Source/cmLocalVisualStudio6Generator.h6
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx60
-rw-r--r--Source/cmLocalVisualStudio7Generator.h10
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx7
-rw-r--r--Source/cmLocalVisualStudioGenerator.h1
-rw-r--r--Source/cmMakefile.cxx12
-rw-r--r--Source/cmTarget.cxx54
-rw-r--r--Source/cmTarget.h11
20 files changed, 342 insertions, 184 deletions
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index 5d59f0a..f7c6b5e 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -69,8 +69,8 @@ public:
void SetEscapeAllowMakeVars(bool b);
/** set get the used status of the command */
- void SetUsed() { this->Used = true;};
- bool IsUsed() { return this->Used;};
+ void SetUsed() { this->Used = true;}
+ bool IsUsed() const { return this->Used;}
private:
std::vector<std::string> Outputs;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index a0e66d3..1691308 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -718,6 +718,13 @@ void cmGlobalGenerator::Configure()
// at this point this->LocalGenerators has been filled,
// so create the map from project name to vector of local generators
this->FillProjectMap();
+ // now create project to target map
+ // This will make sure that targets have all the
+ // targets they depend on as part of the build.
+ this->FillProjectToTargetMap();
+ // now trace all dependencies
+ this->TraceDependencies();
+
if ( !this->CMakeInstance->GetScriptMode() )
{
this->CMakeInstance->UpdateProgress("Configuring done", -1);
@@ -1036,6 +1043,13 @@ const char* cmGlobalGenerator::GetLinkerPreference(const char* lang)
return "None";
}
+void cmGlobalGenerator::TraceDependencies()
+{
+ for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ this->LocalGenerators[i]->TraceDependencies();
+ }
+}
void cmGlobalGenerator::FillProjectMap()
{
@@ -1057,10 +1071,6 @@ void cmGlobalGenerator::FillProjectMap()
}
while (lg);
}
- // now create project to target map
- // This will make sure that targets have all the
- // targets they depend on as part of the build.
- this->FillProjectToTargetMap();
}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 65fe715..0c0cd20 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -202,6 +202,8 @@ protected:
void FillProjectMap();
bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen);
void FillProjectToTargetMap();
+ // Calls TraceVSDependencies() on all targets
+ void TraceDependencies();
void CreateDefaultGlobalTargets(cmTargets* targets);
cmTarget CreateGlobalTarget(const char* name, const char* message,
const cmCustomCommandLines* commandLines,
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index b4e05ed..068cc51 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -1056,7 +1056,7 @@ cmGlobalUnixMakefileGenerator3
{
cmTarget *result;
cmLocalUnixMakefileGenerator3 *lg3;
-
+
// first check the same dir as the current target
lg3 = static_cast<cmLocalUnixMakefileGenerator3 *>
(target.GetMakefile()->GetLocalGenerator());
diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx
index 3b905c0..3829b3e 100644
--- a/Source/cmGlobalVisualStudio6Generator.cxx
+++ b/Source/cmGlobalVisualStudio6Generator.cxx
@@ -208,9 +208,8 @@ void cmGlobalVisualStudio6Generator
static_cast<cmLocalVisualStudio6Generator *>(generators[i])
->GetCreatedProjectNames();
cmTargets &tgts = generators[i]->GetMakefile()->GetTargets();
- cmTargets::iterator l = tgts.begin();
- for(std::vector<std::string>::iterator si = dspnames.begin();
- l != tgts.end(); ++l)
+ std::vector<std::string>::iterator si = dspnames.begin();
+ for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
{
// special handling for the current makefile
if(mf == generators[0]->GetMakefile())
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index afe96e7..67fd7a3 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -294,8 +294,7 @@ void cmGlobalVisualStudio7Generator
// than one dsp could have been created per input CMakeLists.txt file
// for each target
cmTargets &tgts = generators[i]->GetMakefile()->GetTargets();
- cmTargets::iterator l = tgts.begin();
- for(; l != tgts.end(); ++l)
+ for (cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
{
// special handling for the current makefile
if(mf == generators[0]->GetMakefile())
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 7e6d506..580aa5b 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -577,16 +577,17 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
{
continue;
}
+
+ if(cmtarget.GetType() == cmTarget::UTILITY ||
+ cmtarget.GetType() == cmTarget::GLOBAL_TARGET)
+ {
+ targets.push_back(this->CreateUtilityTarget(cmtarget));
+ }
if(cmtarget.GetType() == cmTarget::UTILITY ||
cmtarget.GetType() == cmTarget::GLOBAL_TARGET ||
cmtarget.GetType() == cmTarget::INSTALL_FILES ||
cmtarget.GetType() == cmTarget::INSTALL_PROGRAMS)
{
- if(cmtarget.GetType() == cmTarget::UTILITY ||
- cmtarget.GetType() == cmTarget::GLOBAL_TARGET)
- {
- targets.push_back(this->CreateUtilityTarget(cmtarget));
- }
continue;
}
@@ -849,6 +850,7 @@ std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
}
return retFlag;
}
+
//----------------------------------------------------------------------------
void
cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
@@ -872,8 +874,31 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
return;
}
+ // collect multiple outputs of custom commands into a set
+ // which will be used for every configuration
std::map<cmStdString, cmStdString> multipleOutputPairs;
-
+ for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
+ i != commands.end(); ++i)
+ {
+ cmCustomCommand const& cc = *i;
+ if(!cc.GetCommandLines().empty())
+ {
+ const std::vector<std::string>& outputs = cc.GetOutputs();
+ if(!outputs.empty())
+ {
+ // If there are more than one outputs treat the
+ // first as the primary output and make the rest depend on it.
+ std::vector<std::string>::const_iterator o = outputs.begin();
+ std::string primaryOutput = this->ConvertToRelativeForMake(o->c_str());
+ for(++o; o != outputs.end(); ++o)
+ {
+ std::string currentOutput =this->ConvertToRelativeForMake(o->c_str());
+ multipleOutputPairs[currentOutput] = primaryOutput;
+ }
+ }
+ }
+ }
+
std::string dir = this->CurrentMakefile->GetCurrentOutputDirectory();
dir += "/CMakeScripts";
cmSystemTools::MakeDirectory(dir.c_str());
@@ -883,7 +908,48 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
makefile += "_";
makefile += name;
makefile += ".make";
- cmGeneratedFileStream makefileStream(makefile.c_str());
+
+ for (std::vector<std::string>::const_iterator currentConfig=
+ this->CurrentConfigurationTypes.begin();
+ currentConfig!=this->CurrentConfigurationTypes.end();
+ currentConfig++ )
+ {
+ this->CreateCustomRulesMakefile(makefile.c_str(),
+ target,
+ commands,
+ currentConfig->c_str(),
+ multipleOutputPairs);
+ }
+
+ std::string cdir = this->CurrentMakefile->GetCurrentOutputDirectory();
+ cdir = this->ConvertToRelativeForXCode(cdir.c_str());
+ std::string makecmd = "make -C ";
+ makecmd += cdir;
+ makecmd += " -f ";
+ makecmd += this->ConvertToRelativeForMake((makefile+"$CONFIGURATION").c_str());
+ if(!multipleOutputPairs.empty())
+ {
+ makecmd += " cmake_check_multiple_outputs";
+ }
+ makecmd += " all";
+ cmSystemTools::ReplaceString(makecmd, "\\ ", "\\\\ ");
+ buildphase->AddAttribute("shellScript",
+ this->CreateString(makecmd.c_str()));
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator
+::CreateCustomRulesMakefile(const char* makefileBasename,
+ cmTarget& target,
+ std::vector<cmCustomCommand>
+ const & commands,
+ const char* configName,
+ const std::map<cmStdString, cmStdString>& multipleOutputPairs
+ )
+{
+ std::string makefileName=makefileBasename;
+ makefileName+=configName;
+ cmGeneratedFileStream makefileStream(makefileName.c_str());
if(!makefileStream)
{
return;
@@ -909,7 +975,7 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
o != outputs.end(); ++o)
{
makefileStream
- << "\\\n\t" << this->ConvertToRelativeForMake(o->c_str());
+ << "\\\n\t" << this->ConvertToRelativeForMake(o->c_str());
}
}
else
@@ -939,21 +1005,9 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
const std::vector<std::string>& outputs = cc.GetOutputs();
if(!outputs.empty())
{
- // There is at least one output. If there is more than one treat the
- // first as the primary output and make the rest depend on it.
- std::vector<std::string>::const_iterator o = outputs.begin();
+ // There is at least one output, start the rule for it
std::string primary_output =
- this->ConvertToRelativeForMake(o->c_str());
- for(++o; o != outputs.end(); ++o)
- {
- std::string current_output =
- this->ConvertToRelativeForMake(o->c_str());
- makefileStream << current_output << ": "
- << primary_output << "\n";
- multipleOutputPairs[current_output] = primary_output;
- }
-
- // Start the rule for the primary output.
+ this->ConvertToRelativeForMake(outputs.begin()->c_str());
makefileStream << primary_output << ": ";
}
else
@@ -962,11 +1016,11 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
makefileStream << tname[&cc] << ": ";
}
for(std::vector<std::string>::const_iterator d =
- cc.GetDepends().begin();
+ cc.GetDepends().begin();
d != cc.GetDepends().end(); ++d)
{
if(!this->FindTarget(this->CurrentProject.c_str(),
- d->c_str()))
+ d->c_str()))
{
// if the depend is not a target but
// is a full path then use it, if not then
@@ -974,7 +1028,7 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
if(cmSystemTools::FileIsFullPath(d->c_str()))
{
makefileStream << "\\\n" << this
- ->ConvertToRelativeForMake(d->c_str());
+ ->ConvertToRelativeForMake(d->c_str());
}
}
else
@@ -989,12 +1043,14 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
// Add each command line to the set of commands.
for(cmCustomCommandLines::const_iterator cl =
- cc.GetCommandLines().begin();
+ cc.GetCommandLines().begin();
cl != cc.GetCommandLines().end(); ++cl)
{
// Build the command line in a single string.
const cmCustomCommandLine& commandLine = *cl;
- std::string cmd2 = commandLine[0];
+ std::string cmd2 = this->CurrentLocalGenerator
+ ->GetRealLocation(commandLine[0].c_str(), configName);
+
cmSystemTools::ReplaceString(cmd2, "/./", "/");
cmd2 = this->ConvertToRelativeForMake(cmd2.c_str());
std::string cmd;
@@ -1011,13 +1067,13 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
if(escapeOldStyle)
{
cmd += (this->CurrentLocalGenerator
- ->EscapeForShellOldStyle(commandLine[j].c_str()));
+ ->EscapeForShellOldStyle(commandLine[j].c_str()));
}
else
{
cmd += (this->CurrentLocalGenerator->
- EscapeForShell(commandLine[j].c_str(),
- escapeAllowMakeVars));
+ EscapeForShell(commandLine[j].c_str(),
+ escapeAllowMakeVars));
}
}
makefileStream << "\t" << cmd.c_str() << "\n";
@@ -1025,38 +1081,31 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
}
}
- // Add a rule to deal with multiple outputs of custom commands.
+ // Add rules to deal with multiple outputs of custom commands.
if(!multipleOutputPairs.empty())
{
+ makefileStream <<
+ "\n# Dependencies of multiple outputs to their primary outputs \n";
+
+ for(std::map<cmStdString, cmStdString>::const_iterator o =
+ multipleOutputPairs.begin(); o != multipleOutputPairs.end(); ++o)
+ {
+ makefileStream << o->first << ": " << o->second << "\n";
+ }
+
makefileStream <<
- "\n"
- "cmake_check_multiple_outputs:\n";
+ "\n"
+ "cmake_check_multiple_outputs:\n";
for(std::map<cmStdString, cmStdString>::const_iterator o =
- multipleOutputPairs.begin(); o != multipleOutputPairs.end(); ++o)
+ multipleOutputPairs.begin(); o != multipleOutputPairs.end(); ++o)
{
makefileStream << "\t@if [ ! -f "
- << o->first << " ]; then rm -f "
- << o->second << "; fi\n";
+ << o->first << " ]; then rm -f "
+ << o->second << "; fi\n";
}
}
-
- std::string cdir = this->CurrentMakefile->GetCurrentOutputDirectory();
- cdir = this->ConvertToRelativeForXCode(cdir.c_str());
- std::string makecmd = "make -C ";
- makecmd += cdir;
- makecmd += " -f ";
- makecmd += this->ConvertToRelativeForMake(makefile.c_str());
- if(!multipleOutputPairs.empty())
- {
- makecmd += " cmake_check_multiple_outputs";
- }
- makecmd += " all";
- cmSystemTools::ReplaceString(makecmd, "\\ ", "\\\\ ");
- buildphase->AddAttribute("shellScript",
- this->CreateString(makecmd.c_str()));
}
-
//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
cmXCodeObject* buildSettings,
@@ -2406,20 +2455,6 @@ cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root,
cmMakefile* mf = (*g)->GetMakefile();
std::vector<cmSourceGroup> sourceGroups = mf->GetSourceGroups();
cmTargets &tgts = mf->GetTargets();
- // Call TraceVSDependencies on all targets
- for(cmTargets::iterator l = tgts.begin();
- l != tgts.end(); l++)
- {
- // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
- // so don't build a projectfile for it
- if ((l->second.GetType() != cmTarget::INSTALL_FILES)
- && (l->second.GetType() != cmTarget::INSTALL_PROGRAMS)
- && (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0))
- {
- cmTarget& target = l->second;
- target.TraceVSDependencies(target.GetName(), mf);
- }
- }
// now for all custom commands that are not used directly in a
// target, add them to all targets in the current directory or
// makefile
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index e9091e4..4a08217 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -106,6 +106,15 @@ private:
std::vector<cmCustomCommand>
const & commands,
const char* commandFileName);
+
+ void CreateCustomRulesMakefile(const char* makefileBasename,
+ cmTarget& target,
+ std::vector<cmCustomCommand> const & commands,
+ const char* configName,
+ const std::map<cmStdString, cmStdString>&
+ multipleOutputPairs
+ );
+
cmXCodeObject* FindXCodeTarget(cmTarget*);
// create cmXCodeObject from these functions so that memory can be managed
// correctly. All objects created are stored in this->XCodeObjects.
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 05ba04d..ec78daf 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -52,6 +52,7 @@ cmLocalGenerator::cmLocalGenerator()
this->UseRelativePaths = false;
this->Configured = false;
this->EmitUniversalBinaryFlags = true;
+ this->IsMakefileGenerator = false;
this->RelativePathsConfigured = false;
this->PathConversionsSetup = false;
}
@@ -135,6 +136,30 @@ void cmLocalGenerator::ConfigureFinalPass()
this->Makefile->ConfigureFinalPass();
}
+void cmLocalGenerator::TraceDependencies()
+{
+ // Generate the rule files for each target.
+ cmTargets& targets = this->Makefile->GetTargets();
+ for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ {
+ // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
+ // so don't build a projectfile for it
+ if ((t->second.GetType() != cmTarget::INSTALL_FILES)
+ && (t->second.GetType() != cmTarget::INSTALL_PROGRAMS)
+ && (t->second.GetType() != cmTarget::INSTALL_DIRECTORY)
+ && (strncmp(t->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0)
+ && (t->second.GetPropertyAsBool("IMPORTED") == false))
+ {
+ std::string projectFilename;
+ if (this->IsMakefileGenerator == false) // only use of this variable
+ {
+ projectFilename=t->second.GetName();
+ }
+ t->second.TraceVSDependencies(projectFilename, this->Makefile);
+ }
+ }
+}
+
void cmLocalGenerator::GenerateTestFiles()
{
if ( !this->Makefile->IsOn("CMAKE_TESTING_ENABLED") )
@@ -1987,6 +2012,20 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName,
}
//----------------------------------------------------------------------------
+std::string cmLocalGenerator::GetRealLocation(const char* inName,
+ const char* config)
+{
+ std::string outName=inName;
+ // Look for a CMake target with the given name.
+ cmTarget* target = this->GlobalGenerator->FindTarget(0, inName);
+ if ((target!=0) && (target->GetType()==cmTarget::EXECUTABLE))
+ {
+ outName = target->GetLocation( config );
+ }
+ return outName;
+}
+
+//----------------------------------------------------------------------------
void cmLocalGenerator::AddSharedFlags(std::string& flags,
const char* lang,
bool shared)
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 6519889..a9f5682 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -42,7 +42,7 @@ public:
/**
* Generate the makefile for this directory.
*/
- virtual void Generate() {};
+ virtual void Generate() {}
/**
* Process the CMakeLists files for this directory to fill in the
@@ -50,6 +50,11 @@ public:
*/
virtual void Configure();
+ /**
+ * Calls TraceVSDependencies() on all targets of this generator.
+ */
+ virtual void TraceDependencies();
+
/**
* Perform any final calculations prior to generation
*/
@@ -137,6 +142,11 @@ public:
the source directory of this generator. This should only be
used for dependencies of custom commands. */
std::string GetRealDependency(const char* name, const char* config);
+
+ /** Translate a command as given in CMake code to the location of the
+ executable if the command is the name of a CMake executable target.
+ If that's not the case, just return the original name. */
+ std::string GetRealLocation(const char* inName, const char* config);
///! for existing files convert to output path and short path if spaces
std::string ConvertToOutputForExisting(const char* p);
@@ -298,6 +308,8 @@ protected:
bool IgnoreLibPrefix;
bool Configured;
bool EmitUniversalBinaryFlags;
+ // A type flag is not nice. It's used only in TraceDependencies().
+ bool IsMakefileGenerator;
// Hack for ExpandRuleVariable until object-oriented version is
// committed.
std::string TargetImplib;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 2b8f346..a48bebb 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -54,6 +54,7 @@ cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3()
this->NativeEchoCommand = "@echo ";
this->NativeEchoWindows = true;
this->MakeCommandEscapeTargetTwice = false;
+ this->IsMakefileGenerator = true;
}
//----------------------------------------------------------------------------
@@ -112,7 +113,7 @@ void cmLocalUnixMakefileGenerator3::Generate()
if (tg)
{
this->TargetGenerators.push_back(tg);
- t->second.TraceVSDependencies(empty, this->Makefile);
+// t->second.TraceVSDependencies(empty, this->Makefile);
tg->WriteRuleFiles();
}
}
@@ -885,7 +886,8 @@ cmLocalUnixMakefileGenerator3
{
// Build the command line in a single string.
const cmCustomCommandLine& commandLine = *cl;
- std::string cmd = commandLine[0];
+ std::string cmd = GetRealLocation(commandLine[0].c_str(),
+ this->ConfigurationName.c_str());
if (cmd.size())
{
cmSystemTools::ReplaceString(cmd, "/./", "/");
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 24a381a..b3ae6e2 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -116,16 +116,6 @@ void cmLocalVisualStudio6Generator::OutputDSPFile()
{
this->AddDSPBuildRule(l->second);
}
-
- // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
- // so don't build a projectfile for it
- if ((l->second.GetType() != cmTarget::INSTALL_FILES)
- && (l->second.GetType() != cmTarget::INSTALL_PROGRAMS)
- && (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0))
- {
- cmTarget& target = l->second;
- target.TraceVSDependencies(target.GetName(), this->Makefile);
- }
}
// build any targets
@@ -490,23 +480,8 @@ void cmLocalVisualStudio6Generator
}
if (command)
{
- std::string script =
- this->ConstructScript(command->GetCommandLines(),
- command->GetWorkingDirectory(),
- command->GetEscapeOldStyle(),
- command->GetEscapeAllowMakeVars(),
- "\\\n\t");
- std::string comment =
- this->ConstructComment(*command,
- "Building Custom Rule $(InputPath)");
- if(comment == "<hack>")
- {
- comment = "";
- }
const char* flags = compileFlags.size() ? compileFlags.c_str(): 0;
- this->WriteCustomRule(fout, source.c_str(), script.c_str(),
- comment.c_str(), command->GetDepends(),
- command->GetOutputs(), flags);
+ this->WriteCustomRule(fout, source.c_str(), *command, flags);
}
else if(!compileFlags.empty() || !objectNameDir.empty())
{
@@ -603,16 +578,29 @@ void
cmLocalVisualStudio6Generator
::WriteCustomRule(std::ostream& fout,
const char* source,
- const char* command,
- const char* comment,
- const std::vector<std::string>& depends,
- const std::vector<std::string>& outputs,
+ const cmCustomCommand& command,
const char* flags)
{
+ std::string comment =
+ this->ConstructComment(command, "Building Custom Rule $(InputPath)");
+ if(comment == "<hack>")
+ {
+ comment = "";
+ }
+
// Write the rule for each configuration.
std::vector<std::string>::iterator i;
for(i = this->Configurations.begin(); i != this->Configurations.end(); ++i)
{
+
+ std::string script =
+ this->ConstructScript(command.GetCommandLines(),
+ command.GetWorkingDirectory(),
+ i->c_str(),
+ command.GetEscapeOldStyle(),
+ command.GetEscapeAllowMakeVars(),
+ "\\\n\t");
+
if (i == this->Configurations.begin())
{
fout << "!IF \"$(CFG)\" == " << i->c_str() << std::endl;
@@ -627,8 +615,9 @@ cmLocalVisualStudio6Generator
}
// Write out the dependencies for the rule.
fout << "USERDEP__HACK=";
- for(std::vector<std::string>::const_iterator d = depends.begin();
- d != depends.end(); ++d)
+ for(std::vector<std::string>::const_iterator d=command.GetDepends().begin();
+ d != command.GetDepends().end();
+ ++d)
{
// Lookup the real name of the dependency in case it is a CMake target.
std::string dep = this->GetRealDependency(d->c_str(), i->c_str());
@@ -639,26 +628,28 @@ cmLocalVisualStudio6Generator
fout << "# PROP Ignore_Default_Tool 1\n";
fout << "# Begin Custom Build -";
- if(comment && *comment)
+ if(!comment.empty())
{
- fout << " " << comment;
+ fout << " " << comment.c_str();
}
fout << "\n\n";
- if(outputs.empty())
+ if(command.GetOutputs().empty())
{
fout << source
<< "_force : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
- fout << command << "\n\n";
+ fout << script.c_str() << "\n\n";
}
else
{
- for(std::vector<std::string>::const_iterator o = outputs.begin();
- o != outputs.end(); ++o)
+ for(std::vector<std::string>::const_iterator o =
+ command.GetOutputs().begin();
+ o != command.GetOutputs().end();
+ ++o)
{
// Write a rule for every output generated by this command.
fout << this->ConvertToOptionallyRelativeOutputPath(o->c_str())
<< " : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
- fout << command << "\n\n";
+ fout << script.c_str() << "\n\n";
}
}
fout << "# End Custom Build\n\n";
@@ -768,6 +759,7 @@ void cmLocalVisualStudio6Generator::SetBuildType(BuildType b,
// look for custom rules on a target and collect them together
std::string
cmLocalVisualStudio6Generator::CreateTargetRules(cmTarget &target,
+ const char* configName,
const char * /* libName */)
{
std::string customRuleCode = "";
@@ -808,6 +800,7 @@ cmLocalVisualStudio6Generator::CreateTargetRules(cmTarget &target,
}
customRuleCode += this->ConstructScript(cr->GetCommandLines(),
cr->GetWorkingDirectory(),
+ configName,
cr->GetEscapeOldStyle(),
cr->GetEscapeAllowMakeVars(),
"\\\n\t");
@@ -822,6 +815,7 @@ cmLocalVisualStudio6Generator::CreateTargetRules(cmTarget &target,
}
customRuleCode += this->ConstructScript(cr->GetCommandLines(),
cr->GetWorkingDirectory(),
+ configName,
cr->GetEscapeOldStyle(),
cr->GetEscapeAllowMakeVars(),
"\\\n\t");
@@ -850,6 +844,7 @@ cmLocalVisualStudio6Generator::CreateTargetRules(cmTarget &target,
}
customRuleCode += this->ConstructScript(cr->GetCommandLines(),
cr->GetWorkingDirectory(),
+ configName,
cr->GetEscapeOldStyle(),
cr->GetEscapeAllowMakeVars(),
"\\\n\t");
@@ -1274,7 +1269,14 @@ void cmLocalVisualStudio6Generator
// are there any custom rules on the target itself
// only if the target is a lib or exe
- std::string customRuleCode = this->CreateTargetRules(target, libName);
+ std::string customRuleCodeRelease
+ = this->CreateTargetRules(target, "RELEASE", libName);
+ std::string customRuleCodeDebug
+ = this->CreateTargetRules(target, "DEBUG", libName);
+ std::string customRuleCodeMinSizeRel
+ = this->CreateTargetRules(target, "MINSIZEREL", libName);
+ std::string customRuleCodeRelWithDebInfo
+ = this->CreateTargetRules(target, "RELWITHDEBINFO", libName);
std::ifstream fin(this->DSPHeaderTemplate.c_str());
if(!fin)
@@ -1307,8 +1309,6 @@ void cmLocalVisualStudio6Generator
}
cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME_EXPORTS",
exportSymbol.c_str());
- cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE",
- customRuleCode.c_str());
cmSystemTools::ReplaceString(line, "CMAKE_MFC_FLAG",
mfcFlag);
if(target.GetType() == cmTarget::STATIC_LIBRARY )
@@ -1337,6 +1337,18 @@ void cmLocalVisualStudio6Generator
cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIMIZED_LIBRARIES",
libMultiLineOptimizedOptions.c_str());
#endif
+
+ // Substitute the rules for custom command. When specifying just the
+ // target name for the command the command can be different for
+ // different configs
+ cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_RELEASE",
+ customRuleCodeRelease.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_DEBUG",
+ customRuleCodeDebug.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_MINSIZEREL",
+ customRuleCodeMinSizeRel.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_RELWITHDEBINFO",
+ customRuleCodeRelWithDebInfo.c_str());
// Substitute the real output name into the template.
cmSystemTools::ReplaceString(line, "OUTPUT_NAME_DEBUG",
diff --git a/Source/cmLocalVisualStudio6Generator.h b/Source/cmLocalVisualStudio6Generator.h
index 3b789f8..7ac84a4 100644
--- a/Source/cmLocalVisualStudio6Generator.h
+++ b/Source/cmLocalVisualStudio6Generator.h
@@ -84,10 +84,7 @@ private:
void AddDSPBuildRule(cmTarget& tgt);
void WriteCustomRule(std::ostream& fout,
const char* source,
- const char* command,
- const char* comment,
- const std::vector<std::string>& depends,
- const std::vector<std::string>& outputs,
+ const cmCustomCommand& command,
const char* flags);
void AddUtilityCommandHack(cmTarget& target, int count,
std::vector<std::string>& depends,
@@ -95,6 +92,7 @@ private:
void WriteGroup(const cmSourceGroup *sg, cmTarget target,
std::ostream &fout, const char *libName);
std::string CreateTargetRules(cmTarget &target,
+ const char* configName,
const char *libName);
void ComputeLinkOptions(cmTarget& target, const char* configName,
const std::string extraOptions,
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index c40ca42..6e2f1be 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -124,16 +124,6 @@ void cmLocalVisualStudio7Generator::OutputVCProjFile()
{
this->AddVCProjBuildRule(l->second);
}
-
- // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
- // so don't build a projectfile for it
- if ((l->second.GetType() != cmTarget::INSTALL_FILES)
- && (l->second.GetType() != cmTarget::INSTALL_PROGRAMS)
- && (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0))
- {
- cmTarget& target = l->second;
- target.TraceVSDependencies(target.GetName(), this->Makefile);
- }
}
for(cmTargets::iterator l = tgts.begin();
@@ -623,7 +613,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
<< "\t\t\t/>\n";
}
- this->OutputTargetRules(fout, target, libName);
+ this->OutputTargetRules(fout, configName, target, libName);
this->OutputBuildTool(fout, configName, target);
fout << "\t\t</Configuration>\n";
}
@@ -1141,17 +1131,8 @@ void cmLocalVisualStudio7Generator
fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
if (command)
{
- // Construct the entire set of commands in one string.
- std::string script =
- this->ConstructScript(command->GetCommandLines(),
- command->GetWorkingDirectory(),
- command->GetEscapeOldStyle(),
- command->GetEscapeAllowMakeVars());
- std::string comment = this->ConstructComment(*command);
const char* flags = compileFlags.size() ? compileFlags.c_str(): 0;
- this->WriteCustomRule(fout, source.c_str(), script.c_str(),
- comment.c_str(), command->GetDepends(),
- command->GetOutputs(), flags);
+ this->WriteCustomRule(fout, source.c_str(), *command, flags);
}
else if(compileFlags.size() || additionalDeps.length()
|| objectName.size() || excludedFromBuild)
@@ -1228,12 +1209,11 @@ void cmLocalVisualStudio7Generator
void cmLocalVisualStudio7Generator::
WriteCustomRule(std::ostream& fout,
const char* source,
- const char* command,
- const char* comment,
- const std::vector<std::string>& depends,
- const std::vector<std::string>& outputs,
+ const cmCustomCommand& command,
const char* compileFlags)
{
+ std::string comment = this->ConstructComment(command);
+
// Write the rule for each configuration.
std::vector<std::string>::iterator i;
std::vector<std::string> *configs =
@@ -1251,14 +1231,21 @@ WriteCustomRule(std::ostream& fout,
<< "\t\t\t\t\tAdditionalOptions=\""
<< this->EscapeForXML(compileFlags) << "\"/>\n";
}
+
+ std::string script =
+ this->ConstructScript(command.GetCommandLines(),
+ command.GetWorkingDirectory(),
+ i->c_str(),
+ command.GetEscapeOldStyle(),
+ command.GetEscapeAllowMakeVars());
fout << "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"VCCustomBuildTool\"\n"
<< "\t\t\t\t\tDescription=\""
- << this->EscapeForXML(comment) << "\"\n"
+ << this->EscapeForXML(comment.c_str()) << "\"\n"
<< "\t\t\t\t\tCommandLine=\""
- << this->EscapeForXML(command) << "\"\n"
+ << this->EscapeForXML(script.c_str()) << "\"\n"
<< "\t\t\t\t\tAdditionalDependencies=\"";
- if(depends.empty())
+ if(command.GetDepends().empty())
{
// There are no real dependencies. Produce an artificial one to
// make sure the rule runs reliably.
@@ -1272,8 +1259,10 @@ WriteCustomRule(std::ostream& fout,
else
{
// Write out the dependencies for the rule.
- for(std::vector<std::string>::const_iterator d = depends.begin();
- d != depends.end(); ++d)
+ for(std::vector<std::string>::const_iterator d =
+ command.GetDepends().begin();
+ d != command.GetDepends().end();
+ ++d)
{
// Get the real name of the dependency in case it is a CMake target.
std::string dep = this->GetRealDependency(d->c_str(), i->c_str());
@@ -1283,7 +1272,7 @@ WriteCustomRule(std::ostream& fout,
}
fout << "\"\n";
fout << "\t\t\t\t\tOutputs=\"";
- if(outputs.empty())
+ if(command.GetOutputs().empty())
{
fout << source << "_force";
}
@@ -1291,8 +1280,9 @@ WriteCustomRule(std::ostream& fout,
{
// Write a rule for the output generated by this command.
const char* sep = "";
- for(std::vector<std::string>::const_iterator o = outputs.begin();
- o != outputs.end(); ++o)
+ for(std::vector<std::string>::const_iterator o = command.GetOutputs().begin();
+ o != command.GetOutputs().end();
+ ++o)
{
fout << sep << this->ConvertToXMLOutputPathSingle(o->c_str());
sep = ";";
@@ -1323,6 +1313,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjEndGroup(std::ostream& fout)
// look for custom rules on a target and collect them together
void cmLocalVisualStudio7Generator
::OutputTargetRules(std::ostream& fout,
+ const char* configName,
cmTarget &target,
const char * /*libName*/)
{
@@ -1350,6 +1341,7 @@ void cmLocalVisualStudio7Generator
std::string script =
this->ConstructScript(cr->GetCommandLines(),
cr->GetWorkingDirectory(),
+ configName,
cr->GetEscapeOldStyle(),
cr->GetEscapeAllowMakeVars());
fout << this->EscapeForXML(script.c_str()).c_str();
@@ -1379,6 +1371,7 @@ void cmLocalVisualStudio7Generator
std::string script =
this->ConstructScript(cr->GetCommandLines(),
cr->GetWorkingDirectory(),
+ configName,
cr->GetEscapeOldStyle(),
cr->GetEscapeAllowMakeVars());
fout << this->EscapeForXML(script.c_str()).c_str();
@@ -1408,6 +1401,7 @@ void cmLocalVisualStudio7Generator
std::string script =
this->ConstructScript(cr->GetCommandLines(),
cr->GetWorkingDirectory(),
+ configName,
cr->GetEscapeOldStyle(),
cr->GetEscapeAllowMakeVars());
fout << this->EscapeForXML(script.c_str()).c_str();
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index b983799..1863ff9 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -89,8 +89,8 @@ private:
std::string EscapeForXML(const char* s);
std::string ConvertToXMLOutputPath(const char* path);
std::string ConvertToXMLOutputPathSingle(const char* path);
- void OutputTargetRules(std::ostream& fout, cmTarget &target,
- const char *libName);
+ void OutputTargetRules(std::ostream& fout, const char* configName,
+ cmTarget &target, const char *libName);
void OutputBuildTool(std::ostream& fout, const char* configName,
cmTarget& t);
void OutputLibraries(std::ostream& fout,
@@ -104,12 +104,10 @@ private:
const char* group,
const char* filter);
void WriteVCProjEndGroup(std::ostream& fout);
+
void WriteCustomRule(std::ostream& fout,
const char* source,
- const char* command,
- const char* comment,
- const std::vector<std::string>& depends,
- const std::vector<std::string>& outputs,
+ const cmCustomCommand& command,
const char* extraFlags);
void WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target);
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index 8ca677e..1d494c2 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -111,6 +111,7 @@ std::string
cmLocalVisualStudioGenerator
::ConstructScript(const cmCustomCommandLines& commandLines,
const char* workingDirectory,
+ const char* configName,
bool escapeOldStyle,
bool escapeAllowMakeVars,
const char* newline_text)
@@ -152,13 +153,15 @@ cmLocalVisualStudioGenerator
// Start with the command name.
const cmCustomCommandLine& commandLine = *cl;
+ std::string commandName = this->GetRealLocation(commandLine[0].c_str(),
+ configName);
if(!workingDirectory)
{
- script += this->Convert(commandLine[0].c_str(),START_OUTPUT,SHELL);
+ script += this->Convert(commandName.c_str(),START_OUTPUT,SHELL);
}
else
{
- script += this->Convert(commandLine[0].c_str(),NONE,SHELL);
+ script += this->Convert(commandName.c_str(),NONE,SHELL);
}
// Add the arguments.
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h
index 8259474..db03f8d 100644
--- a/Source/cmLocalVisualStudioGenerator.h
+++ b/Source/cmLocalVisualStudioGenerator.h
@@ -41,6 +41,7 @@ protected:
/** Construct a script from the given list of command lines. */
std::string ConstructScript(const cmCustomCommandLines& commandLines,
const char* workingDirectory,
+ const char* configName,
bool escapeOldStyle,
bool escapeAllowMakeVars,
const char* newline = "\n");
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index c1a65d7..4cc265f 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -578,18 +578,6 @@ cmMakefile::AddCustomCommandToTarget(const char* target,
ti->second.GetPostBuildCommands().push_back(cc);
break;
}
-
- // Add dependencies on commands CMake knows how to build.
- for(cmCustomCommandLines::const_iterator cli = commandLines.begin();
- cli != commandLines.end(); ++cli)
- {
- std::string cacheCommand = *cli->begin();
- if(const char* knownTarget =
- this->GetCacheManager()->GetCacheValue(cacheCommand.c_str()))
- {
- ti->second.AddUtility(knownTarget);
- }
- }
}
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 85f3d6e..9f99266 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -408,6 +408,31 @@ void cmTarget::SetMakefile(cmMakefile* mf)
}
}
+
+void
+cmTarget::checkForTargetsAsCommand(const std::vector<cmCustomCommand>& commands)
+{
+ for ( std::vector<cmCustomCommand>::const_iterator cli = commands.begin();
+ cli != commands.end();
+ ++cli )
+ {
+ for ( cmCustomCommandLines::const_iterator cit=cli->GetCommandLines().begin();
+ cit!=cli->GetCommandLines().end();
+ ++cit )
+ {
+ std::string command = *cit->begin();
+ // see if we can find a target with this name
+ cmTarget* t = this->Makefile->GetLocalGenerator()->
+ GetGlobalGenerator()->FindTarget ( 0, command.c_str() );
+ if ( ( t ) && ( t->GetType() ==cmTarget::EXECUTABLE ) )
+ {
+ this->AddUtility ( command.c_str() );
+ }
+ }
+ }
+}
+
+
void cmTarget::TraceVSDependencies(std::string projFile,
cmMakefile *makefile)
{
@@ -504,6 +529,11 @@ void cmTarget::TraceVSDependencies(std::string projFile,
}
}
}
+
+ checkForTargetsAsCommand(this->GetPreBuildCommands());
+ checkForTargetsAsCommand(this->GetPreLinkCommands());
+ checkForTargetsAsCommand(this->GetPostBuildCommands());
+
while (!srcFilesToProcess.empty())
{
// is this source the output of a custom command
@@ -533,9 +563,28 @@ void cmTarget::TraceVSDependencies(std::string projFile,
srcFilesQueued.insert(temp);
}
}
+
+ // check if commands for this custom commands are names of targets and
+ // if that's the case add these targets as dependencies
+ std::vector<std::string> automaticTargetDepends;
+ for(cmCustomCommandLines::const_iterator it=
+ outsf->GetCustomCommand()->GetCommandLines().begin();
+ it!=outsf->GetCustomCommand()->GetCommandLines().end();
+ ++it)
+ {
+ const std::string& currentCommand = (*it)[0];
+ // see if we can find a target with this name
+ cmTarget* t = this->Makefile->GetLocalGenerator()->
+ GetGlobalGenerator()->FindTarget(0, currentCommand.c_str());
+ if (( t) && (t->GetType()==cmTarget::EXECUTABLE))
+ {
+ automaticTargetDepends.push_back(currentCommand);
+ }
+ }
+ outsf->GetCustomCommand()->AppendDepends(automaticTargetDepends);
+
// add its dependencies to the list to check
- unsigned int i;
- for (i = 0; i < outsf->GetCustomCommand()->GetDepends().size(); ++i)
+ for (unsigned int i = 0; i < outsf->GetCustomCommand()->GetDepends().size(); ++i)
{
const std::string& fullName
= outsf->GetCustomCommand()->GetDepends()[i];
@@ -590,6 +639,7 @@ void cmTarget::TraceVSDependencies(std::string projFile,
}
}
}
+
}
// finished with this SF move to the next
srcFilesToProcess.pop();
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 5cda102..215d879 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -55,7 +55,7 @@ public:
void SetType(TargetType f, const char* name);
///! Set/Get the name of the target
- const char* GetName() {return this->Name.c_str();}
+ const char* GetName() const {return this->Name.c_str();}
///! Set the cmMakefile that owns this target
void SetMakefile(cmMakefile *mf);
@@ -180,7 +180,7 @@ public:
/**
* Trace through the source files in this target and add al source files
- * that they depend on, used by the visual studio generators
+ * that they depend on, used by all generators
*/
void TraceVSDependencies(std::string projName, cmMakefile *mf);
@@ -291,6 +291,13 @@ private:
const LibraryID& lib,
const LibraryID& dep);
+ /*
+ * Checks the prebuild, prelink and postbuild custom commands for known
+ * targets and adds them to the dependencies.
+ */
+ void checkForTargetsAsCommand(const std::vector<cmCustomCommand>& commands);
+
+
/**
* Emits the library \a lib and all its dependencies into link_line.
* \a emitted keeps track of the libraries that have been emitted to