diff options
author | Brad King <brad.king@kitware.com> | 2007-12-28 19:59:06 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2007-12-28 19:59:06 (GMT) |
commit | 59aa144516c36ff4b25028c9617383f57e780900 (patch) | |
tree | ff1028291bfbc1e32a4089b92eebd76c588581eb | |
parent | 0a7bb4112954068b25adc116f9cf6c0baeb6cf3e (diff) | |
download | CMake-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.cxx | 102 | ||||
-rw-r--r-- | Source/cmMakefileLibraryTargetGenerator.cxx | 138 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 32 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.h | 6 |
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); |