[Cmake-commits] CMake branch, next, updated. v3.7.0-rc1-398-g86d03c3

Brad King brad.king at kitware.com
Tue Oct 11 10:25:59 EDT 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  86d03c32678c016cbd70d911d38439125d08e207 (commit)
       via  f30fb4d5a450e287ea34667f42efa10e3426ac1f (commit)
      from  1c6b43d80fe151145e68ed1f718b31705abb1537 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=86d03c32678c016cbd70d911d38439125d08e207
commit 86d03c32678c016cbd70d911d38439125d08e207
Merge: 1c6b43d f30fb4d
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Oct 11 10:25:58 2016 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Tue Oct 11 10:25:58 2016 -0400

    Merge topic 'extract-cmRulePlaceholderExpander' into next
    
    f30fb4d5 Revert topic 'extract-cmRulePlaceholderExpander'

diff --cc Source/cmMakefileLibraryTargetGenerator.cxx
index cb8b5e8,4488f06..8a621ea
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@@ -597,20 -607,15 +595,10 @@@ void cmMakefileLibraryTargetGenerator::
      this->LocalGenerator->AddArchitectureFlags(
        langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
  
 -    // remove any language flags that might not work with the
 -    // particular os
 -    if (forbiddenFlagVar) {
 -      this->RemoveForbiddenFlags(forbiddenFlagVar, linkLanguage, langFlags);
 -    }
      vars.LanguageCompileFlags = langFlags.c_str();
  
-     std::string launcher;
-     const char* val = this->LocalGenerator->GetRuleLauncher(
-       this->GeneratorTarget, "RULE_LAUNCH_LINK");
-     if (val && *val) {
-       launcher = val;
-       launcher += " ";
-     }
- 
-     CM_AUTO_PTR<cmRulePlaceholderExpander> rulePlaceholderExpander(
-       this->LocalGenerator->CreateRulePlaceholderExpander());
      // Construct the main link rule and expand placeholders.
-     rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport);
+     this->LocalGenerator->TargetImplib = targetOutPathImport;
      if (useArchiveRules) {
        // Construct the individual object list strings.
        std::vector<std::string> object_strings;

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f30fb4d5a450e287ea34667f42efa10e3426ac1f
commit f30fb4d5a450e287ea34667f42efa10e3426ac1f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Oct 11 10:25:42 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Oct 11 10:25:42 2016 -0400

    Revert topic 'extract-cmRulePlaceholderExpander'
    
    It needs revisions to deal with dashboard errors.

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 7d82a51..048667a 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -309,8 +309,6 @@ set(SRCS
   cmLocalCommonGenerator.h
   cmLocalGenerator.cxx
   cmLocalGenerator.h
-  cmRulePlaceholderExpander.cxx
-  cmRulePlaceholderExpander.h
   cmLocalUnixMakefileGenerator3.cxx
   cmLocale.h
   ${MACH_SRCS}
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 1c3a97d..3b19694 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -14,7 +14,6 @@
 #include "cmInstallTargetGenerator.h"
 #include "cmLinkLineComputer.h"
 #include "cmMakefile.h"
-#include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
@@ -41,28 +40,6 @@
 #include <StorageDefs.h>
 #endif
 
-// List of variables that are replaced when
-// rules are expanced.  These variables are
-// replaced in the form <var> with GetSafeDefinition(var).
-// ${LANG} is replaced in the variable first with all enabled
-// 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",
-  "CMAKE_SHARED_LIBRARY_${LANG}_FLAGS",
-  "CMAKE_${LANG}_LINK_FLAGS",
-  "CMAKE_SHARED_LIBRARY_SONAME_${LANG}_FLAG",
-  "CMAKE_${LANG}_ARCHIVE",
-  "CMAKE_AR",
-  "CMAKE_CURRENT_SOURCE_DIR",
-  "CMAKE_CURRENT_BINARY_DIR",
-  "CMAKE_RANLIB",
-  "CMAKE_LINKER",
-  "CMAKE_CL_SHOWINCLUDES_PREFIX"
-};
-
 cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
   : cmOutputConverter(makefile->GetStateSnapshot())
   , StateSnapshot(makefile->GetStateSnapshot())
@@ -79,65 +56,6 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
   this->BackwardsCompatibilityFinal = false;
 
   this->ComputeObjectMaxPath();
-
-  std::vector<std::string> enabledLanguages =
-    this->GetState()->GetEnabledLanguages();
-
-  this->CompilerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
-
-  for (std::vector<std::string>::iterator i = enabledLanguages.begin();
-       i != enabledLanguages.end(); ++i) {
-    std::string const& lang = *i;
-    if (lang == "NONE") {
-      continue;
-    }
-    this->Compilers["CMAKE_" + lang + "_COMPILER"] = lang;
-
-    this->VariableMappings["CMAKE_" + lang + "_COMPILER"] =
-      this->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER");
-
-    std::string const& compilerArg1 = "CMAKE_" + lang + "_COMPILER_ARG1";
-    std::string const& compilerTarget = "CMAKE_" + lang + "_COMPILER_TARGET";
-    std::string const& compilerOptionTarget =
-      "CMAKE_" + lang + "_COMPILE_OPTIONS_TARGET";
-    std::string const& compilerExternalToolchain =
-      "CMAKE_" + lang + "_COMPILER_EXTERNAL_TOOLCHAIN";
-    std::string const& compilerOptionExternalToolchain =
-      "CMAKE_" + lang + "_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN";
-    std::string const& compilerOptionSysroot =
-      "CMAKE_" + lang + "_COMPILE_OPTIONS_SYSROOT";
-
-    this->VariableMappings[compilerArg1] =
-      this->Makefile->GetSafeDefinition(compilerArg1);
-    this->VariableMappings[compilerTarget] =
-      this->Makefile->GetSafeDefinition(compilerTarget);
-    this->VariableMappings[compilerOptionTarget] =
-      this->Makefile->GetSafeDefinition(compilerOptionTarget);
-    this->VariableMappings[compilerExternalToolchain] =
-      this->Makefile->GetSafeDefinition(compilerExternalToolchain);
-    this->VariableMappings[compilerOptionExternalToolchain] =
-      this->Makefile->GetSafeDefinition(compilerOptionExternalToolchain);
-    this->VariableMappings[compilerOptionSysroot] =
-      this->Makefile->GetSafeDefinition(compilerOptionSysroot);
-
-    for (const char* const* replaceIter = cmArrayBegin(ruleReplaceVars);
-         replaceIter != cmArrayEnd(ruleReplaceVars); ++replaceIter) {
-      std::string actualReplace = *replaceIter;
-      if (actualReplace.find("${LANG}") != actualReplace.npos) {
-        cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang);
-      }
-
-      this->VariableMappings[actualReplace] =
-        this->Makefile->GetSafeDefinition(actualReplace);
-    }
-  }
-}
-
-cmRulePlaceholderExpander* cmLocalGenerator::CreateRulePlaceholderExpander()
-  const
-{
-  return new cmRulePlaceholderExpander(this->Compilers, this->VariableMappings,
-                                       this->CompilerSysroot);
 }
 
 cmLocalGenerator::~cmLocalGenerator()
@@ -568,6 +486,325 @@ cmState::Snapshot cmLocalGenerator::GetStateSnapshot() const
   return this->Makefile->GetStateSnapshot();
 }
 
+// List of variables that are replaced when
+// rules are expanced.  These variables are
+// replaced in the form <var> with GetSafeDefinition(var).
+// ${LANG} is replaced in the variable first with all enabled
+// 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",
+  "CMAKE_SHARED_LIBRARY_${LANG}_FLAGS",
+  "CMAKE_${LANG}_LINK_FLAGS",
+  "CMAKE_SHARED_LIBRARY_SONAME_${LANG}_FLAG",
+  "CMAKE_${LANG}_ARCHIVE",
+  "CMAKE_AR",
+  "CMAKE_CURRENT_SOURCE_DIR",
+  "CMAKE_CURRENT_BINARY_DIR",
+  "CMAKE_RANLIB",
+  "CMAKE_LINKER",
+  "CMAKE_CL_SHOWINCLUDES_PREFIX",
+  CM_NULLPTR
+};
+
+std::string cmLocalGenerator::ExpandRuleVariable(
+  std::string const& variable, const RuleVariables& replaceValues)
+{
+  if (replaceValues.LinkFlags) {
+    if (variable == "LINK_FLAGS") {
+      return replaceValues.LinkFlags;
+    }
+  }
+  if (replaceValues.Manifests) {
+    if (variable == "MANIFESTS") {
+      return replaceValues.Manifests;
+    }
+  }
+  if (replaceValues.Flags) {
+    if (variable == "FLAGS") {
+      return replaceValues.Flags;
+    }
+  }
+
+  if (replaceValues.Source) {
+    if (variable == "SOURCE") {
+      return replaceValues.Source;
+    }
+  }
+  if (replaceValues.PreprocessedSource) {
+    if (variable == "PREPROCESSED_SOURCE") {
+      return replaceValues.PreprocessedSource;
+    }
+  }
+  if (replaceValues.AssemblySource) {
+    if (variable == "ASSEMBLY_SOURCE") {
+      return replaceValues.AssemblySource;
+    }
+  }
+  if (replaceValues.Object) {
+    if (variable == "OBJECT") {
+      return replaceValues.Object;
+    }
+  }
+  if (replaceValues.ObjectDir) {
+    if (variable == "OBJECT_DIR") {
+      return replaceValues.ObjectDir;
+    }
+  }
+  if (replaceValues.ObjectFileDir) {
+    if (variable == "OBJECT_FILE_DIR") {
+      return replaceValues.ObjectFileDir;
+    }
+  }
+  if (replaceValues.Objects) {
+    if (variable == "OBJECTS") {
+      return replaceValues.Objects;
+    }
+  }
+  if (replaceValues.ObjectsQuoted) {
+    if (variable == "OBJECTS_QUOTED") {
+      return replaceValues.ObjectsQuoted;
+    }
+  }
+  if (replaceValues.Defines && variable == "DEFINES") {
+    return replaceValues.Defines;
+  }
+  if (replaceValues.Includes && variable == "INCLUDES") {
+    return replaceValues.Includes;
+  }
+  if (replaceValues.TargetPDB) {
+    if (variable == "TARGET_PDB") {
+      return replaceValues.TargetPDB;
+    }
+  }
+  if (replaceValues.TargetCompilePDB) {
+    if (variable == "TARGET_COMPILE_PDB") {
+      return replaceValues.TargetCompilePDB;
+    }
+  }
+  if (replaceValues.DependencyFile) {
+    if (variable == "DEP_FILE") {
+      return replaceValues.DependencyFile;
+    }
+  }
+
+  if (replaceValues.Target) {
+    if (variable == "TARGET_QUOTED") {
+      std::string targetQuoted = replaceValues.Target;
+      if (!targetQuoted.empty() && targetQuoted[0] != '\"') {
+        targetQuoted = '\"';
+        targetQuoted += replaceValues.Target;
+        targetQuoted += '\"';
+      }
+      return targetQuoted;
+    }
+    if (variable == "TARGET_UNQUOTED") {
+      std::string unquoted = replaceValues.Target;
+      std::string::size_type sz = unquoted.size();
+      if (sz > 2 && unquoted[0] == '\"' && unquoted[sz - 1] == '\"') {
+        unquoted = unquoted.substr(1, sz - 2);
+      }
+      return unquoted;
+    }
+    if (replaceValues.LanguageCompileFlags) {
+      if (variable == "LANGUAGE_COMPILE_FLAGS") {
+        return replaceValues.LanguageCompileFlags;
+      }
+    }
+    if (replaceValues.Target) {
+      if (variable == "TARGET") {
+        return replaceValues.Target;
+      }
+    }
+    if (variable == "TARGET_IMPLIB") {
+      return this->TargetImplib;
+    }
+    if (variable == "TARGET_VERSION_MAJOR") {
+      if (replaceValues.TargetVersionMajor) {
+        return replaceValues.TargetVersionMajor;
+      }
+      return "0";
+    }
+    if (variable == "TARGET_VERSION_MINOR") {
+      if (replaceValues.TargetVersionMinor) {
+        return replaceValues.TargetVersionMinor;
+      }
+      return "0";
+    }
+    if (replaceValues.Target) {
+      if (variable == "TARGET_BASE") {
+        // Strip the last extension off the target name.
+        std::string targetBase = replaceValues.Target;
+        std::string::size_type pos = targetBase.rfind('.');
+        if (pos != targetBase.npos) {
+          return targetBase.substr(0, pos);
+        }
+        return targetBase;
+      }
+    }
+  }
+  if (variable == "TARGET_SONAME" || variable == "SONAME_FLAG" ||
+      variable == "TARGET_INSTALLNAME_DIR") {
+    // All these variables depend on TargetSOName
+    if (replaceValues.TargetSOName) {
+      if (variable == "TARGET_SONAME") {
+        return replaceValues.TargetSOName;
+      }
+      if (variable == "SONAME_FLAG" && replaceValues.SONameFlag) {
+        return replaceValues.SONameFlag;
+      }
+      if (replaceValues.TargetInstallNameDir &&
+          variable == "TARGET_INSTALLNAME_DIR") {
+        return replaceValues.TargetInstallNameDir;
+      }
+    }
+    return "";
+  }
+  if (replaceValues.LinkLibraries) {
+    if (variable == "LINK_LIBRARIES") {
+      return replaceValues.LinkLibraries;
+    }
+  }
+  if (replaceValues.Language) {
+    if (variable == "LANGUAGE") {
+      return replaceValues.Language;
+    }
+  }
+  if (replaceValues.CMTarget) {
+    if (variable == "TARGET_NAME") {
+      return replaceValues.CMTarget->GetName();
+    }
+    if (variable == "TARGET_TYPE") {
+      return cmState::GetTargetTypeName(replaceValues.CMTarget->GetType());
+    }
+  }
+  if (replaceValues.Output) {
+    if (variable == "OUTPUT") {
+      return replaceValues.Output;
+    }
+  }
+  if (variable == "CMAKE_COMMAND") {
+    return this->ConvertToOutputFormat(
+      cmSystemTools::CollapseFullPath(cmSystemTools::GetCMakeCommand()),
+      SHELL);
+  }
+  std::vector<std::string> enabledLanguages =
+    this->GetState()->GetEnabledLanguages();
+  // loop over language specific replace variables
+  int pos = 0;
+  while (ruleReplaceVars[pos]) {
+    for (std::vector<std::string>::iterator i = enabledLanguages.begin();
+         i != enabledLanguages.end(); ++i) {
+      const char* lang = i->c_str();
+      std::string actualReplace = ruleReplaceVars[pos];
+      // If this is the compiler then look for the extra variable
+      // _COMPILER_ARG1 which must be the first argument to the compiler
+      const char* compilerArg1 = CM_NULLPTR;
+      const char* compilerTarget = CM_NULLPTR;
+      const char* compilerOptionTarget = CM_NULLPTR;
+      const char* compilerExternalToolchain = CM_NULLPTR;
+      const char* compilerOptionExternalToolchain = CM_NULLPTR;
+      const char* compilerSysroot = CM_NULLPTR;
+      const char* compilerOptionSysroot = CM_NULLPTR;
+      if (actualReplace == "CMAKE_${LANG}_COMPILER") {
+        std::string arg1 = actualReplace + "_ARG1";
+        cmSystemTools::ReplaceString(arg1, "${LANG}", lang);
+        compilerArg1 = this->Makefile->GetDefinition(arg1);
+        compilerTarget = this->Makefile->GetDefinition(
+          std::string("CMAKE_") + lang + "_COMPILER_TARGET");
+        compilerOptionTarget = this->Makefile->GetDefinition(
+          std::string("CMAKE_") + lang + "_COMPILE_OPTIONS_TARGET");
+        compilerExternalToolchain = this->Makefile->GetDefinition(
+          std::string("CMAKE_") + lang + "_COMPILER_EXTERNAL_TOOLCHAIN");
+        compilerOptionExternalToolchain =
+          this->Makefile->GetDefinition(std::string("CMAKE_") + lang +
+                                        "_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN");
+        compilerSysroot = this->Makefile->GetDefinition("CMAKE_SYSROOT");
+        compilerOptionSysroot = this->Makefile->GetDefinition(
+          std::string("CMAKE_") + lang + "_COMPILE_OPTIONS_SYSROOT");
+      }
+      if (actualReplace.find("${LANG}") != actualReplace.npos) {
+        cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang);
+      }
+      if (actualReplace == variable) {
+        std::string replace = this->Makefile->GetSafeDefinition(variable);
+        // if the variable is not a FLAG then treat it like a path
+        if (variable.find("_FLAG") == variable.npos) {
+          std::string ret = this->ConvertToOutputForExisting(replace);
+          // if there is a required first argument to the compiler add it
+          // to the compiler string
+          if (compilerArg1) {
+            ret += " ";
+            ret += compilerArg1;
+          }
+          if (compilerTarget && compilerOptionTarget) {
+            ret += " ";
+            ret += compilerOptionTarget;
+            ret += compilerTarget;
+          }
+          if (compilerExternalToolchain && compilerOptionExternalToolchain) {
+            ret += " ";
+            ret += compilerOptionExternalToolchain;
+            ret += this->EscapeForShell(compilerExternalToolchain, true);
+          }
+          if (compilerSysroot && compilerOptionSysroot) {
+            ret += " ";
+            ret += compilerOptionSysroot;
+            ret += this->EscapeForShell(compilerSysroot, true);
+          }
+          return ret;
+        }
+        return replace;
+      }
+    }
+    pos++;
+  }
+  return variable;
+}
+
+void cmLocalGenerator::ExpandRuleVariables(std::string& s,
+                                           const RuleVariables& replaceValues)
+{
+  if (replaceValues.RuleLauncher) {
+    this->InsertRuleLauncher(s, replaceValues.CMTarget,
+                             replaceValues.RuleLauncher);
+  }
+  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, replaceValues);
+      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;
+}
+
 const char* cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
                                               const std::string& prop)
 {
@@ -577,6 +814,17 @@ const char* cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
   return this->Makefile->GetProperty(prop);
 }
 
+void cmLocalGenerator::InsertRuleLauncher(std::string& s,
+                                          cmGeneratorTarget* target,
+                                          const std::string& prop)
+{
+  if (const char* val = this->GetRuleLauncher(target, prop)) {
+    std::ostringstream wrapped;
+    wrapped << val << " " << s;
+    s = wrapped.str();
+  }
+}
+
 std::string cmLocalGenerator::ConvertToIncludeReference(
   std::string const& path, OutputFormat format, bool forceFullPaths)
 {
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 055e1a9..69c4101 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -8,7 +8,6 @@
 #include "cmListFileCache.h"
 #include "cmOutputConverter.h"
 #include "cmPolicies.h"
-#include "cmRulePlaceholderExpander.h"
 #include "cmState.h"
 #include "cmake.h"
 
@@ -24,7 +23,6 @@ class cmComputeLinkInformation;
 class cmCustomCommandGenerator;
 class cmGeneratorTarget;
 class cmGlobalGenerator;
-class cmRulePlaceholderExpander;
 class cmMakefile;
 class cmSourceFile;
 class cmLinkLineComputer;
@@ -86,8 +84,6 @@ public:
     return this->GlobalGenerator;
   }
 
-  virtual cmRulePlaceholderExpander* CreateRulePlaceholderExpander() const;
-
   std::string GetLinkLibsCMP0065(std::string const& linkLanguage,
                                  cmGeneratorTarget& tgt) const;
 
@@ -221,6 +217,42 @@ public:
   // preprocessed files and assembly files.
   void GetIndividualFileTargets(std::vector<std::string>&) {}
 
+  // Create a struct to hold the varibles passed into
+  // ExpandRuleVariables
+  struct RuleVariables
+  {
+    RuleVariables() { memset(this, 0, sizeof(*this)); }
+    cmGeneratorTarget* CMTarget;
+    const char* TargetPDB;
+    const char* TargetCompilePDB;
+    const char* TargetVersionMajor;
+    const char* TargetVersionMinor;
+    const char* Language;
+    const char* Objects;
+    const char* Target;
+    const char* LinkLibraries;
+    const char* Source;
+    const char* AssemblySource;
+    const char* PreprocessedSource;
+    const char* Output;
+    const char* Object;
+    const char* ObjectDir;
+    const char* ObjectFileDir;
+    const char* Flags;
+    const char* ObjectsQuoted;
+    const char* SONameFlag;
+    const char* TargetSOName;
+    const char* TargetInstallNameDir;
+    const char* LinkFlags;
+    const char* Manifests;
+    const char* LanguageCompileFlags;
+    const char* Defines;
+    const char* Includes;
+    const char* RuleLauncher;
+    const char* DependencyFile;
+    const char* FilterPrefix;
+  };
+
   /**
    * Get the relative path from the generator output directory to a
    * per-target support directory.
@@ -314,9 +346,6 @@ public:
   void CreateEvaluationFileOutputs(const std::string& config);
   void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles);
 
-  const char* GetRuleLauncher(cmGeneratorTarget* target,
-                              const std::string& prop);
-
 protected:
   ///! put all the libraries for a target on into the given stream
   void OutputLinkLibraries(cmComputeLinkInformation* pcli,
@@ -324,6 +353,18 @@ protected:
                            std::string& linkLibraries,
                            std::string& frameworkPath, std::string& linkPath);
 
+  // Expand rule variables in CMake of the type found in language rules
+  void ExpandRuleVariables(std::string& string,
+                           const RuleVariables& replaceValues);
+  // Expand rule variables in a single string
+  std::string ExpandRuleVariable(std::string const& variable,
+                                 const RuleVariables& replaceValues);
+
+  const char* GetRuleLauncher(cmGeneratorTarget* target,
+                              const std::string& prop);
+  void InsertRuleLauncher(std::string& s, cmGeneratorTarget* target,
+                          const std::string& prop);
+
   // Handle old-style install rules stored in the targets.
   void GenerateTargetInstallRules(
     std::ostream& os, const std::string& config,
@@ -350,12 +391,12 @@ protected:
   std::vector<cmGeneratorTarget*> OwnedImportedGeneratorTargets;
   std::map<std::string, std::string> AliasTargets;
 
-  std::map<std::string, std::string> Compilers;
-  std::map<std::string, std::string> VariableMappings;
-  std::string CompilerSysroot;
-
   bool EmitUniversalBinaryFlags;
 
+  // Hack for ExpandRuleVariable until object-oriented version is
+  // committed.
+  std::string TargetImplib;
+
   KWIML_INT_uint64_t BackwardsCompatibility;
   bool BackwardsCompatibilityFinal;
 
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 1863376..e25eb0f 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -10,7 +10,6 @@
 #include "cmGlobalNinjaGenerator.h"
 #include "cmMakefile.h"
 #include "cmNinjaTargetGenerator.h"
-#include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
 #include "cmState.h"
 #include "cmSystemTools.h"
@@ -28,19 +27,11 @@ cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg,
   : cmLocalCommonGenerator(gg, mf, mf->GetState()->GetBinaryDirectory())
   , HomeRelativeOutputPath("")
 {
+  this->TargetImplib = "$TARGET_IMPLIB";
 }
 
 // Virtual public methods.
 
-cmRulePlaceholderExpander*
-cmLocalNinjaGenerator::CreateRulePlaceholderExpander() const
-{
-  cmRulePlaceholderExpander* ret = new cmRulePlaceholderExpander(
-    this->Compilers, this->VariableMappings, this->CompilerSysroot);
-  ret->SetTargetImpLib("$TARGET_IMPLIB");
-  return ret;
-}
-
 cmLocalNinjaGenerator::~cmLocalNinjaGenerator()
 {
 }
@@ -477,8 +468,8 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
 std::string cmLocalNinjaGenerator::MakeCustomLauncher(
   cmCustomCommandGenerator const& ccg)
 {
-  const char* property_value =
-    this->Makefile->GetProperty("RULE_LAUNCH_CUSTOM");
+  const char* property = "RULE_LAUNCH_CUSTOM";
+  const char* property_value = this->Makefile->GetProperty(property);
 
   if (!property_value || !*property_value) {
     return std::string();
@@ -486,8 +477,8 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
 
   // Expand rules in the empty string.  It may insert the launcher and
   // perform replacements.
-  cmRulePlaceholderExpander::RuleVariables vars;
-
+  RuleVariables vars;
+  vars.RuleLauncher = property;
   std::string output;
   const std::vector<std::string>& outputs = ccg.GetOutputs();
   if (!outputs.empty()) {
@@ -500,13 +491,8 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
   }
   vars.Output = output.c_str();
 
-  std::string launcher = property_value;
-  launcher += " ";
-
-  CM_AUTO_PTR<cmRulePlaceholderExpander> rulePlaceholderExpander(
-    this->CreateRulePlaceholderExpander());
-
-  rulePlaceholderExpander->ExpandRuleVariables(this, launcher, vars);
+  std::string launcher;
+  this->ExpandRuleVariables(launcher, vars);
   if (!launcher.empty()) {
     launcher += " ";
   }
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 95d8eb8..b04788d 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -42,8 +42,6 @@ public:
 
   void Generate() CM_OVERRIDE;
 
-  cmRulePlaceholderExpander* CreateRulePlaceholderExpander() const CM_OVERRIDE;
-
   std::string GetTargetDirectory(cmGeneratorTarget const* target) const
     CM_OVERRIDE;
 
@@ -60,6 +58,12 @@ public:
     return this->HomeRelativeOutputPath;
   }
 
+  void ExpandRuleVariables(std::string& string,
+                           const RuleVariables& replaceValues)
+  {
+    cmLocalGenerator::ExpandRuleVariables(string, replaceValues);
+  }
+
   std::string BuildCommandLine(const std::vector<std::string>& cmdLines);
 
   void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index f30414c..02eef59 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -14,7 +14,6 @@
 #include "cmMakefile.h"
 #include "cmMakefileTargetGenerator.h"
 #include "cmOutputConverter.h"
-#include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
 #include "cmState.h"
 #include "cmSystemTools.h"
@@ -946,9 +945,6 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
     *content << dir;
   }
 
-  CM_AUTO_PTR<cmRulePlaceholderExpander> rulePlaceholderExpander(
-    this->CreateRulePlaceholderExpander());
-
   // Add each command line to the set of commands.
   std::vector<std::string> commands1;
   std::string currentBinDir = this->GetCurrentBinaryDirectory();
@@ -988,13 +984,14 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
 
       std::string launcher;
       // Short-circuit if there is no launcher.
-      const char* val = this->GetRuleLauncher(target, "RULE_LAUNCH_CUSTOM");
+      const char* prop = "RULE_LAUNCH_CUSTOM";
+      const char* val = this->GetRuleLauncher(target, prop);
       if (val && *val) {
         // Expand rules in the empty string.  It may insert the launcher and
         // perform replacements.
-        cmRulePlaceholderExpander::RuleVariables vars;
-        vars.CMTargetName = target->GetName().c_str();
-        vars.CMTargetType = cmState::GetTargetTypeName(target->GetType());
+        RuleVariables vars;
+        vars.RuleLauncher = prop;
+        vars.CMTarget = target;
         std::string output;
         const std::vector<std::string>& outputs = ccg.GetOutputs();
         if (!outputs.empty()) {
@@ -1008,9 +1005,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
         }
         vars.Output = output.c_str();
 
-        launcher = val;
-        launcher += " ";
-        rulePlaceholderExpander->ExpandRuleVariables(this, launcher, vars);
+        this->ExpandRuleVariables(launcher, vars);
         if (!launcher.empty()) {
           launcher += " ";
         }
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index dd3fc36..bfc4857 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -11,7 +11,6 @@
 #include "cmMakefile.h"
 #include "cmOSXBundleGenerator.h"
 #include "cmOutputConverter.h"
-#include "cmRulePlaceholderExpander.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
 
@@ -332,10 +331,9 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
 
     std::string manifests = this->GetManifests();
 
-    cmRulePlaceholderExpander::RuleVariables vars;
-    vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
-    vars.CMTargetType =
-      cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
+    cmLocalGenerator::RuleVariables vars;
+    vars.RuleLauncher = "RULE_LAUNCH_LINK";
+    vars.CMTarget = this->GeneratorTarget;
     vars.Language = linkLanguage.c_str();
     vars.Objects = buildObjs.c_str();
     std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
@@ -385,26 +383,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
       real_link_commands.push_back(cmakeCommand);
     }
 
-    std::string launcher;
-
-    const char* val = this->LocalGenerator->GetRuleLauncher(
-      this->GeneratorTarget, "RULE_LAUNCH_LINK");
-    if (val && *val) {
-      launcher = val;
-      launcher += " ";
-    }
-
-    CM_AUTO_PTR<cmRulePlaceholderExpander> rulePlaceholderExpander(
-      this->LocalGenerator->CreateRulePlaceholderExpander());
-
     // Expand placeholders in the commands.
-    rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport);
+    this->LocalGenerator->TargetImplib = targetOutPathImport;
     for (std::vector<std::string>::iterator i = real_link_commands.begin();
          i != real_link_commands.end(); ++i) {
-      *i = launcher + *i;
-      rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, *i,
-                                                   vars);
+      this->LocalGenerator->ExpandRuleVariables(*i, vars);
     }
+    this->LocalGenerator->TargetImplib = "";
 
     // Restore path conversion to normal shells.
     this->LocalGenerator->SetLinkScriptShell(false);
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 9f5f0c1..4488f06 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -11,7 +11,6 @@
 #include "cmMakefile.h"
 #include "cmOSXBundleGenerator.h"
 #include "cmOutputConverter.h"
-#include "cmRulePlaceholderExpander.h"
 #include "cmState.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
@@ -533,7 +532,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
 
     std::string manifests = this->GetManifests();
 
-    cmRulePlaceholderExpander::RuleVariables vars;
+    cmLocalGenerator::RuleVariables vars;
     vars.TargetPDB = targetOutPathPDB.c_str();
 
     // Setup the target version.
@@ -553,9 +552,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
     vars.TargetVersionMajor = targetVersionMajor.c_str();
     vars.TargetVersionMinor = targetVersionMinor.c_str();
 
-    vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
-    vars.CMTargetType =
-      cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
+    vars.RuleLauncher = "RULE_LAUNCH_LINK";
+    vars.CMTarget = this->GeneratorTarget;
     vars.Language = linkLanguage.c_str();
     vars.Objects = buildObjs.c_str();
     std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
@@ -616,18 +614,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
     }
     vars.LanguageCompileFlags = langFlags.c_str();
 
-    std::string launcher;
-    const char* val = this->LocalGenerator->GetRuleLauncher(
-      this->GeneratorTarget, "RULE_LAUNCH_LINK");
-    if (val && *val) {
-      launcher = val;
-      launcher += " ";
-    }
-
-    CM_AUTO_PTR<cmRulePlaceholderExpander> rulePlaceholderExpander(
-      this->LocalGenerator->CreateRulePlaceholderExpander());
     // Construct the main link rule and expand placeholders.
-    rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport);
+    this->LocalGenerator->TargetImplib = targetOutPathImport;
     if (useArchiveRules) {
       // Construct the individual object list strings.
       std::vector<std::string> object_strings;
@@ -640,9 +628,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
         for (std::vector<std::string>::const_iterator i =
                archiveCreateCommands.begin();
              i != archiveCreateCommands.end(); ++i) {
-          std::string cmd = launcher + *i;
-          rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
-                                                       cmd, vars);
+          std::string cmd = *i;
+          this->LocalGenerator->ExpandRuleVariables(cmd, vars);
           real_link_commands.push_back(cmd);
         }
       }
@@ -652,9 +639,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
         for (std::vector<std::string>::const_iterator i =
                archiveAppendCommands.begin();
              i != archiveAppendCommands.end(); ++i) {
-          std::string cmd = launcher + *i;
-          rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
-                                                       cmd, vars);
+          std::string cmd = *i;
+          this->LocalGenerator->ExpandRuleVariables(cmd, vars);
           real_link_commands.push_back(cmd);
         }
       }
@@ -663,9 +649,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
       for (std::vector<std::string>::const_iterator i =
              archiveFinishCommands.begin();
            i != archiveFinishCommands.end(); ++i) {
-        std::string cmd = launcher + *i;
-        rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, cmd,
-                                                     vars);
+        std::string cmd = *i;
+        this->LocalGenerator->ExpandRuleVariables(cmd, vars);
         // If there is no ranlib the command will be ":".  Skip it.
         if (!cmd.empty() && cmd[0] != ':') {
           real_link_commands.push_back(cmd);
@@ -687,11 +672,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
       // Expand placeholders.
       for (std::vector<std::string>::iterator i = real_link_commands.begin();
            i != real_link_commands.end(); ++i) {
-        *i = launcher + *i;
-        rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, *i,
-                                                     vars);
+        this->LocalGenerator->ExpandRuleVariables(*i, vars);
       }
     }
+    this->LocalGenerator->TargetImplib = "";
 
     // Restore path conversion to normal shells.
     this->LocalGenerator->SetLinkScriptShell(false);
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 3947c47..1483fbb 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -18,7 +18,6 @@
 #include "cmMakefileLibraryTargetGenerator.h"
 #include "cmMakefileUtilityTargetGenerator.h"
 #include "cmOutputConverter.h"
-#include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
 #include "cmState.h"
 #include "cmSystemTools.h"
@@ -544,11 +543,9 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
       targetOutPathCompilePDB[targetOutPathCompilePDB.size() - 1] = '/';
     }
   }
-  cmRulePlaceholderExpander::RuleVariables vars;
+  cmLocalGenerator::RuleVariables vars;
   vars.RuleLauncher = "RULE_LAUNCH_COMPILE";
-  vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
-  vars.CMTargetType =
-    cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
+  vars.CMTarget = this->GeneratorTarget;
   vars.Language = lang.c_str();
   vars.Target = targetOutPathReal.c_str();
   vars.TargetPDB = targetOutPathPDB.c_str();
@@ -590,9 +587,6 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
   bool const lang_has_assembly = lang_has_preprocessor;
   bool const lang_can_export_cmds = lang_has_preprocessor;
 
-  CM_AUTO_PTR<cmRulePlaceholderExpander> rulePlaceholderExpander(
-    this->LocalGenerator->CreateRulePlaceholderExpander());
-
   // Construct the compile rules.
   {
     std::string compileRuleVar = "CMAKE_";
@@ -606,9 +600,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
     if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") &&
         lang_can_export_cmds && compileCommands.size() == 1) {
       std::string compileCommand = compileCommands[0];
-
-      rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
-                                                   compileCommand, vars);
+      this->LocalGenerator->ExpandRuleVariables(compileCommand, vars);
       std::string workingDirectory = cmSystemTools::CollapseFullPath(
         this->LocalGenerator->GetCurrentBinaryDirectory());
       compileCommand.replace(compileCommand.find(langFlags), langFlags.size(),
@@ -667,8 +659,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
     // Expand placeholders in the commands.
     for (std::vector<std::string>::iterator i = compileCommands.begin();
          i != compileCommands.end(); ++i) {
-      rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, *i,
-                                                   vars);
+      this->LocalGenerator->ExpandRuleVariables(*i, vars);
     }
 
     // Change the command working directory to the local build tree.
@@ -731,8 +722,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
         // Expand placeholders in the commands.
         for (std::vector<std::string>::iterator i = preprocessCommands.begin();
              i != preprocessCommands.end(); ++i) {
-          rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
-                                                       *i, vars);
+          this->LocalGenerator->ExpandRuleVariables(*i, vars);
         }
 
         this->LocalGenerator->CreateCDCommand(
@@ -779,8 +769,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
         // Expand placeholders in the commands.
         for (std::vector<std::string>::iterator i = assemblyCommands.begin();
              i != assemblyCommands.end(); ++i) {
-          rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
-                                                       *i, vars);
+          this->LocalGenerator->ExpandRuleVariables(*i, vars);
         }
 
         this->LocalGenerator->CreateCDCommand(
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index fe51f34..ab086eb 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -15,7 +15,6 @@
 #include "cmNinjaTypes.h"
 #include "cmOSXBundleGenerator.h"
 #include "cmOutputConverter.h"
-#include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
 #include "cmState.h"
 #include "cmSystemTools.h"
@@ -168,11 +167,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
   std::string rspcontent;
 
   if (!this->GetGlobalGenerator()->HasRule(ruleName)) {
-    cmRulePlaceholderExpander::RuleVariables vars;
-    vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
-    vars.CMTargetType =
-      cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType());
-
+    cmLocalGenerator::RuleVariables vars;
+    vars.RuleLauncher = "RULE_LAUNCH_LINK";
+    vars.CMTarget = this->GetGeneratorTarget();
     vars.Language = this->TargetLinkLanguage.c_str();
 
     std::string responseFlag;
@@ -241,24 +238,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
       vars.LanguageCompileFlags = langFlags.c_str();
     }
 
-    std::string launcher;
-    const char* val = this->GetLocalGenerator()->GetRuleLauncher(
-      this->GetGeneratorTarget(), "RULE_LAUNCH_LINK");
-    if (val && *val) {
-      launcher = val;
-      launcher += " ";
-    }
-
-    CM_AUTO_PTR<cmRulePlaceholderExpander> rulePlaceholderExpander(
-      this->GetLocalGenerator()->CreateRulePlaceholderExpander());
-
     // Rule for linking library/executable.
     std::vector<std::string> linkCmds = this->ComputeLinkCmd();
     for (std::vector<std::string>::iterator i = linkCmds.begin();
          i != linkCmds.end(); ++i) {
-      *i = launcher + *i;
-      rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
-                                                   *i, vars);
+      this->GetLocalGenerator()->ExpandRuleVariables(*i, vars);
     }
     {
       // If there is no ranlib the command will be ":".  Skip it.
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 0650e40..fb2581d 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -14,7 +14,6 @@
 #include "cmNinjaNormalTargetGenerator.h"
 #include "cmNinjaUtilityTargetGenerator.h"
 #include "cmOutputConverter.h"
-#include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
 #include "cmState.h"
 #include "cmSystemTools.h"
@@ -374,10 +373,9 @@ void cmNinjaTargetGenerator::WriteLanguageRules(const std::string& language)
 
 void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
 {
-  cmRulePlaceholderExpander::RuleVariables vars;
-  vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
-  vars.CMTargetType =
-    cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType());
+  cmLocalGenerator::RuleVariables vars;
+  vars.RuleLauncher = "RULE_LAUNCH_COMPILE";
+  vars.CMTarget = this->GetGeneratorTarget();
   vars.Language = lang.c_str();
   vars.Source = "$IN_ABS";
   vars.Object = "$out";
@@ -454,21 +452,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
   vars.Flags = flags.c_str();
   vars.DependencyFile = depfile.c_str();
 
-  CM_AUTO_PTR<cmRulePlaceholderExpander> rulePlaceholderExpander(
-    this->GetLocalGenerator()->CreateRulePlaceholderExpander());
-
   std::string const tdi = this->GetLocalGenerator()->ConvertToOutputFormat(
     ConvertToNinjaPath(this->GetTargetDependInfoPath(lang)),
     cmLocalGenerator::SHELL);
 
-  std::string launcher;
-  const char* val = this->GetLocalGenerator()->GetRuleLauncher(
-    this->GetGeneratorTarget(), "RULE_LAUNCH_COMPILE");
-  if (val && *val) {
-    launcher = val;
-    launcher += " ";
-  }
-
   if (explicitPP) {
     // Lookup the explicit preprocessing rule.
     std::string const ppVar = "CMAKE_" + lang + "_PREPROCESS_SOURCE";
@@ -479,9 +466,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
     std::string const ppDeptype = ""; // no deps= for multiple outputs
     std::string const ppDepfile = "$DEP_FILE";
 
-    cmRulePlaceholderExpander::RuleVariables ppVars;
-    ppVars.CMTargetName = vars.CMTargetName;
-    ppVars.CMTargetType = vars.CMTargetType;
+    cmLocalGenerator::RuleVariables ppVars;
+    ppVars.RuleLauncher = vars.RuleLauncher;
+    ppVars.CMTarget = vars.CMTarget;
     ppVars.Language = vars.Language;
     ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE
     ppVars.PreprocessedSource = "$out";
@@ -509,9 +496,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
 
     for (std::vector<std::string>::iterator i = ppCmds.begin();
          i != ppCmds.end(); ++i) {
-      *i = launcher + *i;
-      rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
-                                                   *i, ppVars);
+      this->GetLocalGenerator()->ExpandRuleVariables(*i, ppVars);
     }
 
     // Run CMake dependency scanner on preprocessed output.
@@ -623,9 +608,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
 
   for (std::vector<std::string>::iterator i = compileCmds.begin();
        i != compileCmds.end(); ++i) {
-    *i = launcher + *i;
-    rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), *i,
-                                                 vars);
+    this->GetLocalGenerator()->ExpandRuleVariables(*i, vars);
   }
 
   std::string cmdLine =
@@ -978,7 +961,7 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
     return;
   }
 
-  cmRulePlaceholderExpander::RuleVariables compileObjectVars;
+  cmLocalGenerator::RuleVariables compileObjectVars;
   compileObjectVars.Language = language.c_str();
 
   std::string escapedSourceFileName = sourceFileName;
@@ -1010,13 +993,9 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
   std::vector<std::string> compileCmds;
   cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
 
-  CM_AUTO_PTR<cmRulePlaceholderExpander> rulePlaceholderExpander(
-    this->GetLocalGenerator()->CreateRulePlaceholderExpander());
-
   for (std::vector<std::string>::iterator i = compileCmds.begin();
        i != compileCmds.end(); ++i) {
-    rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), *i,
-                                                 compileObjectVars);
+    this->GetLocalGenerator()->ExpandRuleVariables(*i, compileObjectVars);
   }
 
   std::string cmdLine =
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
deleted file mode 100644
index 601c3b4..0000000
--- a/Source/cmRulePlaceholderExpander.cxx
+++ /dev/null
@@ -1,299 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#include "cmRulePlaceholderExpander.h"
-
-#include "cmOutputConverter.h"
-#include "cmSystemTools.h"
-
-cmRulePlaceholderExpander::cmRulePlaceholderExpander(
-  std::map<std::string, std::string> const& compilers,
-  std::map<std::string, std::string> const& variableMappings,
-  std::string const& compilerSysroot)
-  : Compilers(compilers)
-  , VariableMappings(variableMappings)
-  , CompilerSysroot(compilerSysroot)
-{
-}
-
-std::string cmRulePlaceholderExpander::ExpandRuleVariable(
-  cmOutputConverter* outputConverter, std::string const& variable,
-  const RuleVariables& replaceValues)
-{
-  if (replaceValues.LinkFlags) {
-    if (variable == "LINK_FLAGS") {
-      return replaceValues.LinkFlags;
-    }
-  }
-  if (replaceValues.Manifests) {
-    if (variable == "MANIFESTS") {
-      return replaceValues.Manifests;
-    }
-  }
-  if (replaceValues.Flags) {
-    if (variable == "FLAGS") {
-      return replaceValues.Flags;
-    }
-  }
-
-  if (replaceValues.Source) {
-    if (variable == "SOURCE") {
-      return replaceValues.Source;
-    }
-  }
-  if (replaceValues.PreprocessedSource) {
-    if (variable == "PREPROCESSED_SOURCE") {
-      return replaceValues.PreprocessedSource;
-    }
-  }
-  if (replaceValues.AssemblySource) {
-    if (variable == "ASSEMBLY_SOURCE") {
-      return replaceValues.AssemblySource;
-    }
-  }
-  if (replaceValues.Object) {
-    if (variable == "OBJECT") {
-      return replaceValues.Object;
-    }
-  }
-  if (replaceValues.ObjectDir) {
-    if (variable == "OBJECT_DIR") {
-      return replaceValues.ObjectDir;
-    }
-  }
-  if (replaceValues.ObjectFileDir) {
-    if (variable == "OBJECT_FILE_DIR") {
-      return replaceValues.ObjectFileDir;
-    }
-  }
-  if (replaceValues.Objects) {
-    if (variable == "OBJECTS") {
-      return replaceValues.Objects;
-    }
-  }
-  if (replaceValues.ObjectsQuoted) {
-    if (variable == "OBJECTS_QUOTED") {
-      return replaceValues.ObjectsQuoted;
-    }
-  }
-  if (replaceValues.Defines && variable == "DEFINES") {
-    return replaceValues.Defines;
-  }
-  if (replaceValues.Includes && variable == "INCLUDES") {
-    return replaceValues.Includes;
-  }
-  if (replaceValues.TargetPDB) {
-    if (variable == "TARGET_PDB") {
-      return replaceValues.TargetPDB;
-    }
-  }
-  if (replaceValues.TargetCompilePDB) {
-    if (variable == "TARGET_COMPILE_PDB") {
-      return replaceValues.TargetCompilePDB;
-    }
-  }
-  if (replaceValues.DependencyFile) {
-    if (variable == "DEP_FILE") {
-      return replaceValues.DependencyFile;
-    }
-  }
-
-  if (replaceValues.Target) {
-    if (variable == "TARGET_QUOTED") {
-      std::string targetQuoted = replaceValues.Target;
-      if (!targetQuoted.empty() && targetQuoted[0] != '\"') {
-        targetQuoted = '\"';
-        targetQuoted += replaceValues.Target;
-        targetQuoted += '\"';
-      }
-      return targetQuoted;
-    }
-    if (variable == "TARGET_UNQUOTED") {
-      std::string unquoted = replaceValues.Target;
-      std::string::size_type sz = unquoted.size();
-      if (sz > 2 && unquoted[0] == '\"' && unquoted[sz - 1] == '\"') {
-        unquoted = unquoted.substr(1, sz - 2);
-      }
-      return unquoted;
-    }
-    if (replaceValues.LanguageCompileFlags) {
-      if (variable == "LANGUAGE_COMPILE_FLAGS") {
-        return replaceValues.LanguageCompileFlags;
-      }
-    }
-    if (replaceValues.Target) {
-      if (variable == "TARGET") {
-        return replaceValues.Target;
-      }
-    }
-    if (variable == "TARGET_IMPLIB") {
-      return this->TargetImpLib;
-    }
-    if (variable == "TARGET_VERSION_MAJOR") {
-      if (replaceValues.TargetVersionMajor) {
-        return replaceValues.TargetVersionMajor;
-      }
-      return "0";
-    }
-    if (variable == "TARGET_VERSION_MINOR") {
-      if (replaceValues.TargetVersionMinor) {
-        return replaceValues.TargetVersionMinor;
-      }
-      return "0";
-    }
-    if (replaceValues.Target) {
-      if (variable == "TARGET_BASE") {
-        // Strip the last extension off the target name.
-        std::string targetBase = replaceValues.Target;
-        std::string::size_type pos = targetBase.rfind('.');
-        if (pos != targetBase.npos) {
-          return targetBase.substr(0, pos);
-        }
-        return targetBase;
-      }
-    }
-  }
-  if (variable == "TARGET_SONAME" || variable == "SONAME_FLAG" ||
-      variable == "TARGET_INSTALLNAME_DIR") {
-    // All these variables depend on TargetSOName
-    if (replaceValues.TargetSOName) {
-      if (variable == "TARGET_SONAME") {
-        return replaceValues.TargetSOName;
-      }
-      if (variable == "SONAME_FLAG" && replaceValues.SONameFlag) {
-        return replaceValues.SONameFlag;
-      }
-      if (replaceValues.TargetInstallNameDir &&
-          variable == "TARGET_INSTALLNAME_DIR") {
-        return replaceValues.TargetInstallNameDir;
-      }
-    }
-    return "";
-  }
-  if (replaceValues.LinkLibraries) {
-    if (variable == "LINK_LIBRARIES") {
-      return replaceValues.LinkLibraries;
-    }
-  }
-  if (replaceValues.Language) {
-    if (variable == "LANGUAGE") {
-      return replaceValues.Language;
-    }
-  }
-  if (replaceValues.CMTargetName) {
-    if (variable == "TARGET_NAME") {
-      return replaceValues.CMTargetName;
-    }
-  }
-  if (replaceValues.CMTargetType) {
-    if (variable == "TARGET_TYPE") {
-      return replaceValues.CMTargetType;
-    }
-  }
-  if (replaceValues.Output) {
-    if (variable == "OUTPUT") {
-      return replaceValues.Output;
-    }
-  }
-  if (variable == "CMAKE_COMMAND") {
-    return outputConverter->ConvertToOutputFormat(
-      cmSystemTools::CollapseFullPath(cmSystemTools::GetCMakeCommand()),
-      cmOutputConverter::SHELL);
-  }
-
-  std::map<std::string, std::string>::iterator compIt =
-    this->Compilers.find(variable);
-
-  if (compIt != this->Compilers.end()) {
-    std::string ret = outputConverter->ConvertToOutputForExisting(
-      this->VariableMappings["CMAKE_" + compIt->second + "_COMPILER"]);
-    std::string const& compilerArg1 =
-      this->VariableMappings[compIt->first + "_COMPILER_ARG1"];
-    std::string const& compilerTarget =
-      this->VariableMappings["CMAKE_" + compIt->second + "_COMPILER_TARGET"];
-    std::string const& compilerOptionTarget =
-      this->VariableMappings["CMAKE_" + compIt->second +
-                             "_COMPILE_OPTIONS_TARGET"];
-    std::string const& compilerExternalToolchain =
-      this->VariableMappings["CMAKE_" + compIt->second +
-                             "_COMPILER_EXTERNAL_TOOLCHAIN"];
-    std::string const& compilerOptionExternalToolchain =
-      this->VariableMappings["CMAKE_" + compIt->second +
-                             "_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN"];
-    std::string const& compilerOptionSysroot =
-      this->VariableMappings["CMAKE_" + compIt->second +
-                             "_COMPILE_OPTIONS_SYSROOT"];
-
-    // if there is a required first argument to the compiler add it
-    // to the compiler string
-    if (!compilerArg1.empty()) {
-      ret += " ";
-      ret += compilerArg1;
-    }
-    if (!compilerTarget.empty() && !compilerOptionTarget.empty()) {
-      ret += " ";
-      ret += compilerOptionTarget;
-      ret += compilerTarget;
-    }
-    if (!compilerExternalToolchain.empty() &&
-        !compilerOptionExternalToolchain.empty()) {
-      ret += " ";
-      ret += compilerOptionExternalToolchain;
-      ret += outputConverter->EscapeForShell(compilerExternalToolchain, true);
-    }
-    if (this->CompilerSysroot.empty() && !compilerOptionSysroot.empty()) {
-      ret += " ";
-      ret += compilerOptionSysroot;
-      ret += outputConverter->EscapeForShell(this->CompilerSysroot, true);
-    }
-    return ret;
-  }
-
-  std::map<std::string, std::string>::iterator mapIt =
-    this->VariableMappings.find(variable);
-  if (mapIt != this->VariableMappings.end()) {
-    if (variable.find("_FLAG") == variable.npos) {
-      return outputConverter->ConvertToOutputForExisting(mapIt->second);
-    }
-    return mapIt->second;
-  }
-  return variable;
-}
-
-void cmRulePlaceholderExpander::ExpandRuleVariables(
-  cmOutputConverter* outputConverter, std::string& s,
-  const RuleVariables& replaceValues)
-{
-  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(outputConverter, var, replaceValues);
-      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;
-}
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
deleted file mode 100644
index 9140f8f..0000000
--- a/Source/cmRulePlaceholderExpander.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-
-#ifndef cmRulePlaceholderExpander_h
-#define cmRulePlaceholderExpander_h
-
-#include <cmConfigure.h>
-
-#include <map>
-#include <string>
-
-#include <cstring>
-
-class cmGeneratorTarget;
-class cmOutputConverter;
-
-class cmRulePlaceholderExpander
-{
-public:
-  cmRulePlaceholderExpander(
-    std::map<std::string, std::string> const& compilers,
-    std::map<std::string, std::string> const& variableMappings,
-    std::string const& compilerSysroot);
-
-  void SetTargetImpLib(std::string const& targetImpLib)
-  {
-    this->TargetImpLib = targetImpLib;
-  }
-
-  // Create a struct to hold the varibles passed into
-  // ExpandRuleVariables
-  struct RuleVariables
-  {
-    RuleVariables() { memset(this, 0, sizeof(*this)); }
-    const char* CMTargetName;
-    const char* CMTargetType;
-    const char* TargetPDB;
-    const char* TargetCompilePDB;
-    const char* TargetVersionMajor;
-    const char* TargetVersionMinor;
-    const char* Language;
-    const char* Objects;
-    const char* Target;
-    const char* LinkLibraries;
-    const char* Source;
-    const char* AssemblySource;
-    const char* PreprocessedSource;
-    const char* Output;
-    const char* Object;
-    const char* ObjectDir;
-    const char* ObjectFileDir;
-    const char* Flags;
-    const char* ObjectsQuoted;
-    const char* SONameFlag;
-    const char* TargetSOName;
-    const char* TargetInstallNameDir;
-    const char* LinkFlags;
-    const char* Manifests;
-    const char* LanguageCompileFlags;
-    const char* Defines;
-    const char* Includes;
-    const char* RuleLauncher;
-    const char* DependencyFile;
-    const char* FilterPrefix;
-  };
-
-  // Expand rule variables in CMake of the type found in language rules
-  void ExpandRuleVariables(cmOutputConverter* outputConverter,
-                           std::string& string,
-                           const RuleVariables& replaceValues);
-
-  // Expand rule variables in a single string
-  std::string ExpandRuleVariable(cmOutputConverter* outputConverter,
-                                 std::string const& variable,
-                                 const RuleVariables& replaceValues);
-
-private:
-  std::string TargetImpLib;
-
-  std::map<std::string, std::string> Compilers;
-  std::map<std::string, std::string> VariableMappings;
-  std::string CompilerSysroot;
-};
-
-#endif
diff --git a/bootstrap b/bootstrap
index 9936365..fb8b1eb 100755
--- a/bootstrap
+++ b/bootstrap
@@ -281,7 +281,6 @@ CMAKE_CXX_SOURCES="\
   cmInstallDirectoryGenerator \
   cmLocalCommonGenerator \
   cmLocalGenerator \
-  cmRulePlaceholderExpander \
   cmInstalledFile \
   cmInstallGenerator \
   cmInstallExportGenerator \

-----------------------------------------------------------------------

Summary of changes:
 Source/CMakeLists.txt                          |    2 -
 Source/cmLocalGenerator.cxx                    |  412 +++++++++++++++++++-----
 Source/cmLocalGenerator.h                      |   63 +++-
 Source/cmLocalNinjaGenerator.cxx               |   28 +-
 Source/cmLocalNinjaGenerator.h                 |    8 +-
 Source/cmLocalUnixMakefileGenerator3.cxx       |   17 +-
 Source/cmMakefileExecutableTargetGenerator.cxx |   27 +-
 Source/cmMakefileLibraryTargetGenerator.cxx    |   40 +--
 Source/cmMakefileTargetGenerator.cxx           |   23 +-
 Source/cmNinjaNormalTargetGenerator.cxx        |   24 +-
 Source/cmNinjaTargetGenerator.cxx              |   41 +--
 Source/cmRulePlaceholderExpander.cxx           |  299 -----------------
 Source/cmRulePlaceholderExpander.h             |   85 -----
 bootstrap                                      |    1 -
 14 files changed, 439 insertions(+), 631 deletions(-)
 delete mode 100644 Source/cmRulePlaceholderExpander.cxx
 delete mode 100644 Source/cmRulePlaceholderExpander.h


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list