diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 42e4b6307b2e8ae6d98378c88a5ee3e983eecdc1..6dd90c85e39d4cedb019421e448e33be4a64596b 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -561,7 +561,8 @@ cmState::Snapshot cmLocalGenerator::GetStateSnapshot() const
 }
 
 std::string cmLocalGenerator::ExpandRuleVariable(
-  std::string const& variable, const RuleVariables& replaceValues)
+  cmOutputConverter* outputConverter, std::string const& variable,
+  const RuleVariables& replaceValues)
 {
   if (replaceValues.LinkFlags) {
     if (variable == "LINK_FLAGS") {
@@ -737,7 +738,7 @@ std::string cmLocalGenerator::ExpandRuleVariable(
     }
   }
   if (variable == "CMAKE_COMMAND") {
-    return this->ConvertToOutputFormat(
+    return outputConverter->ConvertToOutputFormat(
       cmSystemTools::CollapseFullPath(cmSystemTools::GetCMakeCommand()),
       SHELL);
   }
@@ -780,12 +781,12 @@ std::string cmLocalGenerator::ExpandRuleVariable(
         !compilerOptionExternalToolchain.empty()) {
       ret += " ";
       ret += compilerOptionExternalToolchain;
-      ret += this->EscapeForShell(compilerExternalToolchain, true);
+      ret += outputConverter->EscapeForShell(compilerExternalToolchain, true);
     }
     if (!this->CompilerSysroot.empty() && !compilerOptionSysroot.empty()) {
       ret += " ";
       ret += compilerOptionSysroot;
-      ret += this->EscapeForShell(this->CompilerSysroot, true);
+      ret += outputConverter->EscapeForShell(this->CompilerSysroot, true);
     }
     return ret;
   }
@@ -794,14 +795,15 @@ std::string cmLocalGenerator::ExpandRuleVariable(
     this->VariableMappings.find(variable);
   if (mapIt != this->VariableMappings.end()) {
     if (variable.find("_FLAG") == variable.npos) {
-      return this->ConvertToOutputForExisting(mapIt->second);
+      return outputConverter->ConvertToOutputForExisting(mapIt->second);
     }
     return mapIt->second;
   }
   return variable;
 }
 
-void cmLocalGenerator::ExpandRuleVariables(std::string& s,
+void cmLocalGenerator::ExpandRuleVariables(cmOutputConverter* outputConverter,
+                                           std::string& s,
                                            const RuleVariables& replaceValues)
 {
   std::string::size_type start = s.find('<');
@@ -825,7 +827,8 @@ void cmLocalGenerator::ExpandRuleVariables(std::string& s,
     } else {
       // extract the var
       std::string var = s.substr(start + 1, end - start - 1);
-      std::string replace = this->ExpandRuleVariable(var, replaceValues);
+      std::string replace =
+        this->ExpandRuleVariable(outputConverter, var, replaceValues);
       expandedInput += s.substr(pos, start - pos);
       expandedInput += replace;
       // move to next one
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index d54fbffae0bd179b8b347c04668309a2f64d4a91..7359f50fb1828b3e611b821a18ec3b835e20d502 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -347,7 +347,8 @@ public:
   void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles);
 
   // Expand rule variables in CMake of the type found in language rules
-  void ExpandRuleVariables(std::string& string,
+  void ExpandRuleVariables(cmOutputConverter* outputConverter,
+                           std::string& string,
                            const RuleVariables& replaceValues);
 
   const char* GetRuleLauncher(cmGeneratorTarget* target,
@@ -361,7 +362,8 @@ protected:
                            std::string& frameworkPath, std::string& linkPath);
 
   // Expand rule variables in a single string
-  std::string ExpandRuleVariable(std::string const& variable,
+  std::string ExpandRuleVariable(cmOutputConverter* outputConverter,
+                                 std::string const& variable,
                                  const RuleVariables& replaceValues);
 
   // Handle old-style install rules stored in the targets.
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index ea711c0c57760e635c26b9ed2bf8f73a806f487c..05596f89ff6c5b718f4d3588956d7e66215284a2 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -494,7 +494,7 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
   std::string launcher = property_value;
   launcher += " ";
 
-  this->ExpandRuleVariables(launcher, vars);
+  this->ExpandRuleVariables(this, launcher, vars);
   if (!launcher.empty()) {
     launcher += " ";
   }
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 92b58bace411fb99348a4aa3af4314fd65271f2d..a4c73dd46759d627b2f83f4f282ffae267a8f3d6 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1005,7 +1005,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
 
         launcher = val;
         launcher += " ";
-        this->ExpandRuleVariables(launcher, vars);
+        this->ExpandRuleVariables(this, launcher, vars);
         if (!launcher.empty()) {
           launcher += " ";
         }
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index da29b60791e9290a3ba5444fa85df7a006692faf..92d6185c8f95ed42ac37d687c2bc8bcd5c22848d 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -396,7 +396,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
     for (std::vector<std::string>::iterator i = real_link_commands.begin();
          i != real_link_commands.end(); ++i) {
       *i = launcher + *i;
-      this->LocalGenerator->ExpandRuleVariables(*i, vars);
+      this->LocalGenerator->ExpandRuleVariables(this->LocalGenerator, *i,
+                                                vars);
     }
     this->LocalGenerator->TargetImplib = "";
 
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 5700c627c8df4354713f09fc0d86b5135ab12f16..0566c1bf4f7adf7200d756b6d03b70ba481c7d6c 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -619,7 +619,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
                archiveCreateCommands.begin();
              i != archiveCreateCommands.end(); ++i) {
           std::string cmd = launcher + *i;
-          this->LocalGenerator->ExpandRuleVariables(cmd, vars);
+          this->LocalGenerator->ExpandRuleVariables(this->LocalGenerator, cmd,
+                                                    vars);
           real_link_commands.push_back(cmd);
         }
       }
@@ -630,7 +631,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
                archiveAppendCommands.begin();
              i != archiveAppendCommands.end(); ++i) {
           std::string cmd = launcher + *i;
-          this->LocalGenerator->ExpandRuleVariables(cmd, vars);
+          this->LocalGenerator->ExpandRuleVariables(this->LocalGenerator, cmd,
+                                                    vars);
           real_link_commands.push_back(cmd);
         }
       }
@@ -640,7 +642,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
              archiveFinishCommands.begin();
            i != archiveFinishCommands.end(); ++i) {
         std::string cmd = launcher + *i;
-        this->LocalGenerator->ExpandRuleVariables(cmd, vars);
+        this->LocalGenerator->ExpandRuleVariables(this->LocalGenerator, cmd,
+                                                  vars);
         // If there is no ranlib the command will be ":".  Skip it.
         if (!cmd.empty() && cmd[0] != ':') {
           real_link_commands.push_back(cmd);
@@ -663,7 +666,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
       for (std::vector<std::string>::iterator i = real_link_commands.begin();
            i != real_link_commands.end(); ++i) {
         *i = launcher + *i;
-        this->LocalGenerator->ExpandRuleVariables(*i, vars);
+        this->LocalGenerator->ExpandRuleVariables(this->LocalGenerator, *i,
+                                                  vars);
       }
     }
     this->LocalGenerator->TargetImplib = "";
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 84ae72685f64934a789c79643c19ba0610dbd83e..77643d199708e1a521762cef7a833c62cbbeda1a 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -600,7 +600,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
     if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") &&
         lang_can_export_cmds && compileCommands.size() == 1) {
       std::string compileCommand = compileCommands[0];
-      this->LocalGenerator->ExpandRuleVariables(compileCommand, vars);
+      this->LocalGenerator->ExpandRuleVariables(this->LocalGenerator,
+                                                compileCommand, vars);
       std::string workingDirectory = cmSystemTools::CollapseFullPath(
         this->LocalGenerator->GetCurrentBinaryDirectory());
       compileCommand.replace(compileCommand.find(langFlags), langFlags.size(),
@@ -659,7 +660,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
     // Expand placeholders in the commands.
     for (std::vector<std::string>::iterator i = compileCommands.begin();
          i != compileCommands.end(); ++i) {
-      this->LocalGenerator->ExpandRuleVariables(*i, vars);
+      this->LocalGenerator->ExpandRuleVariables(this->LocalGenerator, *i,
+                                                vars);
     }
 
     // Change the command working directory to the local build tree.
@@ -722,7 +724,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
         // Expand placeholders in the commands.
         for (std::vector<std::string>::iterator i = preprocessCommands.begin();
              i != preprocessCommands.end(); ++i) {
-          this->LocalGenerator->ExpandRuleVariables(*i, vars);
+          this->LocalGenerator->ExpandRuleVariables(this->LocalGenerator, *i,
+                                                    vars);
         }
 
         this->LocalGenerator->CreateCDCommand(
@@ -769,7 +772,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
         // Expand placeholders in the commands.
         for (std::vector<std::string>::iterator i = assemblyCommands.begin();
              i != assemblyCommands.end(); ++i) {
-          this->LocalGenerator->ExpandRuleVariables(*i, vars);
+          this->LocalGenerator->ExpandRuleVariables(this->LocalGenerator, *i,
+                                                    vars);
         }
 
         this->LocalGenerator->CreateCDCommand(
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 64c434a61e9419013533db4800f23cbf8ec7ffc4..154f3c30a5f53d55aaf2a669468020051067de73 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -250,7 +250,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
     for (std::vector<std::string>::iterator i = linkCmds.begin();
          i != linkCmds.end(); ++i) {
       *i = launcher + *i;
-      this->GetLocalGenerator()->ExpandRuleVariables(*i, vars);
+      this->GetLocalGenerator()->ExpandRuleVariables(this->GetLocalGenerator(),
+                                                     *i, vars);
     }
     {
       // If there is no ranlib the command will be ":".  Skip it.
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index f85ea81fb8b745204511aae8f91975bc7d611644..8ae055fb18c3d0273aef79bac81c59083cd19ae3 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -503,7 +503,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
     for (std::vector<std::string>::iterator i = ppCmds.begin();
          i != ppCmds.end(); ++i) {
       *i = launcher + *i;
-      this->GetLocalGenerator()->ExpandRuleVariables(*i, ppVars);
+      this->GetLocalGenerator()->ExpandRuleVariables(this->GetLocalGenerator(),
+                                                     *i, ppVars);
     }
 
     // Run CMake dependency scanner on preprocessed output.
@@ -616,7 +617,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
   for (std::vector<std::string>::iterator i = compileCmds.begin();
        i != compileCmds.end(); ++i) {
     *i = launcher + *i;
-    this->GetLocalGenerator()->ExpandRuleVariables(*i, vars);
+    this->GetLocalGenerator()->ExpandRuleVariables(this->GetLocalGenerator(),
+                                                   *i, vars);
   }
 
   std::string cmdLine =
@@ -1003,7 +1005,8 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
 
   for (std::vector<std::string>::iterator i = compileCmds.begin();
        i != compileCmds.end(); ++i) {
-    this->GetLocalGenerator()->ExpandRuleVariables(*i, compileObjectVars);
+    this->GetLocalGenerator()->ExpandRuleVariables(this->GetLocalGenerator(),
+                                                   *i, compileObjectVars);
   }
 
   std::string cmdLine =