summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2021-05-18 13:31:13 +0000
committerKitware Robot <kwrobot@kitware.com>2021-05-18 09:31:25 -0400
commita577d3c026e2efb8faf7af74c161f21a7c4b0e33 (patch)
treeaea3892b1230c9f94c0d1f6c3f4f0dc1520dfb20
parent62b0eba266dc80b30a697ba2e58a3a2d3f279c88 (diff)
parent8526756b61014f780348346ba5fdf0604a02d158 (diff)
downloadcmake-a577d3c026e2efb8faf7af74c161f21a7c4b0e33.tar.gz
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 <kwrobot@kitware.com> Merge-request: !6128
-rw-r--r--Source/cmFileAPICodemodel.cxx10
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx4
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx19
-rw-r--r--Source/cmLinkLineComputer.cxx10
-rw-r--r--Source/cmListFileCache.cxx5
-rw-r--r--Source/cmLocalGenerator.cxx47
-rw-r--r--Source/cmLocalGenerator.h15
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx13
-rw-r--r--Source/cmMakefileTargetGenerator.cxx12
-rw-r--r--Source/cmOutputConverter.cxx94
-rw-r--r--Source/cmOutputConverter.h32
-rw-r--r--Source/cmStateDirectory.cxx122
-rw-r--r--Source/cmStateDirectory.h14
-rw-r--r--Source/cmStatePrivate.h8
-rw-r--r--Source/cmSystemTools.cxx14
-rw-r--r--Source/cmSystemTools.h6
-rw-r--r--Source/cmTarget.cxx4
-rw-r--r--Source/cmcmd.cxx16
18 files changed, 188 insertions, 257 deletions
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 6b8757c416..6b358423f1 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/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
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 5cf37daee3..565b9514da 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/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));
}
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 837c59fed5..9c3de1eed6 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/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));
}
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index 480c005cd3..a3f2968b1c 100644
--- a/Source/cmLinkLineComputer.cxx
+++ b/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)
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 2b98f204c8..4f7c959444 100644
--- a/Source/cmListFileCache.cxx
+++ b/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";
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index c101ff3f15..4db9216056 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/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
{
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 5ebf70c85f..993280ac2d 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -463,17 +463,6 @@ public:
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.
*/
void GenerateAppleInfoPList(cmGeneratorTarget* target,
@@ -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;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index a652c7b398..3a65a80c9e 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/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");
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 1cc843467d..4542672bd8 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/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;
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index ec5453716a..840fdb9ecf 100644
--- a/Source/cmOutputConverter.cxx
+++ b/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(
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index f1a8041ba7..865df718b1 100644
--- a/Source/cmOutputConverter.h
+++ b/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;
};
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index a0bfd2820f..9ae2861574 100644
--- a/Source/cmStateDirectory.cxx
+++ b/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)
diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h
index 4dab9ff946..ce00dbb3c3 100644
--- a/Source/cmStateDirectory.h
+++ b/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_;
diff --git a/Source/cmStatePrivate.h b/Source/cmStatePrivate.h
index 489264468d..a437ce2efc 100644
--- a/Source/cmStatePrivate.h
+++ b/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;
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index ab42810feb..2fba13f436 100644
--- a/Source/cmSystemTools.cxx
+++ b/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)
{
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 9f9c493a43..474f591ef5 100644
--- a/Source/cmSystemTools.h
+++ b/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);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index f84d246404..29e361c367 100644
--- a/Source/cmTarget.cxx
+++ b/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';
}
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 98946b64fb..727e41263c 100644
--- a/Source/cmcmd.cxx
+++ b/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;