1
0
Эх сурвалжийг харах

Merge topic 'relative-paths'

8526756b61 cmOutputConverter: Adopt relative path conversion helpers
013ec595c8 cmLocalGenerator: De-duplicate StateSnapshot member
24bfdbcffb cmLocalGenerator: Remove unused MaybeRelativeToCurSrcDir method
d6fe1bdb6d cmLocalGenerator: Localize logic mapping source path to object file name
4cb6a53bf5 cmListFileCache: Simplify relative path conversion in backtraces
5b3a71a83f cmSystemTools: Adopt RelativeIfUnder helper
ea9b1d36b8 cmStateDirectory: Clarify relative path top selection logic
2d9109df7c cmStateDirectory: Remove network path logic from relative path top selection
...

Acked-by: Kitware Robot <[email protected]>
Merge-request: !6128
Brad King 4 жил өмнө
parent
commit
a577d3c026

+ 1 - 9
Source/cmFileAPICodemodel.cxx

@@ -57,15 +57,7 @@ using TargetIndexMapType =
 
 std::string RelativeIfUnder(std::string const& top, std::string const& in)
 {
-  std::string out;
-  if (in == top) {
-    out = ".";
-  } else if (cmSystemTools::IsSubDirectory(in, top)) {
-    out = in.substr(top.size() + 1);
-  } else {
-    out = in;
-  }
-  return out;
+  return cmSystemTools::RelativeIfUnder(top, in);
 }
 
 class JBTIndex

+ 2 - 2
Source/cmGlobalNinjaGenerator.cxx

@@ -2434,10 +2434,10 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
     cmStateSnapshot snapshot = this->GetCMakeInstance()->GetCurrentSnapshot();
     snapshot.GetDirectory().SetCurrentSource(dir_cur_src);
     snapshot.GetDirectory().SetCurrentBinary(dir_cur_bld);
-    snapshot.GetDirectory().SetRelativePathTopSource(dir_top_src.c_str());
-    snapshot.GetDirectory().SetRelativePathTopBinary(dir_top_bld.c_str());
     auto mfd = cm::make_unique<cmMakefile>(this, snapshot);
     auto lgd = this->CreateLocalGenerator(mfd.get());
+    lgd->SetRelativePathTopSource(dir_top_src);
+    lgd->SetRelativePathTopBinary(dir_top_bld);
     this->Makefiles.push_back(std::move(mfd));
     this->LocalGenerators.push_back(std::move(lgd));
   }

+ 0 - 19
Source/cmGlobalUnixMakefileGenerator3.cxx

@@ -22,7 +22,6 @@
 #include "cmOutputConverter.h"
 #include "cmProperty.h"
 #include "cmState.h"
-#include "cmStateDirectory.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -552,21 +551,6 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
   bool fast, int jobs, bool verbose,
   std::vector<std::string> const& makeOptions)
 {
-  std::unique_ptr<cmMakefile> mfu;
-  cmMakefile* mf;
-  if (!this->Makefiles.empty()) {
-    mf = this->Makefiles[0].get();
-  } else {
-    cmStateSnapshot snapshot = this->CMakeInstance->GetCurrentSnapshot();
-    snapshot.GetDirectory().SetCurrentSource(
-      this->CMakeInstance->GetHomeDirectory());
-    snapshot.GetDirectory().SetCurrentBinary(
-      this->CMakeInstance->GetHomeOutputDirectory());
-    snapshot.SetDefaultDefinitions();
-    mfu = cm::make_unique<cmMakefile>(this, snapshot);
-    mf = mfu.get();
-  }
-
   GeneratedMakeCommand makeCommand;
 
   // Make it possible to set verbosity also from command line
@@ -597,9 +581,6 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
       if (fast) {
         tname += "/fast";
       }
-      tname =
-        mf->GetStateSnapshot().GetDirectory().ConvertToRelPathIfContained(
-          mf->GetState()->GetBinaryDirectory(), tname);
       cmSystemTools::ConvertToOutputSlashes(tname);
       makeCommand.Add(std::move(tname));
     }

+ 1 - 9
Source/cmLinkLineComputer.cxx

@@ -11,10 +11,8 @@
 #include "cmGeneratorTarget.h"
 #include "cmListFileCache.h"
 #include "cmOutputConverter.h"
-#include "cmStateDirectory.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
-#include "cmSystemTools.h"
 
 cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter,
                                        cmStateDirectory const& stateDir)
@@ -52,13 +50,7 @@ void cmLinkLineComputer::SetRelink(bool relink)
 std::string cmLinkLineComputer::ConvertToLinkReference(
   std::string const& lib) const
 {
-  std::string relLib = lib;
-
-  if (this->StateDir.ContainsBoth(this->StateDir.GetCurrentBinary(), lib)) {
-    relLib = cmSystemTools::ForceToRelativePath(
-      this->StateDir.GetCurrentBinary(), lib);
-  }
-  return relLib;
+  return this->OutputConverter->MaybeRelativeToCurBinDir(lib);
 }
 
 std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli)

+ 2 - 3
Source/cmListFileCache.cxx

@@ -15,7 +15,6 @@
 #include "cmMessageType.h"
 #include "cmMessenger.h"
 #include "cmState.h"
-#include "cmStateDirectory.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
@@ -550,7 +549,7 @@ void cmListFileBacktrace::PrintTitle(std::ostream& out) const
   cmListFileContext lfc = this->TopEntry->Context;
   cmStateSnapshot bottom = this->GetBottom();
   if (!bottom.GetState()->GetIsInTryCompile()) {
-    lfc.FilePath = bottom.GetDirectory().ConvertToRelPathIfContained(
+    lfc.FilePath = cmSystemTools::RelativeIfUnder(
       bottom.GetState()->GetSourceDirectory(), lfc.FilePath);
   }
   out << (lfc.Line ? " at " : " in ") << lfc;
@@ -581,7 +580,7 @@ void cmListFileBacktrace::PrintCallStack(std::ostream& out) const
     }
     cmListFileContext lfc = cur->Context;
     if (!bottom.GetState()->GetIsInTryCompile()) {
-      lfc.FilePath = bottom.GetDirectory().ConvertToRelPathIfContained(
+      lfc.FilePath = cmSystemTools::RelativeIfUnder(
         bottom.GetState()->GetSourceDirectory(), lfc.FilePath);
     }
     out << "  " << lfc << "\n";

+ 19 - 28
Source/cmLocalGenerator.cxx

@@ -88,7 +88,6 @@ static auto ruleReplaceVars = { "CMAKE_${LANG}_COMPILER",
 
 cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
   : cmOutputConverter(makefile->GetStateSnapshot())
-  , StateSnapshot(makefile->GetStateSnapshot())
   , DirectoryBacktrace(makefile->GetBacktrace())
 {
   this->GlobalGenerator = gg;
@@ -3532,6 +3531,21 @@ bool cmLocalGenerator::IsNinjaMulti() const
   return this->GetState()->UseNinjaMulti();
 }
 
+namespace {
+std::string relativeIfUnder(std::string const& top, std::string const& cur,
+                            std::string const& path)
+{
+  // Use a path relative to 'cur' if it can be expressed without
+  // a `../` sequence that leaves 'top'.
+  if (cmSystemTools::IsSubDirectory(path, cur) ||
+      (cmSystemTools::IsSubDirectory(cur, top) &&
+       cmSystemTools::IsSubDirectory(path, top))) {
+    return cmSystemTools::ForceToRelativePath(cur, path);
+  }
+  return path;
+}
+}
+
 std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
   const cmSourceFile& source, std::string const& dir_max,
   bool* hasSourceExtension, char const* customOutputExtension)
@@ -3541,13 +3555,15 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
   std::string const& fullPath = source.GetFullPath();
 
   // Try referencing the source relative to the source tree.
-  std::string relFromSource = this->MaybeRelativeToCurSrcDir(fullPath);
+  std::string relFromSource = relativeIfUnder(
+    this->GetSourceDirectory(), this->GetCurrentSourceDirectory(), fullPath);
   assert(!relFromSource.empty());
   bool relSource = !cmSystemTools::FileIsFullPath(relFromSource);
   bool subSource = relSource && relFromSource[0] != '.';
 
   // Try referencing the source relative to the binary tree.
-  std::string relFromBinary = this->MaybeRelativeToCurBinDir(fullPath);
+  std::string relFromBinary = relativeIfUnder(
+    this->GetBinaryDirectory(), this->GetCurrentBinaryDirectory(), fullPath);
   assert(!relFromBinary.empty());
   bool relBinary = !cmSystemTools::FileIsFullPath(relFromBinary);
   bool subBinary = relBinary && relFromBinary[0] != '.';
@@ -3662,31 +3678,6 @@ std::string const& cmLocalGenerator::GetCurrentSourceDirectory() const
   return this->StateSnapshot.GetDirectory().GetCurrentSource();
 }
 
-std::string cmLocalGenerator::MaybeRelativeTo(
-  std::string const& local_path, std::string const& remote_path) const
-{
-  return this->StateSnapshot.GetDirectory().ConvertToRelPathIfContained(
-    local_path, remote_path);
-}
-
-std::string cmLocalGenerator::MaybeRelativeToTopBinDir(
-  std::string const& path) const
-{
-  return this->MaybeRelativeTo(this->GetBinaryDirectory(), path);
-}
-
-std::string cmLocalGenerator::MaybeRelativeToCurBinDir(
-  std::string const& path) const
-{
-  return this->MaybeRelativeTo(this->GetCurrentBinaryDirectory(), path);
-}
-
-std::string cmLocalGenerator::MaybeRelativeToCurSrcDir(
-  std::string const& path) const
-{
-  return this->MaybeRelativeTo(this->GetCurrentSourceDirectory(), path);
-}
-
 std::string cmLocalGenerator::GetTargetDirectory(
   const cmGeneratorTarget* /*unused*/) const
 {

+ 0 - 15
Source/cmLocalGenerator.h

@@ -462,17 +462,6 @@ public:
   std::string const& GetCurrentBinaryDirectory() const;
   std::string const& GetCurrentSourceDirectory() const;
 
-  /**
-   * Convert the given remote path to a relative path with respect to
-   * one of our common work directories.  The path must use forward
-   * slashes and not already be escaped or quoted.
-   * The conversion is skipped if the paths are not both in the source
-   * or both in the binary tree.
-   */
-  std::string MaybeRelativeToTopBinDir(std::string const& path) const;
-  std::string MaybeRelativeToCurBinDir(std::string const& path) const;
-  std::string MaybeRelativeToCurSrcDir(std::string const& path) const;
-
   /**
    * Generate a macOS application bundle Info.plist file.
    */
@@ -559,9 +548,6 @@ public:
   cmProp GetRuleLauncher(cmGeneratorTarget* target, const std::string& prop);
 
 protected:
-  std::string MaybeRelativeTo(std::string const& local_path,
-                              std::string const& remote_path) const;
-
   // The default implementation ignores the IncludePathStyle and always
   // uses absolute paths.  A generator may override this to use relative
   // paths in some cases.
@@ -595,7 +581,6 @@ protected:
   virtual bool CheckDefinition(std::string const& define) const;
 
   cmMakefile* Makefile;
-  cmStateSnapshot StateSnapshot;
   cmListFileBacktrace DirectoryBacktrace;
   cmGlobalGenerator* GlobalGenerator;
   std::map<std::string, std::string> UniqueObjectNamesMap;

+ 4 - 9
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -38,7 +38,6 @@
 #include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
 #include "cmState.h"
-#include "cmStateDirectory.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -474,11 +473,9 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
   infoFileStream
     << "# Relative path conversion top directories.\n"
     << "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \""
-    << this->StateSnapshot.GetDirectory().GetRelativePathTopSource()
-    << "\")\n"
+    << this->GetRelativePathTopSource() << "\")\n"
     << "set(CMAKE_RELATIVE_PATH_TOP_BINARY \""
-    << this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()
-    << "\")\n"
+    << this->GetRelativePathTopBinary() << "\")\n"
     << "\n";
   /* clang-format on */
 
@@ -1513,13 +1510,11 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
     // Setup relative path top directories.
     if (cmProp relativePathTopSource =
           mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE")) {
-      this->StateSnapshot.GetDirectory().SetRelativePathTopSource(
-        relativePathTopSource->c_str());
+      this->SetRelativePathTopSource(*relativePathTopSource);
     }
     if (cmProp relativePathTopBinary =
           mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY")) {
-      this->StateSnapshot.GetDirectory().SetRelativePathTopBinary(
-        relativePathTopBinary->c_str());
+      this->SetRelativePathTopBinary(*relativePathTopBinary);
     }
   } else {
     cmSystemTools::Error("Directory Information file not found");

+ 2 - 10
Source/cmMakefileTargetGenerator.cxx

@@ -1749,7 +1749,8 @@ public:
   {
     // Construct the name of the next object.
     this->NextObject = this->OutputConverter->ConvertToOutputFormat(
-      this->MaybeRelativeToCurBinDir(obj), cmOutputConverter::RESPONSE);
+      this->OutputConverter->MaybeRelativeToCurBinDir(obj),
+      cmOutputConverter::RESPONSE);
 
     // Roll over to next string if the limit will be exceeded.
     if (this->LengthLimit != std::string::npos &&
@@ -1770,15 +1771,6 @@ public:
   void Done() { this->Strings.push_back(this->CurrentString); }
 
 private:
-  std::string MaybeRelativeToCurBinDir(std::string const& path)
-  {
-    std::string const& base = this->StateDir.GetCurrentBinary();
-    if (!this->StateDir.ContainsBoth(base, path)) {
-      return path;
-    }
-    return cmSystemTools::ForceToRelativePath(base, path);
-  }
-
   std::vector<std::string>& Strings;
   cmOutputConverter* OutputConverter;
   cmStateDirectory StateDir;

+ 94 - 0
Source/cmOutputConverter.cxx

@@ -9,14 +9,108 @@
 #include <vector>
 
 #include "cmState.h"
+#include "cmStateDirectory.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
+namespace {
+bool PathEqOrSubDir(std::string const& a, std::string const& b)
+{
+  return (cmSystemTools::ComparePath(a, b) ||
+          cmSystemTools::IsSubDirectory(a, b));
+};
+}
+
 cmOutputConverter::cmOutputConverter(cmStateSnapshot const& snapshot)
   : StateSnapshot(snapshot)
   , LinkScriptShell(false)
 {
   assert(this->StateSnapshot.IsValid());
+  this->ComputeRelativePathTopSource();
+  this->ComputeRelativePathTopBinary();
+}
+
+void cmOutputConverter::ComputeRelativePathTopSource()
+{
+  // Walk up the buildsystem directory tree to find the highest source
+  // directory that contains the current source directory.
+  cmStateSnapshot snapshot = this->StateSnapshot;
+  for (cmStateSnapshot parent = snapshot.GetBuildsystemDirectoryParent();
+       parent.IsValid(); parent = parent.GetBuildsystemDirectoryParent()) {
+    if (cmSystemTools::IsSubDirectory(
+          snapshot.GetDirectory().GetCurrentSource(),
+          parent.GetDirectory().GetCurrentSource())) {
+      snapshot = parent;
+    }
+  }
+  this->RelativePathTopSource = snapshot.GetDirectory().GetCurrentSource();
+}
+
+void cmOutputConverter::ComputeRelativePathTopBinary()
+{
+  // Walk up the buildsystem directory tree to find the highest binary
+  // directory that contains the current binary directory.
+  cmStateSnapshot snapshot = this->StateSnapshot;
+  for (cmStateSnapshot parent = snapshot.GetBuildsystemDirectoryParent();
+       parent.IsValid(); parent = parent.GetBuildsystemDirectoryParent()) {
+    if (cmSystemTools::IsSubDirectory(
+          snapshot.GetDirectory().GetCurrentBinary(),
+          parent.GetDirectory().GetCurrentBinary())) {
+      snapshot = parent;
+    }
+  }
+
+  this->RelativePathTopBinary = snapshot.GetDirectory().GetCurrentBinary();
+}
+
+std::string const& cmOutputConverter::GetRelativePathTopSource() const
+{
+  return this->RelativePathTopSource;
+}
+
+std::string const& cmOutputConverter::GetRelativePathTopBinary() const
+{
+  return this->RelativePathTopBinary;
+}
+
+void cmOutputConverter::SetRelativePathTopSource(std::string const& top)
+{
+  this->RelativePathTopSource = top;
+}
+
+void cmOutputConverter::SetRelativePathTopBinary(std::string const& top)
+{
+  this->RelativePathTopBinary = top;
+}
+
+std::string cmOutputConverter::MaybeRelativeTo(
+  std::string const& local_path, std::string const& remote_path) const
+{
+  bool bothInBinary =
+    PathEqOrSubDir(local_path, this->RelativePathTopBinary) &&
+    PathEqOrSubDir(remote_path, this->RelativePathTopBinary);
+
+  bool bothInSource =
+    PathEqOrSubDir(local_path, this->RelativePathTopSource) &&
+    PathEqOrSubDir(remote_path, this->RelativePathTopSource);
+
+  if (bothInBinary || bothInSource) {
+    return cmSystemTools::ForceToRelativePath(local_path, remote_path);
+  }
+  return remote_path;
+}
+
+std::string cmOutputConverter::MaybeRelativeToTopBinDir(
+  std::string const& path) const
+{
+  return this->MaybeRelativeTo(this->GetState()->GetBinaryDirectory(), path);
+}
+
+std::string cmOutputConverter::MaybeRelativeToCurBinDir(
+  std::string const& path) const
+{
+  return this->MaybeRelativeTo(
+    this->StateSnapshot.GetDirectory().GetCurrentBinary(), path);
 }
 
 std::string cmOutputConverter::ConvertToOutputForExisting(

+ 30 - 2
Source/cmOutputConverter.h

@@ -17,6 +17,21 @@ class cmOutputConverter
 public:
   cmOutputConverter(cmStateSnapshot const& snapshot);
 
+  /**
+   * Convert the given remote path to a relative path with respect to
+   * one of our common work directories.  The path must use forward
+   * slashes and not already be escaped or quoted.
+   * The conversion is skipped if the paths are not both in the source
+   * or both in the binary tree.
+   */
+  std::string MaybeRelativeToTopBinDir(std::string const& path) const;
+  std::string MaybeRelativeToCurBinDir(std::string const& path) const;
+
+  std::string const& GetRelativePathTopSource() const;
+  std::string const& GetRelativePathTopBinary() const;
+  void SetRelativePathTopSource(std::string const& top);
+  void SetRelativePathTopBinary(std::string const& top);
+
   enum OutputFormat
   {
     SHELL,
@@ -102,6 +117,9 @@ public:
   };
   static FortranPreprocess GetFortranPreprocess(cm::string_view value);
 
+protected:
+  cmStateSnapshot StateSnapshot;
+
 private:
   cmState* GetState() const;
 
@@ -111,7 +129,17 @@ private:
   static bool Shell_ArgumentNeedsQuotes(cm::string_view in, int flags);
   static std::string Shell_GetArgument(cm::string_view in, int flags);
 
-  cmStateSnapshot StateSnapshot;
-
   bool LinkScriptShell;
+
+  // The top-most directories for relative path conversion.  Both the
+  // source and destination location of a relative path conversion
+  // must be underneath one of these directories (both under source or
+  // both under binary) in order for the relative path to be evaluated
+  // safely by the build tools.
+  std::string RelativePathTopSource;
+  std::string RelativePathTopBinary;
+  void ComputeRelativePathTopSource();
+  void ComputeRelativePathTopBinary();
+  std::string MaybeRelativeTo(std::string const& local_path,
+                              std::string const& remote_path) const;
 };

+ 0 - 122
Source/cmStateDirectory.cxx

@@ -24,74 +24,6 @@ static std::string const kBUILDSYSTEM_TARGETS = "BUILDSYSTEM_TARGETS";
 static std::string const kSOURCE_DIR = "SOURCE_DIR";
 static std::string const kSUBDIRECTORIES = "SUBDIRECTORIES";
 
-void cmStateDirectory::ComputeRelativePathTopSource()
-{
-  // Relative path conversion inside the source tree is not used to
-  // construct relative paths passed to build tools so it is safe to use
-  // even when the source is a network path.
-
-  cmStateSnapshot snapshot = this->Snapshot_;
-  std::vector<cmStateSnapshot> snapshots;
-  snapshots.push_back(snapshot);
-  while (true) {
-    snapshot = snapshot.GetBuildsystemDirectoryParent();
-    if (snapshot.IsValid()) {
-      snapshots.push_back(snapshot);
-    } else {
-      break;
-    }
-  }
-
-  std::string result = snapshots.front().GetDirectory().GetCurrentSource();
-
-  // Walk up the buildsystem directory tree to find the highest source
-  // directory that contains the current source directory and the
-  // intermediate ancestors.
-  for (cmStateSnapshot const& snp : cmMakeRange(snapshots).advance(1)) {
-    std::string currentSource = snp.GetDirectory().GetCurrentSource();
-    if (cmSystemTools::IsSubDirectory(result, currentSource)) {
-      result = currentSource;
-    }
-  }
-  this->DirectoryState->RelativePathTopSource = result;
-}
-
-void cmStateDirectory::ComputeRelativePathTopBinary()
-{
-  cmStateSnapshot snapshot = this->Snapshot_;
-  std::vector<cmStateSnapshot> snapshots;
-  snapshots.push_back(snapshot);
-  while (true) {
-    snapshot = snapshot.GetBuildsystemDirectoryParent();
-    if (snapshot.IsValid()) {
-      snapshots.push_back(snapshot);
-    } else {
-      break;
-    }
-  }
-
-  std::string result = snapshots.front().GetDirectory().GetCurrentBinary();
-
-  // Walk up the buildsystem directory tree to find the highest binary
-  // directory that contains the current binary directory and the
-  // intermediate ancestors.
-  for (cmStateSnapshot const& snp : cmMakeRange(snapshots).advance(1)) {
-    std::string currentBinary = snp.GetDirectory().GetCurrentBinary();
-    if (cmSystemTools::IsSubDirectory(result, currentBinary)) {
-      result = currentBinary;
-    }
-  }
-
-  // The current working directory on Windows cannot be a network
-  // path.  Therefore relative paths cannot work when the binary tree
-  // is a network path.
-  if (result.size() < 2 || result.substr(0, 2) != "//") {
-    this->DirectoryState->RelativePathTopBinary = result;
-  } else {
-    this->DirectoryState->RelativePathTopBinary.clear();
-  }
-}
-
 std::string const& cmStateDirectory::GetCurrentSource() const
 {
   return this->DirectoryState->Location;
@@ -103,9 +35,6 @@ void cmStateDirectory::SetCurrentSource(std::string const& dir)
   loc = dir;
   cmSystemTools::ConvertToUnixSlashes(loc);
   loc = cmSystemTools::CollapseFullPath(loc);
-
-  this->ComputeRelativePathTopSource();
-
   this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc);
 }
 
@@ -120,60 +49,9 @@ void cmStateDirectory::SetCurrentBinary(std::string const& dir)
   loc = dir;
   cmSystemTools::ConvertToUnixSlashes(loc);
   loc = cmSystemTools::CollapseFullPath(loc);
-
-  this->ComputeRelativePathTopBinary();
-
   this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc);
 }
 
-std::string const& cmStateDirectory::GetRelativePathTopSource() const
-{
-  return this->DirectoryState->RelativePathTopSource;
-}
-
-std::string const& cmStateDirectory::GetRelativePathTopBinary() const
-{
-  return this->DirectoryState->RelativePathTopBinary;
-}
-
-void cmStateDirectory::SetRelativePathTopSource(const char* dir)
-{
-  this->DirectoryState->RelativePathTopSource = dir;
-}
-
-void cmStateDirectory::SetRelativePathTopBinary(const char* dir)
-{
-  this->DirectoryState->RelativePathTopBinary = dir;
-}
-
-bool cmStateDirectory::ContainsBoth(std::string const& local_path,
-                                    std::string const& remote_path) const
-{
-  auto PathEqOrSubDir = [](std::string const& a, std::string const& b) {
-    return (cmSystemTools::ComparePath(a, b) ||
-            cmSystemTools::IsSubDirectory(a, b));
-  };
-
-  bool bothInBinary =
-    PathEqOrSubDir(local_path, this->GetRelativePathTopBinary()) &&
-    PathEqOrSubDir(remote_path, this->GetRelativePathTopBinary());
-
-  bool bothInSource =
-    PathEqOrSubDir(local_path, this->GetRelativePathTopSource()) &&
-    PathEqOrSubDir(remote_path, this->GetRelativePathTopSource());
-
-  return bothInBinary || bothInSource;
-}
-
-std::string cmStateDirectory::ConvertToRelPathIfContained(
-  std::string const& local_path, std::string const& remote_path) const
-{
-  if (!this->ContainsBoth(local_path, remote_path)) {
-    return remote_path;
-  }
-  return cmSystemTools::ForceToRelativePath(local_path, remote_path);
-}
-
 cmStateDirectory::cmStateDirectory(
   cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator iter,
   const cmStateSnapshot& snapshot)

+ 0 - 14
Source/cmStateDirectory.h

@@ -28,17 +28,6 @@ public:
   std::string const& GetCurrentBinary() const;
   void SetCurrentBinary(std::string const& dir);
 
-  std::string const& GetRelativePathTopSource() const;
-  std::string const& GetRelativePathTopBinary() const;
-  void SetRelativePathTopSource(const char* dir);
-  void SetRelativePathTopBinary(const char* dir);
-
-  bool ContainsBoth(std::string const& local_path,
-                    std::string const& remote_path) const;
-
-  std::string ConvertToRelPathIfContained(
-    std::string const& local_path, std::string const& remote_path) const;
-
   cmStringRange GetIncludeDirectoriesEntries() const;
   cmBacktraceRange GetIncludeDirectoriesEntryBacktraces() const;
   void AppendIncludeDirectoriesEntry(std::string const& vec,
@@ -94,9 +83,6 @@ public:
   void AddNormalTargetName(std::string const& name);
 
 private:
-  void ComputeRelativePathTopSource();
-  void ComputeRelativePathTopBinary();
-
   cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator
     DirectoryState;
   cmStateSnapshot Snapshot_;

+ 0 - 8
Source/cmStatePrivate.h

@@ -67,14 +67,6 @@ struct cmStateDetail::BuildsystemDirectoryStateType
   std::string Location;
   std::string OutputLocation;
 
-  // The top-most directories for relative path conversion.  Both the
-  // source and destination location of a relative path conversion
-  // must be underneath one of these directories (both under source or
-  // both under binary) in order for the relative path to be evaluated
-  // safely by the build tools.
-  std::string RelativePathTopSource;
-  std::string RelativePathTopBinary;
-
   std::vector<std::string> IncludeDirectories;
   std::vector<cmListFileBacktrace> IncludeDirectoryBacktraces;
 

+ 14 - 0
Source/cmSystemTools.cxx

@@ -1491,6 +1491,20 @@ std::string cmSystemTools::ForceToRelativePath(std::string const& local_path,
   return relative;
 }
 
+std::string cmSystemTools::RelativeIfUnder(std::string const& top,
+                                           std::string const& in)
+{
+  std::string out;
+  if (in == top) {
+    out = ".";
+  } else if (cmSystemTools::IsSubDirectory(in, top)) {
+    out = in.substr(top.size() + 1);
+  } else {
+    out = in;
+  }
+  return out;
+}
+
 #ifndef CMAKE_BOOTSTRAP
 bool cmSystemTools::UnsetEnv(const char* value)
 {

+ 6 - 0
Source/cmSystemTools.h

@@ -346,6 +346,12 @@ public:
   static std::string ForceToRelativePath(std::string const& local_path,
                                          std::string const& remote_path);
 
+  /**
+   * Express the 'in' path relative to 'top' if it does not start in '../'.
+   */
+  static std::string RelativeIfUnder(std::string const& top,
+                                     std::string const& in);
+
 #ifndef CMAKE_BOOTSTRAP
   /** Remove an environment variable */
   static bool UnsetEnv(const char* value);

+ 1 - 3
Source/cmTarget.cxx

@@ -929,12 +929,10 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const
   const char* sigString =
     (sig == cmTarget::KeywordTLLSignature ? "keyword" : "plain");
   s << "The uses of the " << sigString << " signature are here:\n";
-  cmStateDirectory cmDir =
-    this->impl->Makefile->GetStateSnapshot().GetDirectory();
   for (auto const& cmd : this->impl->TLLCommands) {
     if (cmd.first == sig) {
       cmListFileContext lfc = cmd.second;
-      lfc.FilePath = cmDir.ConvertToRelPathIfContained(
+      lfc.FilePath = cmSystemTools::RelativeIfUnder(
         this->impl->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath);
       s << " * " << lfc << '\n';
     }

+ 12 - 4
Source/cmcmd.cxx

@@ -1270,11 +1270,15 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
         cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
         snapshot.GetDirectory().SetCurrentBinary(startOutDir);
         snapshot.GetDirectory().SetCurrentSource(startDir);
-        snapshot.GetDirectory().SetRelativePathTopSource(homeDir.c_str());
-        snapshot.GetDirectory().SetRelativePathTopBinary(homeOutDir.c_str());
         cmMakefile mf(cm.GetGlobalGenerator(), snapshot);
         auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf);
 
+        // FIXME: With advanced add_subdirectory usage, these are
+        // not necessarily the same as the generator originally used.
+        // We should pass all these directories through an info file.
+        lgd->SetRelativePathTopSource(homeDir);
+        lgd->SetRelativePathTopBinary(homeOutDir);
+
         // Actually scan dependencies.
         return lgd->UpdateDependencies(depInfo, verbose, color) ? 0 : 2;
       }
@@ -1551,11 +1555,15 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
         cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
         snapshot.GetDirectory().SetCurrentBinary(startOutDir);
         snapshot.GetDirectory().SetCurrentSource(startDir);
-        snapshot.GetDirectory().SetRelativePathTopSource(homeDir.c_str());
-        snapshot.GetDirectory().SetRelativePathTopBinary(homeOutDir.c_str());
         cmMakefile mf(cm.GetGlobalGenerator(), snapshot);
         auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf);
 
+        // FIXME: With advanced add_subdirectory usage, these are
+        // not necessarily the same as the generator originally used.
+        // We should pass all these directories through an info file.
+        lgd->SetRelativePathTopSource(homeDir);
+        lgd->SetRelativePathTopBinary(homeOutDir);
+
         return cmTransformDepfile(format, *lgd, args[8], args[9]) ? 0 : 2;
       }
       return 1;