summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2007-12-28 19:59:06 (GMT)
committerBrad King <brad.king@kitware.com>2007-12-28 19:59:06 (GMT)
commit59aa144516c36ff4b25028c9617383f57e780900 (patch)
treeff1028291bfbc1e32a4089b92eebd76c588581eb
parent0a7bb4112954068b25adc116f9cf6c0baeb6cf3e (diff)
downloadCMake-59aa144516c36ff4b25028c9617383f57e780900.zip
CMake-59aa144516c36ff4b25028c9617383f57e780900.tar.gz
CMake-59aa144516c36ff4b25028c9617383f57e780900.tar.bz2
ENH: Simplified and moved link script implementation up from cmMakefileLibraryTargetGenerator to cmMakefileTargetGenerator and use for cmMakefileExecutableTargetGenerator too. This addresses bug #6192.
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx102
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx138
-rw-r--r--Source/cmMakefileTargetGenerator.cxx32
-rw-r--r--Source/cmMakefileTargetGenerator.h6
4 files changed, 151 insertions, 127 deletions
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 3c605c4..85d8565 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -339,14 +339,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
->AppendCustomCommands(commands, this->Target->GetPreLinkCommands());
}
+ // Determine whether a link script will be used.
+ bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
+
// Construct the main link rule.
+ std::vector<std::string> real_link_commands;
std::string linkRuleVar = "CMAKE_";
linkRuleVar += linkLanguage;
linkRuleVar += "_LINK_EXECUTABLE";
std::string linkRule =
this->Makefile->GetRequiredDefinition(linkRuleVar.c_str());
std::vector<std::string> commands1;
- cmSystemTools::ExpandListArgument(linkRule, commands1);
+ cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
if(this->Target->GetPropertyAsBool("ENABLE_EXPORTS"))
{
// If a separate rule for creating an import library is specified
@@ -357,37 +361,12 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
if(const char* rule =
this->Makefile->GetDefinition(implibRuleVar.c_str()))
{
- cmSystemTools::ExpandListArgument(rule, commands1);
+ cmSystemTools::ExpandListArgument(rule, real_link_commands);
}
}
- this->LocalGenerator->CreateCDCommand
- (commands1,
- this->Makefile->GetStartOutputDirectory(),
- this->Makefile->GetHomeOutputDirectory());
- commands.insert(commands.end(), commands1.begin(), commands1.end());
-
- // Add a rule to create necessary symlinks for the library.
- if(targetOutPath != targetOutPathReal)
- {
- std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_executable ";
- symlink += targetOutPathReal;
- symlink += " ";
- symlink += targetOutPath;
- commands1.clear();
- commands1.push_back(symlink);
- this->LocalGenerator->CreateCDCommand(commands1,
- this->Makefile->GetStartOutputDirectory(),
- this->Makefile->GetHomeOutputDirectory());
- commands.insert(commands.end(), commands1.begin(), commands1.end());
- }
-
- // Add the post-build rules when building but not when relinking.
- if(!relink)
- {
- this->LocalGenerator->
- AppendCustomCommands(commands, this->Target->GetPostBuildCommands());
- }
+ // Expand the rule variables.
+ {
// Collect up flags to link in needed libraries.
cmOStringStream linklibs;
this->LocalGenerator->OutputLinkLibraries(linklibs, *this->Target, relink);
@@ -397,11 +376,19 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string variableName;
std::string variableNameExternal;
this->WriteObjectsVariable(variableName, variableNameExternal);
- std::string buildObjs = "$(";
- buildObjs += variableName;
- buildObjs += ") $(";
- buildObjs += variableNameExternal;
- buildObjs += ")";
+ std::string buildObjs;
+ if(useLinkScript)
+ {
+ this->WriteObjectsString(buildObjs);
+ }
+ else
+ {
+ buildObjs = "$(";
+ buildObjs += variableName;
+ buildObjs += ") $(";
+ buildObjs += variableNameExternal;
+ buildObjs += ")";
+ }
std::string cleanObjs = "$(";
cleanObjs += variableName;
cleanObjs += ")";
@@ -435,12 +422,55 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.LinkFlags = linkFlags.c_str();
// Expand placeholders in the commands.
this->LocalGenerator->TargetImplib = targetOutPathImport;
- for(std::vector<std::string>::iterator i = commands.begin();
- i != commands.end(); ++i)
+ for(std::vector<std::string>::iterator i = real_link_commands.begin();
+ i != real_link_commands.end(); ++i)
{
this->LocalGenerator->ExpandRuleVariables(*i, vars);
}
this->LocalGenerator->TargetImplib = "";
+ }
+
+ // Optionally convert the build rule to use a script to avoid long
+ // command lines in the make shell.
+ if(useLinkScript)
+ {
+ // Use a link script.
+ const char* name = (relink? "relink.txt" : "link.txt");
+ this->CreateLinkScript(name, real_link_commands, commands1);
+ }
+ else
+ {
+ // No link script. Just use the link rule directly.
+ commands1 = real_link_commands;
+ }
+ this->LocalGenerator->CreateCDCommand
+ (commands1,
+ this->Makefile->GetStartOutputDirectory(),
+ this->Makefile->GetHomeOutputDirectory());
+ commands.insert(commands.end(), commands1.begin(), commands1.end());
+ commands1.clear();
+
+ // Add a rule to create necessary symlinks for the library.
+ if(targetOutPath != targetOutPathReal)
+ {
+ std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_executable ";
+ symlink += targetOutPathReal;
+ symlink += " ";
+ symlink += targetOutPath;
+ commands1.push_back(symlink);
+ this->LocalGenerator->CreateCDCommand(commands1,
+ this->Makefile->GetStartOutputDirectory(),
+ this->Makefile->GetHomeOutputDirectory());
+ commands.insert(commands.end(), commands1.begin(), commands1.end());
+ commands1.clear();
+ }
+
+ // Add the post-build rules when building but not when relinking.
+ if(!relink)
+ {
+ this->LocalGenerator->
+ AppendCustomCommands(commands, this->Target->GetPostBuildCommands());
+ }
// Write the build rule.
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream,
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 3ac6d8e..40bbdf2 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -668,77 +668,16 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
->AppendCustomCommands(commands, this->Target->GetPreLinkCommands());
}
- // Open the link script if it will be used.
- bool useLinkScript = false;
- std::string linkScriptName;
- std::auto_ptr<cmGeneratedFileStream> linkScriptStream;
- if(this->GlobalGenerator->GetUseLinkScript() &&
- (this->Target->GetType() == cmTarget::STATIC_LIBRARY ||
- this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
- this->Target->GetType() == cmTarget::MODULE_LIBRARY))
- {
- useLinkScript = true;
- linkScriptName = this->TargetBuildDirectoryFull;
- if(relink)
- {
- linkScriptName += "/relink.txt";
- }
- else
- {
- linkScriptName += "/link.txt";
- }
- std::auto_ptr<cmGeneratedFileStream> lss(
- new cmGeneratedFileStream(linkScriptName.c_str()));
- linkScriptStream = lss;
- }
-
- std::vector<std::string> link_script_commands;
+ // Determine whether a link script will be used.
+ bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
// Construct the main link rule.
+ std::vector<std::string> real_link_commands;
std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
- if(useLinkScript)
- {
- cmSystemTools::ExpandListArgument(linkRule, link_script_commands);
- std::string link_command = "$(CMAKE_COMMAND) -E cmake_link_script ";
- link_command += this->Convert(linkScriptName.c_str(),
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::SHELL);
- link_command += " --verbose=$(VERBOSE)";
- commands1.push_back(link_command);
- }
- else
- {
- cmSystemTools::ExpandListArgument(linkRule, commands1);
- }
- this->LocalGenerator->CreateCDCommand
- (commands1,
- this->Makefile->GetStartOutputDirectory(),
- this->Makefile->GetHomeOutputDirectory());
- commands.insert(commands.end(), commands1.begin(), commands1.end());
-
- // Add a rule to create necessary symlinks for the library.
- if(targetOutPath != targetOutPathReal)
- {
- std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_library ";
- symlink += targetOutPathReal;
- symlink += " ";
- symlink += targetOutPathSO;
- symlink += " ";
- symlink += targetOutPath;
- commands1.clear();
- commands1.push_back(symlink);
- this->LocalGenerator->CreateCDCommand(commands1,
- this->Makefile->GetStartOutputDirectory(),
- this->Makefile->GetHomeOutputDirectory());
- commands.insert(commands.end(), commands1.begin(), commands1.end());
- }
- // Add the post-build rules when building but not when relinking.
- if(!relink)
- {
- this->LocalGenerator->
- AppendCustomCommands(commands, this->Target->GetPostBuildCommands());
- }
+ cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
+ // Expand the rule variables.
+ {
// Collect up flags to link in needed libraries.
cmOStringStream linklibs;
this->LocalGenerator->OutputLinkLibraries(linklibs, *this->Target, relink);
@@ -834,38 +773,55 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
vars.LanguageCompileFlags = langFlags.c_str();
// Expand placeholders in the commands.
this->LocalGenerator->TargetImplib = targetOutPathImport;
- if(useLinkScript)
+ for(std::vector<std::string>::iterator i = real_link_commands.begin();
+ i != real_link_commands.end(); ++i)
{
- for(std::vector<std::string>::iterator i = link_script_commands.begin();
- i != link_script_commands.end(); ++i)
- {
- this->LocalGenerator->ExpandRuleVariables(*i, vars);
- }
- }
- else
- {
- for(std::vector<std::string>::iterator i = commands.begin();
- i != commands.end(); ++i)
- {
- this->LocalGenerator->ExpandRuleVariables(*i, vars);
- }
+ this->LocalGenerator->ExpandRuleVariables(*i, vars);
}
this->LocalGenerator->TargetImplib = "";
+ }
// Optionally convert the build rule to use a script to avoid long
// command lines in the make shell.
if(useLinkScript)
{
- for(std::vector<std::string>::iterator cmd = link_script_commands.begin();
- cmd != link_script_commands.end(); ++cmd)
- {
- // Do not write out empty commands or commands beginning in the
- // shell no-op ":".
- if(!cmd->empty() && (*cmd)[0] != ':')
- {
- (*linkScriptStream) << *cmd << "\n";
- }
- }
+ // Use a link script.
+ const char* name = (relink? "relink.txt" : "link.txt");
+ this->CreateLinkScript(name, real_link_commands, commands1);
+ }
+ else
+ {
+ // No link script. Just use the link rule directly.
+ commands1 = real_link_commands;
+ }
+ this->LocalGenerator->CreateCDCommand
+ (commands1,
+ this->Makefile->GetStartOutputDirectory(),
+ this->Makefile->GetHomeOutputDirectory());
+ commands.insert(commands.end(), commands1.begin(), commands1.end());
+ commands1.clear();
+
+ // Add a rule to create necessary symlinks for the library.
+ if(targetOutPath != targetOutPathReal)
+ {
+ std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_library ";
+ symlink += targetOutPathReal;
+ symlink += " ";
+ symlink += targetOutPathSO;
+ symlink += " ";
+ symlink += targetOutPath;
+ commands1.push_back(symlink);
+ this->LocalGenerator->CreateCDCommand(commands1,
+ this->Makefile->GetStartOutputDirectory(),
+ this->Makefile->GetHomeOutputDirectory());
+ commands.insert(commands.end(), commands1.begin(), commands1.end());
+ commands1.clear();
+ }
+ // Add the post-build rules when building but not when relinking.
+ if(!relink)
+ {
+ this->LocalGenerator->
+ AppendCustomCommands(commands, this->Target->GetPostBuildCommands());
}
// Write the build rule.
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index e780219..13c1b64 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1391,3 +1391,35 @@ cmMakefileTargetGenerator
MultipleOutputPairsType::value_type p(depender, dependee);
this->MultipleOutputPairs.insert(p);
}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
+::CreateLinkScript(const char* name,
+ std::vector<std::string> const& link_commands,
+ std::vector<std::string>& makefile_commands)
+{
+ // Create the link script file.
+ std::string linkScriptName = this->TargetBuildDirectoryFull;
+ linkScriptName += "/";
+ linkScriptName += name;
+ cmGeneratedFileStream linkScriptStream(linkScriptName.c_str());
+ for(std::vector<std::string>::const_iterator cmd = link_commands.begin();
+ cmd != link_commands.end(); ++cmd)
+ {
+ // Do not write out empty commands or commands beginning in the
+ // shell no-op ":".
+ if(!cmd->empty() && (*cmd)[0] != ':')
+ {
+ linkScriptStream << *cmd << "\n";
+ }
+ }
+
+ // Create the makefile command to invoke the link script.
+ std::string link_command = "$(CMAKE_COMMAND) -E cmake_link_script ";
+ link_command += this->Convert(linkScriptName.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ link_command += " --verbose=$(VERBOSE)";
+ makefile_commands.push_back(link_command);
+}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 4b8a281..aa452c9 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -128,6 +128,12 @@ protected:
makefile generators to register such pairs. */
void AddMultipleOutputPair(const char* depender, const char* dependee);
+ /** Create a script to hold link rules and a command to invoke the
+ script at build time. */
+ void CreateLinkScript(const char* name,
+ std::vector<std::string> const& link_commands,
+ std::vector<std::string>& makefile_commands);
+
virtual void CloseFileStreams();
void RemoveForbiddenFlags(const char* flagVar, const char* linkLang,
std::string& linkFlags);