Browse Source

cmOutputConverter: Adopt relative path conversion helpers

Move them up from cmLocalGenerator and out of cmStateDirectory.
Brad King 4 years ago
parent
commit
8526756b61

+ 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));
   }

+ 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)

+ 0 - 19
Source/cmLocalGenerator.cxx

@@ -3678,25 +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::GetTargetDirectory(
   const cmGeneratorTarget* /*unused*/) const
 {

+ 0 - 13
Source/cmLocalGenerator.h

@@ -462,16 +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;
-
   /**
    * Generate a macOS application bundle Info.plist file.
    */
@@ -558,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.

+ 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(

+ 27 - 0
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,
@@ -115,4 +130,16 @@ private:
   static std::string Shell_GetArgument(cm::string_view in, int flags);
 
   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 - 89
Source/cmStateDirectory.cxx

@@ -24,41 +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()
-{
-  // Walk up the buildsystem directory tree to find the highest source
-  // directory that contains the current source directory.
-  cmStateSnapshot snapshot = this->Snapshot_;
-  for (cmStateSnapshot parent = snapshot.GetBuildsystemDirectoryParent();
-       parent.IsValid(); parent = parent.GetBuildsystemDirectoryParent()) {
-    if (cmSystemTools::IsSubDirectory(
-          snapshot.GetDirectory().GetCurrentSource(),
-          parent.GetDirectory().GetCurrentSource())) {
-      snapshot = parent;
-    }
-  }
-  this->DirectoryState->RelativePathTopSource =
-    snapshot.GetDirectory().GetCurrentSource();
-}
-
-void cmStateDirectory::ComputeRelativePathTopBinary()
-{
-  // Walk up the buildsystem directory tree to find the highest binary
-  // directory that contains the current binary directory.
-  cmStateSnapshot snapshot = this->Snapshot_;
-  for (cmStateSnapshot parent = snapshot.GetBuildsystemDirectoryParent();
-       parent.IsValid(); parent = parent.GetBuildsystemDirectoryParent()) {
-    if (cmSystemTools::IsSubDirectory(
-          snapshot.GetDirectory().GetCurrentBinary(),
-          parent.GetDirectory().GetCurrentBinary())) {
-      snapshot = parent;
-    }
-  }
-
-  this->DirectoryState->RelativePathTopBinary =
-    snapshot.GetDirectory().GetCurrentBinary();
-}
-
 std::string const& cmStateDirectory::GetCurrentSource() const
 {
   return this->DirectoryState->Location;
@@ -70,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);
 }
 
@@ -87,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;
 

+ 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;