소스 검색

Merge topic 'target-file-dir-refactoring'

c95a8348ce cmLocalGenerator: add an override for CMakeFiles-using paths
35d32b8741 cmLocalGenerator: move the `CMakeFiles` subdir from the target to output root
bc19e42461 generators: use `GetObjectOutputRoot` to compute target directories
b1d9a5313c cmLocalGenerator: add a `GetObjectOutputRoot` method
b82a74d918 generators: use GetSupportDirectory() in more places
36f85ee0cc cmGeneratorTarget: query the local generator for the target directory
ff5d7bc301 cmLocalXCodeGenerator: use a per-target directory
aafd771529 cmNinjaTargetGenerator: use `GetObjectFileDir` where possible
...

Acked-by: Kitware Robot <[email protected]>
Merge-request: !10812
Brad King 8 달 전
부모
커밋
2cf735a5dc
35개의 변경된 파일200개의 추가작업 그리고 236개의 파일을 삭제
  1. 1 2
      Source/cmCommonTargetGenerator.cxx
  2. 4 6
      Source/cmExtraCodeBlocksGenerator.cxx
  3. 1 2
      Source/cmExtraCodeBlocksGenerator.h
  4. 2 2
      Source/cmExtraEclipseCDT4Generator.cxx
  5. 17 10
      Source/cmGeneratorTarget.cxx
  6. 1 0
      Source/cmGeneratorTarget.h
  7. 1 2
      Source/cmGeneratorTarget_IncludeDirectories.cxx
  8. 9 18
      Source/cmGhsMultiTargetGenerator.cxx
  9. 2 2
      Source/cmGlobalGenerator.cxx
  10. 1 3
      Source/cmGlobalGhsMultiGenerator.cxx
  11. 2 3
      Source/cmGlobalNinjaGenerator.cxx
  12. 1 3
      Source/cmGlobalUnixMakefileGenerator3.cxx
  13. 6 1
      Source/cmGlobalVisualStudio7Generator.cxx
  14. 1 11
      Source/cmGlobalVisualStudioGenerator.cxx
  15. 1 3
      Source/cmGlobalXCodeGenerator.cxx
  16. 1 1
      Source/cmInstallCxxModuleBmiGenerator.cxx
  17. 12 0
      Source/cmLocalCommonGenerator.cxx
  18. 3 0
      Source/cmLocalCommonGenerator.h
  19. 35 18
      Source/cmLocalGenerator.cxx
  20. 5 0
      Source/cmLocalGenerator.h
  21. 1 2
      Source/cmLocalGhsMultiGenerator.cxx
  22. 1 14
      Source/cmLocalNinjaGenerator.cxx
  23. 0 3
      Source/cmLocalNinjaGenerator.h
  24. 8 22
      Source/cmLocalUnixMakefileGenerator3.cxx
  25. 0 3
      Source/cmLocalUnixMakefileGenerator3.h
  26. 6 7
      Source/cmLocalVisualStudio7Generator.cxx
  27. 10 0
      Source/cmLocalVisualStudioGenerator.cxx
  28. 3 0
      Source/cmLocalVisualStudioGenerator.h
  29. 2 3
      Source/cmLocalXCodeGenerator.cxx
  30. 19 18
      Source/cmMakefileTargetGenerator.cxx
  31. 6 4
      Source/cmNinjaNormalTargetGenerator.cxx
  32. 17 53
      Source/cmNinjaTargetGenerator.cxx
  33. 3 0
      Source/cmQtAutoGenInitializer.cxx
  34. 16 18
      Source/cmVisualStudio10TargetGenerator.cxx
  35. 2 2
      Tests/RunCMake/InstallParallel/RunCMakeTest.cmake

+ 1 - 2
Source/cmCommonTargetGenerator.cxx

@@ -196,8 +196,7 @@ cmCommonTargetGenerator::GetLinkedTargetDirectories(
             ((lang == "CXX"_s && linkee->HaveCxx20ModuleSources()) ||
              (lang == "Fortran"_s && linkee->HaveFortranSources(config)))) {
           cmLocalGenerator* lg = linkee->GetLocalGenerator();
-          std::string di = cmStrCat(lg->GetCurrentBinaryDirectory(), '/',
-                                    lg->GetTargetDirectory(linkee));
+          std::string di = linkee->GetSupportDirectory();
           if (lg->GetGlobalGenerator()->IsMultiConfig()) {
             di = cmStrCat(di, '/', config);
           }

+ 4 - 6
Source/cmExtraCodeBlocksGenerator.cxx

@@ -461,14 +461,13 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
 
 // Write a dummy file for OBJECT libraries, so C::B can reference some file
 std::string cmExtraCodeBlocksGenerator::CreateDummyTargetFile(
-  cmLocalGenerator* lg, cmGeneratorTarget* target) const
+  cmGeneratorTarget* target) const
 {
   // this file doesn't seem to be used by C::B in custom makefile mode,
   // but we generate a unique file for each OBJECT library so in case
   // C::B uses it in some way, the targets don't interfere with each other.
-  std::string filename = cmStrCat(lg->GetCurrentBinaryDirectory(), '/',
-                                  lg->GetTargetDirectory(target), '/',
-                                  target->GetName(), ".objlib");
+  std::string filename =
+    cmStrCat(target->GetSupportDirectory(), '/', target->GetName(), ".objlib");
   cmGeneratedFileStream fout(filename);
   if (fout) {
     /* clang-format off */
@@ -516,8 +515,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(
     std::string buildType = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
     std::string location;
     if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
-      location =
-        this->CreateDummyTargetFile(const_cast<cmLocalGenerator*>(lg), target);
+      location = this->CreateDummyTargetFile(target);
     } else {
       location = target->GetLocation(buildType);
     }

+ 1 - 2
Source/cmExtraCodeBlocksGenerator.h

@@ -36,8 +36,7 @@ private:
 
   void CreateNewProjectFile(std::vector<cmLocalGenerator*> const& lgs,
                             std::string const& filename);
-  std::string CreateDummyTargetFile(cmLocalGenerator* lg,
-                                    cmGeneratorTarget* target) const;
+  std::string CreateDummyTargetFile(cmGeneratorTarget* target) const;
 
   std::string GetCBCompilerId(cmMakefile const* mf);
   int GetCBTargetType(cmGeneratorTarget* target);

+ 2 - 2
Source/cmExtraEclipseCDT4Generator.cxx

@@ -972,8 +972,8 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
               xml, "Build", make, buildArgs, virtDir, "", targetName.c_str());
 
             std::string cleanArgs =
-              cmStrCat("-E chdir \"", lgen->GetCurrentBinaryDirectory(),
-                       "\" \"", cmSystemTools::GetCMakeCommand(), "\" -P \"");
+              cmStrCat("-E chdir \"", lgen->GetObjectOutputRoot(), "\" \"",
+                       cmSystemTools::GetCMakeCommand(), "\" -P \"");
             cleanArgs += lgen->GetTargetDirectory(target.get());
             cleanArgs += "/cmake_clean.cmake\"";
             cmExtraEclipseCDT4Generator::AppendTarget(

+ 17 - 10
Source/cmGeneratorTarget.cxx

@@ -2851,7 +2851,7 @@ std::string cmGeneratorTarget::GetPchHeader(std::string const& config,
       { "OBJCXX", ".objcxx.hxx" }
     };
 
-    filename = generatorTarget->GetSupportDirectory();
+    filename = generatorTarget->GetCMFSupportDirectory();
 
     if (this->GetGlobalGenerator()->IsMultiConfig()) {
       filename = cmStrCat(filename, '/', config);
@@ -2944,7 +2944,8 @@ std::string cmGeneratorTarget::GetPchSource(std::string const& config,
         this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
     }
 
-    filename = cmStrCat(generatorTarget->GetSupportDirectory(), "/cmake_pch");
+    filename =
+      cmStrCat(generatorTarget->GetCMFSupportDirectory(), "/cmake_pch");
 
     // For GCC the source extension will be transformed into .h[xx].gch
     if (!this->Makefile->IsOn("CMAKE_LINK_PCH")) {
@@ -5217,14 +5218,20 @@ bool cmGeneratorTarget::NeedImportLibraryName(std::string const& config) const
 
 std::string cmGeneratorTarget::GetSupportDirectory() const
 {
-  std::string dir = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
-                             "/CMakeFiles/", this->GetName());
-#if defined(__VMS)
-  dir += "_dir";
-#else
-  dir += ".dir";
-#endif
-  return dir;
+  cmLocalGenerator* lg = this->GetLocalGenerator();
+  return cmStrCat(lg->GetObjectOutputRoot(), '/',
+                  lg->GetTargetDirectory(this));
+}
+
+std::string cmGeneratorTarget::GetCMFSupportDirectory() const
+{
+  cmLocalGenerator* lg = this->GetLocalGenerator();
+  if (!lg->AlwaysUsesCMFPaths()) {
+    return cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/",
+                    lg->GetTargetDirectory(this));
+  }
+  return cmStrCat(lg->GetObjectOutputRoot(), '/',
+                  lg->GetTargetDirectory(this));
 }
 
 bool cmGeneratorTarget::IsLinkable() const

+ 1 - 0
Source/cmGeneratorTarget.h

@@ -935,6 +935,7 @@ public:
 
   /** Get a build-tree directory in which to place target support files.  */
   std::string GetSupportDirectory() const;
+  std::string GetCMFSupportDirectory() const;
 
   /** Return whether this target may be used to link another target.  */
   bool IsLinkable() const;

+ 1 - 2
Source/cmGeneratorTarget_IncludeDirectories.cxx

@@ -81,8 +81,7 @@ std::string AddLangSpecificInterfaceIncludeDirectories(
             if (mode == IncludeDirectoryFallBack::BINARY) {
               value = lg->GetCurrentBinaryDirectory();
             } else if (mode == IncludeDirectoryFallBack::OBJECT) {
-              value = cmStrCat(lg->GetCurrentBinaryDirectory(), '/',
-                               lg->GetTargetDirectory(dependency));
+              value = dependency->GetSupportDirectory();
             }
           }
 

+ 9 - 18
Source/cmGhsMultiTargetGenerator.cxx

@@ -132,9 +132,8 @@ void cmGhsMultiTargetGenerator::GenerateTarget()
 
   // Open the target file in copy-if-different mode.
   std::string fproj =
-    cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
-             this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
-             '/', this->Name, cmGlobalGhsMultiGenerator::FILE_EXTENSION);
+    cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', this->Name,
+             cmGlobalGhsMultiGenerator::FILE_EXTENSION);
 
   // Tell the global generator the name of the project file
   this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME", fproj);
@@ -179,9 +178,7 @@ void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout,
    */
   if (this->TagType != GhsMultiGpj::SUBPROJECT) {
     // set target binary file destination
-    std::string binpath = cmStrCat(
-      this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
-      this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget));
+    std::string binpath = this->GeneratorTarget->GetSupportDirectory();
     outpath = cmSystemTools::RelativePath(
       binpath, this->GeneratorTarget->GetDirectory(config));
     /* clang-format off */
@@ -386,10 +383,8 @@ void cmGhsMultiTargetGenerator::WriteBuildEventsHelper(
   for (cmCustomCommand const& cc : ccv) {
     cmCustomCommandGenerator ccg(cc, this->ConfigName, this->LocalGenerator);
     // Open the filestream for this custom command
-    std::string fname =
-      cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
-               this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
-               '/', this->Name, '_', name, cmdcount++, fext);
+    std::string fname = cmStrCat(this->GeneratorTarget->GetSupportDirectory(),
+                                 '/', this->Name, '_', name, cmdcount++, fext);
 
     cmGeneratedFileStream f(fname);
     f.SetCopyIfDifferent(true);
@@ -604,10 +599,8 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
       cmsys::SystemTools::ReplaceString(gname, "\\", "_");
       std::string lpath =
         cmStrCat(gname, cmGlobalGhsMultiGenerator::FILE_EXTENSION);
-      std::string fpath = cmStrCat(
-        this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
-        this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), '/',
-        lpath);
+      std::string fpath =
+        cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', lpath);
       cmGeneratedFileStream* f = new cmGeneratedFileStream(fpath);
       f->SetCopyIfDifferent(true);
       gfiles.push_back(f);
@@ -700,10 +693,8 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
 
           // Open the filestream for this custom command
           std::string fname = cmStrCat(
-            this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
-            this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
-            '/', this->Name, "_cc", cmdcount++, '_',
-            (sf->GetLocation()).GetName(), fext);
+            this->GeneratorTarget->GetSupportDirectory(), '/', this->Name,
+            "_cc", cmdcount++, '_', (sf->GetLocation()).GetName(), fext);
 
           cmGeneratedFileStream f(fname);
           f.SetCopyIfDifferent(true);

+ 2 - 2
Source/cmGlobalGenerator.cxx

@@ -3636,7 +3636,7 @@ void cmGlobalGenerator::WriteSummary()
         continue;
       }
       this->WriteSummary(tgt.get());
-      fout << tgt->GetSupportDirectory() << '\n';
+      fout << tgt->GetCMFSupportDirectory() << '\n';
     }
   }
 }
@@ -3644,7 +3644,7 @@ void cmGlobalGenerator::WriteSummary()
 void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
 {
   // Place the labels file in a per-target support directory.
-  std::string dir = target->GetSupportDirectory();
+  std::string dir = target->GetCMFSupportDirectory();
   std::string file = cmStrCat(dir, "/Labels.txt");
   std::string json_file = cmStrCat(dir, "/Labels.json");
 

+ 1 - 3
Source/cmGlobalGhsMultiGenerator.cxx

@@ -69,9 +69,7 @@ void cmGlobalGhsMultiGenerator::ComputeTargetObjectDirectory(
   cmGeneratorTarget* gt) const
 {
   // Compute full path to object file directory for this target.
-  std::string dir =
-    cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/',
-             gt->LocalGenerator->GetTargetDirectory(gt), '/');
+  std::string dir = cmStrCat(gt->GetSupportDirectory(), '/');
   gt->ObjectDirectory = dir;
 }
 

+ 2 - 3
Source/cmGlobalNinjaGenerator.cxx

@@ -1052,9 +1052,8 @@ void cmGlobalNinjaGenerator::ComputeTargetObjectDirectory(
   cmGeneratorTarget* gt) const
 {
   // Compute full path to object file directory for this target.
-  std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(),
-                             '/', gt->LocalGenerator->GetTargetDirectory(gt),
-                             '/', this->GetCMakeCFGIntDir(), '/');
+  std::string dir =
+    cmStrCat(gt->GetSupportDirectory(), '/', this->GetCMakeCFGIntDir(), '/');
   gt->ObjectDirectory = dir;
 }
 

+ 1 - 3
Source/cmGlobalUnixMakefileGenerator3.cxx

@@ -81,9 +81,7 @@ void cmGlobalUnixMakefileGenerator3::ComputeTargetObjectDirectory(
   cmGeneratorTarget* gt) const
 {
   // Compute full path to object file directory for this target.
-  std::string dir =
-    cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/',
-             gt->LocalGenerator->GetTargetDirectory(gt), '/');
+  std::string dir = cmStrCat(gt->GetSupportDirectory(), '/');
   gt->ObjectDirectory = dir;
 }
 

+ 6 - 1
Source/cmGlobalVisualStudio7Generator.cxx

@@ -619,13 +619,18 @@ std::string cmGlobalVisualStudio7Generator::WriteUtilityDepend(
     "\t<Configurations>\n"
     ;
   /* clang-format on */
+  std::string intDirPrefix =
+    target->GetLocalGenerator()->MaybeRelativeToCurBinDir(
+      cmStrCat(target->GetSupportDirectory(), '\\'));
   for (std::string const& i : configs) {
+    std::string intDir = cmStrCat(intDir, i);
+
     /* clang-format off */
     fout <<
       "\t\t<Configuration\n"
       "\t\t\tName=\"" << i << "|Win32\"\n"
       "\t\t\tOutputDirectory=\"" << i << "\"\n"
-      "\t\t\tIntermediateDirectory=\"" << pname << ".dir\\" << i << "\"\n"
+      "\t\t\tIntermediateDirectory=\"" << intDir << "\"\n"
       "\t\t\tConfigurationType=\"10\"\n"
       "\t\t\tUseOfMFC=\"0\"\n"
       "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"FALSE\"\n"

+ 1 - 11
Source/cmGlobalVisualStudioGenerator.cxx

@@ -226,17 +226,7 @@ void cmGlobalVisualStudioGenerator::ComputeTargetObjectDirectory(
   cmGeneratorTarget* gt) const
 {
   std::string dir =
-    cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/');
-  std::string tgtDir = gt->LocalGenerator->GetTargetDirectory(gt);
-  if (!tgtDir.empty()) {
-    dir += tgtDir;
-    dir += '/';
-  }
-  char const* cd = this->GetCMakeCFGIntDir();
-  if (cd && *cd) {
-    dir += cd;
-    dir += '/';
-  }
+    cmStrCat(gt->GetSupportDirectory(), '/', this->GetCMakeCFGIntDir(), '/');
   gt->ObjectDirectory = dir;
 }
 

+ 1 - 3
Source/cmGlobalXCodeGenerator.cxx

@@ -5344,9 +5344,7 @@ void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
 std::string cmGlobalXCodeGenerator::ComputeInfoPListLocation(
   cmGeneratorTarget* target)
 {
-  std::string plist =
-    cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
-             "/CMakeFiles/", target->GetName(), ".dir/Info.plist");
+  std::string plist = cmStrCat(target->GetSupportDirectory(), "/Info.plist");
   return plist;
 }
 

+ 1 - 1
Source/cmInstallCxxModuleBmiGenerator.cxx

@@ -51,7 +51,7 @@ std::string cmInstallCxxModuleBmiGenerator::GetScriptLocation(
   if (config.empty()) {
     config_name = "noconfig";
   }
-  return cmStrCat(this->Target->GetSupportDirectory(),
+  return cmStrCat(this->Target->GetCMFSupportDirectory(),
                   "/install-cxx-module-bmi-", config_name, ".cmake");
 }
 

+ 12 - 0
Source/cmLocalCommonGenerator.cxx

@@ -89,6 +89,18 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags(
   return flags;
 }
 
+std::string cmLocalCommonGenerator::GetTargetDirectory(
+  cmGeneratorTarget const* target) const
+{
+  std::string dir = target->GetName();
+#if defined(__VMS)
+  dir += "_dir";
+#else
+  dir += ".dir";
+#endif
+  return dir;
+}
+
 void cmLocalCommonGenerator::ComputeObjectFilenames(
   std::map<cmSourceFile const*, std::string>& mapping,
   cmGeneratorTarget const* gt)

+ 3 - 0
Source/cmLocalCommonGenerator.h

@@ -34,6 +34,9 @@ public:
   std::string GetTargetFortranFlags(cmGeneratorTarget const* target,
                                     std::string const& config) override;
 
+  std::string GetTargetDirectory(
+    cmGeneratorTarget const* target) const override;
+
   void ComputeObjectFilenames(
     std::map<cmSourceFile const*, std::string>& mapping,
     cmGeneratorTarget const* gt = nullptr) override;

+ 35 - 18
Source/cmLocalGenerator.cxx

@@ -2941,8 +2941,8 @@ void cmLocalGenerator::CopyPchCompilePdb(
     cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
              target->GetName(), ".dir/");
 
-  std::string const copy_script = cmStrCat(
-    target_compile_pdb_dir, "copy_idb_pdb_", config.c_str(), ".cmake");
+  std::string const copy_script =
+    cmStrCat(target_compile_pdb_dir, "copy_idb_pdb_", config, ".cmake");
   cmGeneratedFileStream file(copy_script);
 
   file << "# CMake generated file\n";
@@ -3323,8 +3323,7 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
   }
 
   std::string filename_base =
-    cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/",
-             target->GetName(), ".dir/Unity/");
+    cmStrCat(target->GetCMFSupportDirectory(), "/Unity/");
 
   cmValue batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE");
   size_t const unityBatchSize = batchSizeString
@@ -4056,6 +4055,27 @@ bool cmLocalGeneratorCheckObjectName(std::string& objName,
 }
 }
 
+std::string cmLocalGenerator::CreateSafeObjectFileName(
+  std::string const& sin) const
+{
+  // Start with the original name.
+  std::string ssin = sin;
+
+  // Avoid full paths by removing leading slashes.
+  ssin.erase(0, ssin.find_first_not_of('/'));
+
+  // Avoid full paths by removing colons.
+  std::replace(ssin.begin(), ssin.end(), ':', '_');
+
+  // Avoid relative paths that go up the tree.
+  cmSystemTools::ReplaceString(ssin, "../", "__/");
+
+  // Avoid spaces.
+  std::replace(ssin.begin(), ssin.end(), ' ', '_');
+
+  return ssin;
+}
+
 std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName(
   std::string const& sin, std::string const& dir_max)
 {
@@ -4064,20 +4084,7 @@ std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName(
 
   // If no entry exists create one.
   if (it == this->UniqueObjectNamesMap.end()) {
-    // Start with the original name.
-    std::string ssin = sin;
-
-    // Avoid full paths by removing leading slashes.
-    ssin.erase(0, ssin.find_first_not_of('/'));
-
-    // Avoid full paths by removing colons.
-    std::replace(ssin.begin(), ssin.end(), ':', '_');
-
-    // Avoid relative paths that go up the tree.
-    cmSystemTools::ReplaceString(ssin, "../", "__/");
-
-    // Avoid spaces.
-    std::replace(ssin.begin(), ssin.end(), ' ', '_');
+    auto ssin = this->CreateSafeObjectFileName(sin);
 
     // Mangle the name if necessary.
     if (this->Makefile->IsOn("CMAKE_MANGLE_OBJECT_FILE_NAMES")) {
@@ -4279,6 +4286,16 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
   return this->CreateSafeUniqueObjectFileName(objectName, dir_max);
 }
 
+std::string cmLocalGenerator::GetObjectOutputRoot() const
+{
+  return cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles");
+}
+
+bool cmLocalGenerator::AlwaysUsesCMFPaths() const
+{
+  return true;
+}
+
 std::string cmLocalGenerator::GetSourceFileLanguage(cmSourceFile const& source)
 {
   return source.GetLanguage();

+ 5 - 0
Source/cmLocalGenerator.h

@@ -438,6 +438,9 @@ public:
   std::string const& GetCurrentBinaryDirectory() const;
   std::string const& GetCurrentSourceDirectory() const;
 
+  virtual std::string GetObjectOutputRoot() const;
+  virtual bool AlwaysUsesCMFPaths() const;
+
   /**
    * Generate a macOS application bundle Info.plist file.
    */
@@ -536,6 +539,8 @@ public:
   // (If CMP0157 is NEW, we can do a split build)
   bool IsSplitSwiftBuild() const;
 
+  std::string CreateSafeObjectFileName(std::string const& sin) const;
+
 protected:
   // The default implementation converts to a Windows shortpath to
   // help older toolchains handle spaces and such.  A generator may

+ 1 - 2
Source/cmLocalGhsMultiGenerator.cxx

@@ -44,8 +44,7 @@ void cmLocalGhsMultiGenerator::ComputeObjectFilenames(
   std::map<cmSourceFile const*, std::string>& mapping,
   cmGeneratorTarget const* gt)
 {
-  std::string dir_max = cmStrCat(this->GetCurrentBinaryDirectory(), '/',
-                                 this->GetTargetDirectory(gt), '/');
+  std::string dir_max = cmStrCat(gt->GetSupportDirectory(), '/');
 
   // Count the number of object files with each name.  Note that
   // filesystem may not be case sensitive.

+ 1 - 14
Source/cmLocalNinjaGenerator.cxx

@@ -75,7 +75,7 @@ void cmLocalNinjaGenerator::Generate()
   // Compute the path to use when referencing the current output
   // directory from the top output directory.
   this->HomeRelativeOutputPath =
-    this->MaybeRelativeToTopBinDir(this->GetCurrentBinaryDirectory());
+    this->MaybeRelativeToTopBinDir(this->GetObjectOutputRoot());
   if (this->HomeRelativeOutputPath == ".") {
     this->HomeRelativeOutputPath.clear();
   }
@@ -173,19 +173,6 @@ void cmLocalNinjaGenerator::Generate()
   }
 }
 
-// TODO: Picked up from cmLocalUnixMakefileGenerator3.  Refactor it.
-std::string cmLocalNinjaGenerator::GetTargetDirectory(
-  cmGeneratorTarget const* target) const
-{
-  std::string dir = cmStrCat("CMakeFiles/", target->GetName());
-#if defined(__VMS)
-  dir += "_dir";
-#else
-  dir += ".dir";
-#endif
-  return dir;
-}
-
 // Non-virtual public methods.
 
 cmGlobalNinjaGenerator const* cmLocalNinjaGenerator::GetGlobalNinjaGenerator()

+ 0 - 3
Source/cmLocalNinjaGenerator.h

@@ -49,9 +49,6 @@ public:
     cmBuildStep buildStep, cmGeneratorTarget const* target,
     std::string const& language) override;
 
-  std::string GetTargetDirectory(
-    cmGeneratorTarget const* target) const override;
-
   cmGlobalNinjaGenerator const* GetGlobalNinjaGenerator() const;
   cmGlobalNinjaGenerator* GetGlobalNinjaGenerator();
 

+ 8 - 22
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -224,8 +224,7 @@ void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles(
     std::vector<cmSourceFile const*> objectSources;
     gt->GetObjectSources(objectSources, this->GetConfigName());
     // Compute full path to object file directory for this target.
-    std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(),
-                               '/', this->GetTargetDirectory(gt.get()), '/');
+    std::string dir = cmStrCat(gt->GetSupportDirectory(), '/');
     // Compute the name of each object file.
     for (cmSourceFile const* sf : objectSources) {
       bool hasSourceExtension = true;
@@ -249,7 +248,7 @@ void cmLocalUnixMakefileGenerator3::GetIndividualFileTargets(
   for (auto const& localObjectFile : localObjectFiles) {
     targets.push_back(localObjectFile.first);
 
-    std::string::size_type dot_pos = localObjectFile.first.rfind(".");
+    std::string::size_type dot_pos = localObjectFile.first.rfind('.');
     std::string base = localObjectFile.first.substr(0, dot_pos);
     if (localObjectFile.second.HasPreprocessRule) {
       targets.push_back(base + ".i");
@@ -891,9 +890,7 @@ void cmLocalUnixMakefileGenerator3::WriteConvenienceRule(
 std::string cmLocalUnixMakefileGenerator3::GetRelativeTargetDirectory(
   cmGeneratorTarget const* target) const
 {
-  std::string dir =
-    cmStrCat(this->HomeRelativeOutputPath, this->GetTargetDirectory(target));
-  return dir;
+  return this->MaybeRelativeToTopBinDir(target->GetSupportDirectory());
 }
 
 void cmLocalUnixMakefileGenerator3::AppendFlags(
@@ -1120,9 +1117,8 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
   std::vector<std::string>& commands, std::set<std::string> const& files,
   cmGeneratorTarget* target, char const* filename)
 {
-  std::string currentBinDir = this->GetCurrentBinaryDirectory();
-  std::string cleanfile = cmStrCat(
-    currentBinDir, '/', this->GetTargetDirectory(target), "/cmake_clean");
+  std::string cleanfile =
+    cmStrCat(target->GetSupportDirectory(), "/cmake_clean");
   if (filename) {
     cleanfile += "_";
     cleanfile += filename;
@@ -1154,11 +1150,13 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
     std::set<std::string> languages;
     target->GetLanguages(
       languages, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+    auto langFileDir = cmSystemTools::GetFilenamePath(
+      this->MaybeRelativeToCurBinDir(cleanfile));
     /* clang-format off */
     fout << "\n"
             "# Per-language clean rules from dependency scanning.\n"
             "foreach(lang " << cmJoin(languages, " ") << ")\n"
-            "  include(" << this->GetTargetDirectory(target)
+            "  include(" << langFileDir
          << "/cmake_clean_${lang}.cmake OPTIONAL)\n"
             "endforeach()\n";
     /* clang-format on */
@@ -2246,18 +2244,6 @@ std::string cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
   return result;
 }
 
-std::string cmLocalUnixMakefileGenerator3::GetTargetDirectory(
-  cmGeneratorTarget const* target) const
-{
-  std::string dir = cmStrCat("CMakeFiles/", target->GetName());
-#if defined(__VMS)
-  dir += "_dir";
-#else
-  dir += ".dir";
-#endif
-  return dir;
-}
-
 cmLocalUnixMakefileGenerator3::ImplicitDependLanguageMap const&
 cmLocalUnixMakefileGenerator3::GetImplicitDepends(
   cmGeneratorTarget const* tgt, cmDependencyScannerKind scanner)

+ 0 - 3
Source/cmLocalUnixMakefileGenerator3.h

@@ -122,9 +122,6 @@ public:
   /** Get whether the makefile is to have color.  */
   bool GetColorMakefile() const { return this->ColorMakefile; }
 
-  std::string GetTargetDirectory(
-    cmGeneratorTarget const* target) const override;
-
   // create a command that cds to the start dir then runs the commands
   void CreateCDCommand(std::vector<std::string>& commands,
                        std::string const& targetDir,

+ 6 - 7
Source/cmLocalVisualStudio7Generator.cxx

@@ -771,8 +771,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
 
   // The intermediate directory name consists of a directory for the
   // target and a subdirectory for the configuration name.
-  std::string intermediateDir =
-    cmStrCat(this->GetTargetDirectory(target), '/', configName);
+  std::string intermediateDir = this->MaybeRelativeToCurBinDir(
+    cmStrCat(target->GetSupportDirectory(), '/', configName));
 
   if (target->GetType() < cmStateEnums::UTILITY) {
     std::string const& outDir =
@@ -1019,9 +1019,9 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
     case cmStateEnums::UNKNOWN_LIBRARY:
       break;
     case cmStateEnums::OBJECT_LIBRARY: {
-      std::string libpath =
-        cmStrCat(this->GetTargetDirectory(target), '/', configName, '/',
-                 target->GetName(), ".lib");
+      std::string libpath = this->MaybeRelativeToCurBinDir(
+        cmStrCat(target->GetSupportDirectory(), '/', configName, '/',
+                 target->GetName(), ".lib"));
       char const* tool =
         this->FortranProject ? "VFLibrarianTool" : "VCLibrarianTool";
       fout << "\t\t\t<Tool\n"
@@ -1661,8 +1661,7 @@ std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory(
   // files directory for any configuration.  This is used to construct
   // object file names that do not produce paths that are too long.
   std::string dir_max =
-    cmStrCat(this->GetCurrentBinaryDirectory(), '/',
-             this->GetTargetDirectory(target), '/', config_max, '/');
+    cmStrCat(target->GetSupportDirectory(), '/', config_max, '/');
   return dir_max;
 }
 

+ 10 - 0
Source/cmLocalVisualStudioGenerator.cxx

@@ -84,6 +84,16 @@ void cmLocalVisualStudioGenerator::ComputeObjectFilenames(
   }
 }
 
+std::string cmLocalVisualStudioGenerator::GetObjectOutputRoot() const
+{
+  return this->GetCurrentBinaryDirectory();
+}
+
+bool cmLocalVisualStudioGenerator::AlwaysUsesCMFPaths() const
+{
+  return false;
+}
+
 std::unique_ptr<cmCustomCommand>
 cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmGeneratorTarget* target,
                                                    std::string const& config,

+ 3 - 0
Source/cmLocalVisualStudioGenerator.h

@@ -51,6 +51,9 @@ public:
     std::map<cmSourceFile const*, std::string>& mapping,
     cmGeneratorTarget const* = nullptr) override;
 
+  std::string GetObjectOutputRoot() const override;
+  bool AlwaysUsesCMFPaths() const override;
+
 protected:
   virtual char const* ReportErrorLabel() const;
   virtual bool CustomCommandUseLocal() const { return false; }

+ 2 - 3
Source/cmLocalXCodeGenerator.cxx

@@ -28,10 +28,9 @@ cmLocalXCodeGenerator::cmLocalXCodeGenerator(cmGlobalGenerator* gg,
 cmLocalXCodeGenerator::~cmLocalXCodeGenerator() = default;
 
 std::string cmLocalXCodeGenerator::GetTargetDirectory(
-  cmGeneratorTarget const*) const
+  cmGeneratorTarget const* target) const
 {
-  // No per-target directory for this generator (yet).
-  return std::string{};
+  return cmStrCat(target->GetName(), ".dir");
 }
 
 void cmLocalXCodeGenerator::AppendFlagEscape(std::string& flags,

+ 19 - 18
Source/cmMakefileTargetGenerator.cxx

@@ -165,10 +165,10 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
 void cmMakefileTargetGenerator::CreateRuleFile()
 {
   // Create a directory for this target.
-  this->TargetBuildDirectory =
-    this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
   this->TargetBuildDirectoryFull =
-    this->LocalGenerator->ConvertToFullPath(this->TargetBuildDirectory);
+    this->GeneratorTarget->GetSupportDirectory();
+  this->TargetBuildDirectory = this->LocalGenerator->MaybeRelativeToCurBinDir(
+    this->TargetBuildDirectoryFull);
   cmSystemTools::MakeDirectory(this->TargetBuildDirectoryFull);
 
   // Construct the rule file name.
@@ -655,8 +655,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
   std::string const& objectName =
     this->GeneratorTarget->GetObjectName(&source);
   std::string const obj =
-    cmStrCat(this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
-             '/', objectName);
+    cmStrCat(this->TargetBuildDirectory, '/', objectName);
 
   // Avoid generating duplicate rules.
   if (this->ObjectFiles.find(obj) == this->ObjectFiles.end()) {
@@ -1419,26 +1418,28 @@ std::string cmMakefileTargetGenerator::GetClangTidyReplacementsFilePath(
 {
   (void)config;
   auto const& objectName = this->GeneratorTarget->GetObjectName(&source);
-  auto fixesFile = cmSystemTools::CollapseFullPath(cmStrCat(
-    directory, '/',
-    this->GeneratorTarget->GetLocalGenerator()->MaybeRelativeToTopBinDir(
-      cmStrCat(this->GeneratorTarget->GetLocalGenerator()
-                 ->GetCurrentBinaryDirectory(),
-               '/',
-               this->GeneratorTarget->GetLocalGenerator()->GetTargetDirectory(
-                 this->GeneratorTarget),
-               '/', objectName, ".yaml"))));
+  // NOTE: This may be better to use `this->TargetBuildDirectory` instead of
+  // `MaybeRelativeToTopBinDir(this->TargetBuildDirectoryFull)` here. The main
+  // difference is that the current behavior looks odd to relative
+  // `<LANG>_CLANG_TIDY_EXPORT_FIXES_DIR` settings. Each subdirectory has its
+  // own export fixes directory *and* adds its relative-from-root path
+  // underneath it. However, when using an absolute export fixes directory, the
+  // source directory structure is preserved. The main benefit of the former is
+  // shorter paths everywhere versus the status quo of the existing code.
+  cmLocalGenerator* lg = this->GeneratorTarget->GetLocalGenerator();
+  auto fixesFile = cmSystemTools::CollapseFullPath(
+    cmStrCat(directory, '/',
+             lg->CreateSafeObjectFileName(
+               lg->MaybeRelativeToTopBinDir(this->TargetBuildDirectoryFull)),
+             '/', objectName, ".yaml"));
   return fixesFile;
 }
 
 void cmMakefileTargetGenerator::WriteTargetDependRules()
 {
   // must write the targets depend info file
-  std::string dir =
-    this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
-  this->InfoFileNameFull = cmStrCat(dir, "/DependInfo.cmake");
   this->InfoFileNameFull =
-    this->LocalGenerator->ConvertToFullPath(this->InfoFileNameFull);
+    cmStrCat(this->TargetBuildDirectoryFull, "/DependInfo.cmake");
   this->InfoFileStream =
     cm::make_unique<cmGeneratedFileStream>(this->InfoFileNameFull);
   if (!this->InfoFileStream) {

+ 6 - 4
Source/cmNinjaNormalTargetGenerator.cxx

@@ -844,8 +844,9 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
     this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION");
 
   std::string targetOutputDir =
-    cmStrCat(this->GetLocalGenerator()->GetTargetDirectory(genTarget),
-             globalGen->ConfigDirectory(config), '/');
+    this->GetLocalGenerator()->MaybeRelativeToTopBinDir(
+      cmStrCat(genTarget->GetSupportDirectory(),
+               globalGen->ConfigDirectory(config), '/'));
   targetOutputDir = globalGen->ExpandCFGIntDir(targetOutputDir, config);
 
   std::string targetOutputReal =
@@ -980,8 +981,9 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement(
 
   if (config != fileConfig) {
     std::string targetOutputFileConfigDir =
-      cmStrCat(this->GetLocalGenerator()->GetTargetDirectory(genTarget),
-               globalGen->ConfigDirectory(fileConfig), '/');
+      this->GetLocalGenerator()->MaybeRelativeToTopBinDir(
+        cmStrCat(genTarget->GetSupportDirectory(),
+                 globalGen->ConfigDirectory(config), '/'));
     targetOutputFileConfigDir =
       globalGen->ExpandCFGIntDir(outputDir, fileConfig);
     if (outputDir == targetOutputFileConfigDir) {

+ 17 - 53
Source/cmNinjaTargetGenerator.cxx

@@ -412,14 +412,9 @@ std::string cmNinjaTargetGenerator::GetCompiledSourceNinjaPath(
 std::string cmNinjaTargetGenerator::GetObjectFileDir(
   std::string const& config) const
 {
-  std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
-  if (!path.empty()) {
-    path += '/';
-  }
-  path +=
-    cmStrCat(this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
-             this->GetGlobalGenerator()->ConfigDirectory(config));
-  return path;
+  return this->LocalGenerator->MaybeRelativeToTopBinDir(
+    cmStrCat(this->GeneratorTarget->GetSupportDirectory(),
+             this->GetGlobalGenerator()->GetConfigDirectory(config)));
 }
 
 std::string cmNinjaTargetGenerator::GetObjectFilePath(
@@ -450,18 +445,11 @@ std::string cmNinjaTargetGenerator::GetClangTidyReplacementsFilePath(
   std::string const& directory, cmSourceFile const& source,
   std::string const& config) const
 {
-  auto path = this->LocalGenerator->GetHomeRelativeOutputPath();
-  if (!path.empty()) {
-    path += '/';
-  }
-  path = cmStrCat(directory, '/', path);
   auto const& objectName = this->GeneratorTarget->GetObjectName(&source);
-  path =
-    cmStrCat(std::move(path),
-             this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
-             this->GetGlobalGenerator()->ConfigDirectory(config), '/',
-             objectName, ".yaml");
-  return path;
+  return cmStrCat(directory, '/',
+                  this->LocalGenerator->CreateSafeObjectFileName(
+                    this->GetObjectFileDir(config)),
+                  '/', objectName, ".yaml");
 }
 
 std::string cmNinjaTargetGenerator::GetPreprocessedFilePath(
@@ -490,38 +478,20 @@ std::string cmNinjaTargetGenerator::GetPreprocessedFilePath(
   std::string const ppName =
     cmStrCat(objName.substr(0, objName.size() - objExt.size()), "-pp.", ppExt);
 
-  std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
-  if (!path.empty()) {
-    path += '/';
-  }
-  path +=
-    cmStrCat(this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
-             this->GetGlobalGenerator()->ConfigDirectory(config), '/', ppName);
-  return path;
+  return cmStrCat(this->GetObjectFileDir(config), '/', ppName);
 }
 
 std::string cmNinjaTargetGenerator::GetDyndepFilePath(
   std::string const& lang, std::string const& config) const
 {
-  std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
-  if (!path.empty()) {
-    path += '/';
-  }
-  path += cmStrCat(
-    this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
-    this->GetGlobalGenerator()->ConfigDirectory(config), '/', lang, ".dd");
-  return path;
+  return cmStrCat(this->GetObjectFileDir(config), '/', lang, ".dd");
 }
 
 std::string cmNinjaTargetGenerator::GetTargetDependInfoPath(
   std::string const& lang, std::string const& config) const
 {
-  std::string path =
-    cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/',
-             this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
-             this->GetGlobalGenerator()->ConfigDirectory(config), '/', lang,
-             "DependInfo.json");
-  return path;
+  return cmStrCat(this->GetObjectFileDir(config), '/', lang,
+                  "DependInfo.json");
 }
 
 std::string cmNinjaTargetGenerator::GetTargetOutputDir(
@@ -1129,9 +1099,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
         tgtDir = ".";
       } else {
         // Any path that always exists will work here.
-        tgtDir = cmStrCat(
-          this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
-          this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget));
+        tgtDir = this->GetObjectFileDir(config);
       }
       orderOnlyDeps.push_back(this->ConvertToNinjaPath(tgtDir));
     }
@@ -1233,10 +1201,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
     cmNinjaBuild build(this->LanguageDyndepRule(language, config));
     build.Outputs.push_back(this->GetDyndepFilePath(language, config));
     build.ImplicitOuts.emplace_back(
-      cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/',
-               this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
-               this->GetGlobalGenerator()->ConfigDirectory(config), '/',
-               language, "Modules.json"));
+      cmStrCat(this->GetObjectFileDir(config), '/', language, "Modules.json"));
     build.ImplicitDeps.emplace_back(
       this->GetTargetDependInfoPath(language, config));
     {
@@ -1269,11 +1234,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
       this->GetLinkedTargetDirectories(language, config);
     for (std::string const& l : linked_directories.Direct) {
       build.ImplicitDeps.emplace_back(
-        cmStrCat(l, '/', language, "Modules.json"));
+        this->ConvertToNinjaPath(cmStrCat(l, '/', language, "Modules.json")));
     }
     for (std::string const& l : linked_directories.Forward) {
       build.ImplicitDeps.emplace_back(
-        cmStrCat(l, '/', language, "Modules.json"));
+        this->ConvertToNinjaPath(cmStrCat(l, '/', language, "Modules.json")));
     }
 
     this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
@@ -1411,9 +1376,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
 {
   std::string const language = source->GetLanguage();
   std::string const sourceFilePath = this->GetCompiledSourceNinjaPath(source);
-  std::string const objectDir = this->ConvertToNinjaPath(
-    cmStrCat(this->GeneratorTarget->GetSupportDirectory(),
-             this->GetGlobalGenerator()->ConfigDirectory(config)));
+  std::string const objectDir =
+    this->ConvertToNinjaPath(this->GetObjectFileDir(config));
   std::string const objectFileName =
     this->ConvertToNinjaPath(this->GetObjectFilePath(source, config));
   std::string const objectFileDir =

+ 3 - 0
Source/cmQtAutoGenInitializer.cxx

@@ -462,6 +462,9 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
       std::string(), this->Makefile->GetCurrentBinaryDirectory());
 
     // Info directory
+    // TODO: Split this? `AutogenInfo.json` is expected to always be under the
+    // `CMakeFiles` directory, but not all generators places its `<tgt>.dir`
+    // directories there.
     this->Dir.Info = cmStrCat(cbd, "/CMakeFiles/", this->GenTarget->GetName(),
                               "_autogen.dir");
     cmSystemTools::ConvertToUnixSlashes(this->Dir.Info);

+ 16 - 18
Source/cmVisualStudio10TargetGenerator.cxx

@@ -300,9 +300,7 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
          &this->NsightTegraVersion[0], &this->NsightTegraVersion[1],
          &this->NsightTegraVersion[2], &this->NsightTegraVersion[3]);
   this->MSTools = !this->NsightTegra && !this->Android;
-  this->DefaultArtifactDir =
-    cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
-             this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget));
+  this->DefaultArtifactDir = this->GeneratorTarget->GetSupportDirectory();
   this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() ==
                          this->Makefile->GetCurrentBinaryDirectory());
   this->ClassifyAllConfigSources();
@@ -3094,9 +3092,9 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions(
         }
       }
 
-      std::string intermediateDir = cmStrCat(
-        this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), '/',
-        config, '/');
+      std::string intermediateDir =
+        this->LocalGenerator->MaybeRelativeToCurBinDir(cmStrCat(
+          this->GeneratorTarget->GetSupportDirectory(), '/', config, '/'));
       std::string outDir;
       std::string targetNameFull;
       if (ttype == cmStateEnums::OBJECT_LIBRARY) {
@@ -5255,8 +5253,8 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile(
         !(this->GlobalGenerator->TargetsWindowsPhone() &&
           this->GlobalGenerator->GetSystemVersion() == "8.0"_s)) {
       // Move the manifest to a project directory to avoid clashes
-      std::string artifactDir =
-        this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+      std::string artifactDir = this->LocalGenerator->MaybeRelativeToCurBinDir(
+        this->GeneratorTarget->GetSupportDirectory());
       ConvertToWindowsSlash(artifactDir);
       Elem e1(e0, "PropertyGroup");
       e1.Element("AppxPackageArtifactsDir", cmStrCat(artifactDir, '\\'));
@@ -5507,8 +5505,8 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWP80(Elem& e1)
   // folders
   std::string manifestFile = cmStrCat(
     this->LocalGenerator->GetCurrentBinaryDirectory(), "/WMAppManifest.xml");
-  std::string artifactDir =
-    this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+  std::string artifactDir = this->LocalGenerator->MaybeRelativeToCurBinDir(
+    this->GeneratorTarget->GetSupportDirectory());
   ConvertToWindowsSlash(artifactDir);
   std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
   std::string const& targetNameXML = cmVS10EscapeXML(GetTargetOutputName());
@@ -5589,8 +5587,8 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWP81(Elem& e1)
 {
   std::string manifestFile =
     cmStrCat(this->DefaultArtifactDir, "/package.appxManifest");
-  std::string artifactDir =
-    this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+  std::string artifactDir = this->LocalGenerator->MaybeRelativeToCurBinDir(
+    this->GeneratorTarget->GetSupportDirectory());
   ConvertToWindowsSlash(artifactDir);
   std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
   std::string const& targetNameXML = cmVS10EscapeXML(GetTargetOutputName());
@@ -5651,8 +5649,8 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWS80(Elem& e1)
 {
   std::string manifestFile =
     cmStrCat(this->DefaultArtifactDir, "/package.appxManifest");
-  std::string artifactDir =
-    this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+  std::string artifactDir = this->LocalGenerator->MaybeRelativeToCurBinDir(
+    this->GeneratorTarget->GetSupportDirectory());
   ConvertToWindowsSlash(artifactDir);
   std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
   std::string const& targetNameXML = cmVS10EscapeXML(GetTargetOutputName());
@@ -5705,8 +5703,8 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWS81(Elem& e1)
 {
   std::string manifestFile =
     cmStrCat(this->DefaultArtifactDir, "/package.appxManifest");
-  std::string artifactDir =
-    this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+  std::string artifactDir = this->LocalGenerator->MaybeRelativeToCurBinDir(
+    this->GeneratorTarget->GetSupportDirectory());
   ConvertToWindowsSlash(artifactDir);
   std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
   std::string const& targetNameXML = cmVS10EscapeXML(GetTargetOutputName());
@@ -5764,8 +5762,8 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWS10_0(Elem& e1)
 {
   std::string manifestFile =
     cmStrCat(this->DefaultArtifactDir, "/package.appxManifest");
-  std::string artifactDir =
-    this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+  std::string artifactDir = this->LocalGenerator->MaybeRelativeToCurBinDir(
+    this->GeneratorTarget->GetSupportDirectory());
   ConvertToWindowsSlash(artifactDir);
   std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
   std::string const& targetNameXML = cmVS10EscapeXML(GetTargetOutputName());

+ 2 - 2
Tests/RunCMake/InstallParallel/RunCMakeTest.cmake

@@ -25,7 +25,7 @@ function(install_test test)
       set(INSTALL_COUNT 1)
     endif()
     set(RunCMake-check-file check-num-installs.cmake)
-    run_cmake_command(${test}-install ${CMAKE_COMMAND} --build . --config Debug ${ARGS_ARGS})
+    run_cmake_command(${test}-install ${CMAKE_COMMAND} -E env --unset=NINJA_STATUS ${CMAKE_COMMAND} --build . --config Debug ${ARGS_ARGS})
     unset(RunCMake-check-file)
   else()
     if (ARGS_COMPONENT)
@@ -42,7 +42,7 @@ function(install_test test)
     endif()
     set(INSTALL_MANIFEST ${RunCMake_TEST_BINARY_DIR}/${INSTALL_MANIFEST})
     set(RunCMake-check-file check-manifest.cmake)
-    run_cmake_command(${test}-install ${CMAKE_COMMAND} --install . ${ARGS_ARGS})
+    run_cmake_command(${test}-install ${CMAKE_COMMAND} -E env --unset=NINJA_STATUS ${CMAKE_COMMAND} --install . ${ARGS_ARGS})
     unset(RunCMake-check-file)
   endif()
 endfunction()