[cmake-commits] king committed cmDocumentVariables.cxx 1.12 1.13
cmMakefileLibraryTargetGenerator.cxx 1.51 1.52
cmMakefileTargetGenerator.cxx 1.87 1.88
cmMakefileTargetGenerator.h 1.19 1.20
cmake-commits at cmake.org
cmake-commits at cmake.org
Tue Jan 29 20:46:27 EST 2008
Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv7659/Source
Modified Files:
cmDocumentVariables.cxx cmMakefileLibraryTargetGenerator.cxx
cmMakefileTargetGenerator.cxx cmMakefileTargetGenerator.h
Log Message:
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.
Index: cmMakefileLibraryTargetGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefileLibraryTargetGenerator.cxx,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- cmMakefileLibraryTargetGenerator.cxx 28 Jan 2008 18:05:58 -0000 1.51
+++ cmMakefileLibraryTargetGenerator.cxx 30 Jan 2008 01:46:25 -0000 1.52
@@ -668,12 +668,45 @@
// 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 @@
std::string buildObjs;
if(useLinkScript)
{
- this->WriteObjectsString(buildObjs);
+ if(!useArchiveRules)
+ {
+ this->WriteObjectsString(buildObjs);
+ }
}
else
{
@@ -768,12 +804,64 @@
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)
{
- this->LocalGenerator->ExpandRuleVariables(*i, vars);
+ // 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();
+ {
+ 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 = "";
}
Index: cmDocumentVariables.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmDocumentVariables.cxx,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- cmDocumentVariables.cxx 23 Jan 2008 20:22:38 -0000 1.12
+++ cmDocumentVariables.cxx 30 Jan 2008 01:46:25 -0000 1.13
@@ -944,7 +944,34 @@
"This is a rule variable that tells CMake how "
"to create a static library for the language <LANG>.",false,
"Variables for Languages");
-
+
+ cm->DefineProperty
+ ("CMAKE_<LANG>_ARCHIVE_CREATE", cmProperty::VARIABLE,
+ "Rule variable to create a new static archive.",
+ "This is a rule variable that tells CMake how to create a static "
+ "archive. It is used in place of CMAKE_<LANG>_CREATE_STATIC_LIBRARY "
+ "on some platforms in order to support large object counts. "
+ "See also CMAKE_<LANG>_ARCHIVE_APPEND and CMAKE_<LANG>_ARCHIVE_FINISH.",
+ false, "Variables for Languages");
+
+ cm->DefineProperty
+ ("CMAKE_<LANG>_ARCHIVE_APPEND", cmProperty::VARIABLE,
+ "Rule variable to append to a static archive.",
+ "This is a rule variable that tells CMake how to append to a static "
+ "archive. It is used in place of CMAKE_<LANG>_CREATE_STATIC_LIBRARY "
+ "on some platforms in order to support large object counts. "
+ "See also CMAKE_<LANG>_ARCHIVE_CREATE and CMAKE_<LANG>_ARCHIVE_FINISH.",
+ false, "Variables for Languages");
+
+ cm->DefineProperty
+ ("CMAKE_<LANG>_ARCHIVE_FINISH", cmProperty::VARIABLE,
+ "Rule variable to finish an existing static archive.",
+ "This is a rule variable that tells CMake how to finish a static "
+ "archive. It is used in place of CMAKE_<LANG>_CREATE_STATIC_LIBRARY "
+ "on some platforms in order to support large object counts. "
+ "See also CMAKE_<LANG>_ARCHIVE_CREATE and CMAKE_<LANG>_ARCHIVE_APPEND.",
+ false, "Variables for Languages");
+
cm->DefineProperty
("CMAKE_<LANG>_IGNORE_EXTENSIONS", cmProperty::VARIABLE,
"File extensions that should be ignored by the build.",
Index: cmMakefileTargetGenerator.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefileTargetGenerator.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- cmMakefileTargetGenerator.h 30 Dec 2007 21:11:38 -0000 1.19
+++ cmMakefileTargetGenerator.h 30 Jan 2008 01:46:25 -0000 1.20
@@ -107,6 +107,8 @@
void WriteObjectsVariable(std::string& variableName,
std::string& variableNameExternal);
void WriteObjectsString(std::string& buildObjs);
+ void WriteObjectsStrings(std::vector<std::string>& objStrings,
+ std::string::size_type limit = std::string::npos);
// write the driver rule to build target outputs
void WriteTargetDriverRule(const char* main_output, bool relink);
Index: cmMakefileTargetGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefileTargetGenerator.cxx,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -d -r1.87 -r1.88
--- cmMakefileTargetGenerator.cxx 28 Jan 2008 13:38:36 -0000 1.87
+++ cmMakefileTargetGenerator.cxx 30 Jan 2008 01:46:25 -0000 1.88
@@ -1200,49 +1200,96 @@
cmMakefileTargetGenerator
::WriteObjectsString(std::string& buildObjs)
{
- std::string object;
- const char* no_quoted =
- this->Makefile->GetDefinition("CMAKE_NO_QUOTED_OBJECTS");
- const char* space = "";
- for(std::vector<std::string>::const_iterator i = this->Objects.begin();
- i != this->Objects.end(); ++i)
+ std::vector<std::string> objStrings;
+ this->WriteObjectsStrings(objStrings);
+ buildObjs = objStrings[0];
+}
+
+//----------------------------------------------------------------------------
+class cmMakefileTargetGeneratorObjectStrings
+{
+public:
+ cmMakefileTargetGeneratorObjectStrings(std::vector<std::string>& strings,
+ cmMakefile* mf,
+ cmLocalUnixMakefileGenerator3* lg,
+ std::string::size_type limit):
+ Strings(strings), Makefile(mf), LocalGenerator(lg), LengthLimit(limit)
{
- if ( this->ExtraContent.find(i->c_str()) != this->ExtraContent.end() )
+ this->NoQuotes = mf->IsOn("CMAKE_NO_QUOTED_OBJECTS");
+ this->Space = "";
+ }
+ void Feed(std::string const& obj)
+ {
+ // Construct the name of the next object.
+ if(this->NoQuotes)
{
- continue;
+ this->NextObject =
+ this->LocalGenerator->Convert(obj.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
}
- buildObjs += space;
- space = " ";
- if(no_quoted)
+ else
{
- buildObjs +=
- this->Convert(i->c_str(), cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::SHELL);
+ this->NextObject =
+ this->LocalGenerator->ConvertToQuotedOutputPath(obj.c_str());
}
- else
+
+ // Roll over to next string if the limit will be exceeded.
+ if(this->LengthLimit != std::string::npos &&
+ (this->CurrentString.length() + 1 + this->NextObject.length()
+ > this->LengthLimit))
{
- buildObjs +=
- this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str());
+ this->Strings.push_back(this->CurrentString);
+ this->CurrentString = "";
+ this->Space = "";
}
+
+ // Separate from previous object.
+ this->CurrentString += this->Space;
+ this->Space = " ";
+
+ // Append this object.
+ this->CurrentString += this->NextObject;
+ }
+ void Done()
+ {
+ this->Strings.push_back(this->CurrentString);
+ }
+private:
+ std::vector<std::string>& Strings;
+ cmMakefile* Makefile;
+ cmLocalUnixMakefileGenerator3* LocalGenerator;
+ std::string::size_type LengthLimit;
+ bool NoQuotes;
+ std::string CurrentString;
+ std::string NextObject;
+ const char* Space;
+};
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
+::WriteObjectsStrings(std::vector<std::string>& objStrings,
+ std::string::size_type limit)
+{
+ cmMakefileTargetGeneratorObjectStrings
+ helper(objStrings, this->Makefile, this->LocalGenerator, limit);
+ for(std::vector<std::string>::const_iterator i = this->Objects.begin();
+ i != this->Objects.end(); ++i)
+ {
+ if ( this->ExtraContent.find(i->c_str()) != this->ExtraContent.end() )
+ {
+ continue;
+ }
+ helper.Feed(*i);
}
for(std::vector<std::string>::const_iterator i =
this->ExternalObjects.begin();
i != this->ExternalObjects.end(); ++i)
{
- buildObjs += space;
- space = " ";
- if(no_quoted)
- {
- buildObjs +=
- this->Convert(i->c_str(), cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::SHELL);
- }
- else
- {
- buildObjs +=
- this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str());
- }
+ helper.Feed(*i);
}
+ helper.Done();
}
//----------------------------------------------------------------------------
More information about the Cmake-commits
mailing list