diff options
author | Brad King <brad.king@kitware.com> | 2008-01-30 01:46:25 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2008-01-30 01:46:25 (GMT) |
commit | 66e0b4212fbbaaf3c5aa5af6a51aa3a5af002edf (patch) | |
tree | 6a18f76856cfe10f1e7be02d2b1cf41896a34cd6 /Source/cmMakefileLibraryTargetGenerator.cxx | |
parent | 44cf465ff5f768c96e8708eba35f31f296e78b1e (diff) | |
download | CMake-66e0b4212fbbaaf3c5aa5af6a51aa3a5af002edf.zip CMake-66e0b4212fbbaaf3c5aa5af6a51aa3a5af002edf.tar.gz CMake-66e0b4212fbbaaf3c5aa5af6a51aa3a5af002edf.tar.bz2 |
ENH: Added build rule variables CMAKE_<LANG>_ARCHIVE_CREATE, CMAKE_<LANG>_ARCHIVE_APPEND, and CMAKE_<LANG>_ARCHIVE_FINISH to support creation of static archive libraries out of a large number of objects. See bug #6284.
Diffstat (limited to 'Source/cmMakefileLibraryTargetGenerator.cxx')
-rw-r--r-- | Source/cmMakefileLibraryTargetGenerator.cxx | 106 |
1 files changed, 97 insertions, 9 deletions
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 9ab4649..a81cfd6 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -668,12 +668,45 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules // 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); - cmSystemTools::ExpandListArgument(linkRule, real_link_commands); + // For static libraries there might be archiving rules. + std::vector<std::string> archiveCreateCommands; + std::vector<std::string> archiveAppendCommands; + std::vector<std::string> archiveFinishCommands; + std::string::size_type archiveCommandLimit = std::string::npos; + if(useLinkScript && this->Target->GetType() == cmTarget::STATIC_LIBRARY) + { + std::string arCreateVar = "CMAKE_"; + arCreateVar += linkLanguage; + arCreateVar += "_ARCHIVE_CREATE"; + if(const char* rule = this->Makefile->GetDefinition(arCreateVar.c_str())) + { + cmSystemTools::ExpandListArgument(rule, archiveCreateCommands); + } + std::string arAppendVar = "CMAKE_"; + arAppendVar += linkLanguage; + arAppendVar += "_ARCHIVE_APPEND"; + if(const char* rule = this->Makefile->GetDefinition(arAppendVar.c_str())) + { + cmSystemTools::ExpandListArgument(rule, archiveAppendCommands); + } + std::string arFinishVar = "CMAKE_"; + arFinishVar += linkLanguage; + arFinishVar += "_ARCHIVE_FINISH"; + if(const char* rule = this->Makefile->GetDefinition(arFinishVar.c_str())) + { + cmSystemTools::ExpandListArgument(rule, archiveFinishCommands); + } + + // Limit the length of individual object lists to less than the + // 32K command line length limit on Windows. We could make this a + // platform file variable but this should work everywhere. + archiveCommandLimit = 30000; + } + bool useArchiveRules = + !archiveCreateCommands.empty() && !archiveAppendCommands.empty(); // Expand the rule variables. + std::vector<std::string> real_link_commands; { // Collect up flags to link in needed libraries. cmOStringStream linklibs; @@ -687,7 +720,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules std::string buildObjs; if(useLinkScript) { - this->WriteObjectsString(buildObjs); + if(!useArchiveRules) + { + this->WriteObjectsString(buildObjs); + } } else { @@ -768,12 +804,64 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules linkLanguage, langFlags); } vars.LanguageCompileFlags = langFlags.c_str(); - // Expand placeholders in the commands. + + // Construct the main link rule and expand placeholders. this->LocalGenerator->TargetImplib = targetOutPathImport; - for(std::vector<std::string>::iterator i = real_link_commands.begin(); - i != real_link_commands.end(); ++i) + if(useArchiveRules) + { + // Construct the individual object list strings. + std::vector<std::string> object_strings; + this->WriteObjectsStrings(object_strings, archiveCommandLimit); + + // Create the archive with the first set of objects. + std::vector<std::string>::iterator osi = object_strings.begin(); { - this->LocalGenerator->ExpandRuleVariables(*i, vars); + vars.Objects = osi->c_str(); + for(std::vector<std::string>::const_iterator + i = archiveCreateCommands.begin(); + i != archiveCreateCommands.end(); ++i) + { + std::string cmd = *i; + this->LocalGenerator->ExpandRuleVariables(cmd, vars); + real_link_commands.push_back(cmd); + } + } + // Append to the archive with the other object sets. + for(++osi; osi != object_strings.end(); ++osi) + { + vars.Objects = osi->c_str(); + for(std::vector<std::string>::const_iterator + i = archiveAppendCommands.begin(); + i != archiveAppendCommands.end(); ++i) + { + std::string cmd = *i; + this->LocalGenerator->ExpandRuleVariables(cmd, vars); + real_link_commands.push_back(cmd); + } + } + // Finish the archive. + vars.Objects = ""; + for(std::vector<std::string>::const_iterator + i = archiveFinishCommands.begin(); + i != archiveFinishCommands.end(); ++i) + { + std::string cmd = *i; + this->LocalGenerator->ExpandRuleVariables(cmd, vars); + real_link_commands.push_back(cmd); + } + } + else + { + // Get the set of commands. + std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar); + cmSystemTools::ExpandListArgument(linkRule, real_link_commands); + + // Expand placeholders. + 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 = ""; } |