浏览代码

ENH: performance improvements

Bill Hoffman 20 年之前
父节点
当前提交
1004073942

+ 164 - 77
Source/cmLocalGenerator.cxx

@@ -592,11 +592,6 @@ void cmLocalGenerator::CreateCustomTargetsAndCommands(std::set<cmStdString> cons
 }
 
 
-struct RuleVariables
-{
-  const char* variable;
-};
-
 
 // List of variables that are replaced when
 // rules are expanced.  These variables are
@@ -605,6 +600,7 @@ struct RuleVariables
 // languages.
 static const char* ruleReplaceVars[] =
 {
+  "CMAKE_${LANG}_COMPILER",
   "CMAKE_SHARED_LIBRARY_CREATE_${LANG}_FLAGS",
   "CMAKE_SHARED_MODULE_CREATE_${LANG}_FLAGS",
   "CMAKE_SHARED_MODULE_${LANG}_FLAGS", 
@@ -612,7 +608,6 @@ static const char* ruleReplaceVars[] =
   "CMAKE_${LANG}_LINK_FLAGS",
   "CMAKE_SHARED_LIBRARY_SONAME_${LANG}_FLAG",
   "CMAKE_${LANG}_ARCHIVE",
-  "CMAKE_${LANG}_COMPILER",
   "CMAKE_AR",
   "CMAKE_CURRENT_SOURCE_DIR",
   "CMAKE_CURRENT_BINARY_DIR",
@@ -620,103 +615,135 @@ static const char* ruleReplaceVars[] =
   0
 };
 
-
-
- 
-void 
-cmLocalGenerator::ExpandRuleVariables(std::string& s,
-                                      const char* lang,
-                                      const char* objects,
-                                      const char* target,
-                                      const char* linkLibs,
-                                      const char* source,
-                                      const char* object,
-                                      const char* flags,
-                                      const char* objectsquoted,
-                                      const char* targetBase,
-                                      const char* targetSOName,
-                                      const char* linkFlags)
+std::string
+cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
+                                     const char* lang,
+                                     const char* objects,
+                                     const char* target,
+                                     const char* linkLibs,
+                                     const char* source,
+                                     const char* object,
+                                     const char* flags,
+                                     const char* objectsquoted,
+                                     const char* targetBase,
+                                     const char* targetSOName,
+                                     const char* linkFlags)
 {
-  std::vector<std::string> enabledLanguages;
-  m_GlobalGenerator->GetEnabledLanguages(enabledLanguages);
-
   if(linkFlags)
     {
-    cmSystemTools::ReplaceString(s, "<LINK_FLAGS>", linkFlags);
+    if(variable == "LINK_FLAGS")
+      {
+      return linkFlags;
+      }
     }
   if(flags)
     {
-    cmSystemTools::ReplaceString(s, "<FLAGS>", flags);
+    if(variable == "FLAGS")
+      {
+      return flags;
+      }
     }
     
   if(source)
     {
-    cmSystemTools::ReplaceString(s, "<SOURCE>", source);
+    if(variable == "SOURCE")
+      {
+      return source;
+      }
     }
   if(object)
     {
-    cmSystemTools::ReplaceString(s, "<OBJECT>", object);
+    if(variable == "OBJECT")
+      {
+      return object;
+      }
     }
   if(objects)
     {
-    cmSystemTools::ReplaceString(s, "<OBJECTS>", objects);
+    if(variable == "OBJECTS")
+      {
+      return objects;
+      }
     }
   if(objectsquoted)
     {
-    cmSystemTools::ReplaceString(s, "<OBJECTS_QUOTED>", objectsquoted);
+    if(variable == "OBJECTS_QUOTED")
+      {
+      return objectsquoted;
+      }
     }
   if(target)
     { 
-    std::string targetQuoted = target;
-    if(targetQuoted.size() && targetQuoted[0] != '\"')
+    if(variable == "TARGET_QUOTED")
+      {
+      std::string targetQuoted = target;
+      if(targetQuoted.size() && targetQuoted[0] != '\"')
+        {
+        targetQuoted = '\"';
+        targetQuoted += target;
+        targetQuoted += '\"';
+        return targetQuoted;
+        }
+      }
+    if(variable == "TARGET")
       {
-      targetQuoted = '\"';
-      targetQuoted += target;
-      targetQuoted += '\"';
+      return target;
       }
-    cmSystemTools::ReplaceString(s, "<TARGET_QUOTED>", targetQuoted.c_str());
-    cmSystemTools::ReplaceString(s, "<TARGET>", target);
     }
   if(targetBase)
     {
-    // special case for quoted paths with spaces 
-    // if you see <TARGET_BASE>.lib then put the .lib inside
-    // the quotes, same for .dll
-    if((strlen(targetBase) > 1) && targetBase[0] == '\"')
+    if(variable == "TARGET_BASE.lib" || variable == "TARGET_BASE.dll")
+      {
+      // special case for quoted paths with spaces 
+      // if you see <TARGET_BASE>.lib then put the .lib inside
+      // the quotes, same for .dll
+      if((strlen(targetBase) > 1) && targetBase[0] == '\"')
+        {
+        std::string base = targetBase;
+        base[base.size()-1] = '.';
+        std::string baseLib = base + "lib\"";
+        std::string baseDll = base + "dll\"";
+        if(variable == "TARGET_BASE.lib" )
+          {
+          return baseLib;
+          }
+        if(variable == "TARGET_BASE.dll" )
+          {
+          return baseDll;
+          }
+        }
+      }
+    if(variable == "TARGET_BASE")
       {
-      std::string base = targetBase;
-      base[base.size()-1] = '.';
-      std::string baseLib = base + "lib\"";
-      std::string baseDll = base + "dll\"";
-      cmSystemTools::ReplaceString(s, "<TARGET_BASE>.lib", baseLib.c_str());
-      cmSystemTools::ReplaceString(s, "<TARGET_BASE>.dll", baseDll.c_str());
+      return targetBase;
       }
-    cmSystemTools::ReplaceString(s, "<TARGET_BASE>", targetBase);
     }
   if(targetSOName)
     {
-    bool replaced = false;
-    if(lang)
+    if(variable == "TARGET_SONAME")
       {
-      std::string name = "CMAKE_SHARED_LIBRARY_SONAME_";
-      name += lang;
-      name += "_FLAG";
-      if(m_Makefile->GetDefinition(name.c_str()))
+      if(lang)
         {
-        replaced = true;
-        cmSystemTools::ReplaceString(s, "<TARGET_SONAME>", targetSOName);
+        std::string name = "CMAKE_SHARED_LIBRARY_SONAME_";
+        name += lang;
+        name += "_FLAG";
+        if(m_Makefile->GetDefinition(name.c_str()))
+          {
+          return targetSOName;
+          }
         }
-      }
-    if(!replaced)
-      {
-      cmSystemTools::ReplaceString(s, "<TARGET_SONAME>", "");
+      return "";
       }
     }
   if(linkLibs)
     {
-    cmSystemTools::ReplaceString(s, "<LINK_LIBRARIES>", linkLibs);
+    if(variable == "LINK_LIBRARIES")
+      {
+      return linkLibs;
+      }
     }
-  
+  std::vector<std::string> enabledLanguages;
+  m_GlobalGenerator->GetEnabledLanguages(enabledLanguages);
   // loop over language specific replace variables
   int pos = 0;
   while(ruleReplaceVars[pos])
@@ -725,27 +752,87 @@ cmLocalGenerator::ExpandRuleVariables(std::string& s,
         i != enabledLanguages.end(); ++i)   
       { 
       lang = i->c_str();
-      std::string replace = "<";
-      replace += ruleReplaceVars[pos];
-      replace += ">";
-      std::string replaceWith = ruleReplaceVars[pos];
-      std::string actualReplace = replace;
-      cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang);
-      std::string actualReplaceWith = replaceWith;
-      cmSystemTools::ReplaceString(actualReplaceWith, "${LANG}", lang);
-      replace = m_Makefile->GetSafeDefinition(actualReplaceWith.c_str());
-      // if the variable is not a FLAG then treat it like a path
-      if(actualReplaceWith.find("_FLAG") == actualReplaceWith.npos)
+      std::string actualReplace = ruleReplaceVars[pos];
+      if(actualReplace.find("${LANG}") != actualReplace.npos)
         {
-        replace = this->ConvertToOutputForExisting(replace.c_str());
+        cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang);
         }
-      if(actualReplace.size())
+      if(actualReplace == variable)
         {
-        cmSystemTools::ReplaceString(s, actualReplace.c_str(), replace.c_str());
+        std::string replace = m_Makefile->GetSafeDefinition(variable.c_str());
+        // if the variable is not a FLAG then treat it like a path
+        if(variable.find("_FLAG") == variable.npos)
+          {
+          return this->ConvertToOutputForExisting(replace.c_str());
+          }
+        return replace;
         }
       }
     pos++;
     }
+  return variable;
+}
+
+
+void 
+cmLocalGenerator::ExpandRuleVariables(std::string& s,
+                                      const char* lang,
+                                      const char* objects,
+                                      const char* target,
+                                      const char* linkLibs,
+                                      const char* source,
+                                      const char* object,
+                                      const char* flags,
+                                      const char* objectsquoted,
+                                      const char* targetBase,
+                                      const char* targetSOName,
+                                      const char* linkFlags)
+{
+  std::vector<std::string> enabledLanguages;
+  m_GlobalGenerator->GetEnabledLanguages(enabledLanguages);
+  std::string::size_type start = s.find('<');
+  // no variables to expand
+  if(start == s.npos)
+    {
+    return;
+    }
+  std::string::size_type pos = 0;
+  std::string expandedInput;
+  while(start != s.npos && start < s.size()-2)
+    {
+    std::string::size_type end = s.find('>', start);
+    // if we find a < with no > we are done
+    if(end == s.npos)
+      {
+      return;
+      }
+    char c = s[start+1];
+    // if the next char after the < is not A-Za-z then
+    // skip it and try to find the next < in the string
+    if(!isalpha(c))
+      {
+      start = s.find('<', start+1);
+      }
+    else
+      {
+      // extract the var
+      std::string var = s.substr(start+1,  end - start-1);
+      std::string replace = this->ExpandRuleVariable(var, lang, objects,
+                                                     target, linkLibs,
+                                                     source, object, flags,
+                                                     objectsquoted, 
+                                                     targetBase, targetSOName,
+                                                     linkFlags);
+      expandedInput += s.substr(pos, start-pos);
+      expandedInput += replace;
+      // move to next one
+      start = s.find('<', start+var.size()+2);
+      pos = end+1;
+      }
+    }
+  // add the rest of the input
+  expandedInput += s.substr(pos, s.size()-pos);
+  s = expandedInput;
 }
 
 

+ 14 - 0
Source/cmLocalGenerator.h

@@ -162,6 +162,20 @@ protected:
                            const char* targetBase = 0,
                            const char* targetSOName = 0,
                            const char* linkFlags = 0);
+  // Expand rule variables in a single string
+  std::string ExpandRuleVariable(std::string const& variable,
+                                 const char* lang,
+                                 const char* objects,
+                                 const char* target,
+                                 const char* linkLibs,
+                                 const char* source,
+                                 const char* object,
+                                 const char* flags,
+                                 const char* objectsquoted,
+                                 const char* targetBase,
+                                 const char* targetSOName,
+                                 const char* linkFlags);
+  
   ///! Convert a target to a utility target for unsupported languages of a generator
   void AddBuildTargetRule(const char* llang, cmTarget& target);
   ///! add a custom command to build a .o file that is part of a target 

+ 17 - 6
Source/cmLocalVisualStudio7Generator.cxx

@@ -540,19 +540,30 @@ void cmLocalVisualStudio7Generator::FillFlagMapFromCommandFlags(
   std::string& flags)
 {
   std::string replace;
+  std::string option;
   while(flagTable->IDEName)
     {
-    std::string regex = "((/|-)";
-    regex += flagTable->commandFlag;
-    regex += ")";
-    cmsys::RegularExpression reg(regex.c_str());
-    while(reg.find(flags))
+    option.reserve(strlen(flagTable->commandFlag+2));
+    // first do the - version
+    option.insert(0, 1, '-');
+    option.append(flagTable->commandFlag);
+    while(flags.find(option) != flags.npos)
       {
       // replace the flag 
-      cmSystemTools::ReplaceString(flags, reg.match(1).c_str(), "");
+      cmSystemTools::ReplaceString(flags, option.c_str(), "");
       // now put value into flag map
       flagMap[flagTable->IDEName] = flagTable->value;
       }
+    // now do the / version
+    option[0] = '/';
+    while(flags.find(option) != flags.npos)
+      {
+      // replace the flag 
+      cmSystemTools::ReplaceString(flags, option.c_str(), "");
+      // now put value into flag map
+      flagMap[flagTable->IDEName] = flagTable->value;
+      }
+    // move to next flag
     flagTable++;
     }
 }

+ 9 - 3
Source/cmMacroCommand.cxx

@@ -119,6 +119,14 @@ bool cmMacroHelperCommand::InvokeInitialPass
     newLFF.m_Name = m_Functions[c].m_Name;
     newLFF.m_FilePath = m_Functions[c].m_FilePath;
     newLFF.m_Line = m_Functions[c].m_Line;
+    const char* def =
+      m_Makefile->GetDefinition("CMAKE_MACRO_REPORT_DEFINITION_LOCATION"); 
+    bool macroReportLocation = false;
+    if(def && !cmSystemTools::IsOff(def))
+      {
+      macroReportLocation = true;
+      }
+    
     // for each argument of the current function
     for (std::vector<cmListFileArgument>::const_iterator k = 
            m_Functions[c].m_Arguments.begin();
@@ -194,9 +202,7 @@ bool cmMacroHelperCommand::InvokeInitialPass
       
       arg.Value = tmps;
       arg.Quoted = k->Quoted;
-      const char* def =
-        m_Makefile->GetDefinition("CMAKE_MACRO_REPORT_DEFINITION_LOCATION");
-      if(def && !cmSystemTools::IsOff(def))
+      if(macroReportLocation)
         {
         // Report the location of the argument where the macro was
         // defined.

+ 5 - 4
Source/cmMakefile.cxx

@@ -1355,7 +1355,8 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
                                                 bool escapeQuotes,
                                                 bool atOnly,
                                                 const char* filename,
-                                                long line) const
+                                                long line,
+                                                bool removeEmpty) const
 {
   // This method replaces ${VAR} and @VAR@ where VAR is looked up
   // with GetDefinition(), if not found in the map, nothing is expanded.
@@ -1491,7 +1492,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
         if (!found)
           {
           // if no definition is found then add the var back
-          if(endVariableMarker == '@')
+          if(!removeEmpty && endVariableMarker == '@')
             {
             result += "@";
             result += var;
@@ -2311,8 +2312,8 @@ void cmMakefile::ConfigureString(const std::string& input,
     }
 
   // Perform variable replacements.
-  this->ExpandVariablesInString(output, escapeQuotes, atOnly);
-  this->RemoveVariablesInString(output, atOnly);
+  this->ExpandVariablesInString(output, escapeQuotes, atOnly, 0, -1, true);
+//  this->RemoveVariablesInString(output, atOnly);
 }
 
 int cmMakefile::ConfigureFile(const char* infile, const char* outfile, 

+ 2 - 1
Source/cmMakefile.h

@@ -542,7 +542,8 @@ public:
   const char *ExpandVariablesInString(std::string& source, bool escapeQuotes,
                                       bool atOnly = false,
                                       const char* filename = 0,
-                                      long line = -1) const;
+                                      long line = -1,
+                                      bool removeEmpty = false) const;
 
   /**
    * Remove any remaining variables in the string. Anything with ${var} or