diff options
author | Brad King <brad.king@kitware.com> | 2021-05-18 13:31:13 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2021-05-18 13:31:25 (GMT) |
commit | a577d3c026e2efb8faf7af74c161f21a7c4b0e33 (patch) | |
tree | aea3892b1230c9f94c0d1f6c3f4f0dc1520dfb20 | |
parent | 62b0eba266dc80b30a697ba2e58a3a2d3f279c88 (diff) | |
parent | 8526756b61014f780348346ba5fdf0604a02d158 (diff) | |
download | CMake-a577d3c026e2efb8faf7af74c161f21a7c4b0e33.zip CMake-a577d3c026e2efb8faf7af74c161f21a7c4b0e33.tar.gz CMake-a577d3c026e2efb8faf7af74c161f21a7c4b0e33.tar.bz2 |
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.cxx | 10 | ||||
-rw-r--r-- | Source/cmGlobalNinjaGenerator.cxx | 4 | ||||
-rw-r--r-- | Source/cmGlobalUnixMakefileGenerator3.cxx | 19 | ||||
-rw-r--r-- | Source/cmLinkLineComputer.cxx | 10 | ||||
-rw-r--r-- | Source/cmListFileCache.cxx | 5 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 47 | ||||
-rw-r--r-- | Source/cmLocalGenerator.h | 15 | ||||
-rw-r--r-- | Source/cmLocalUnixMakefileGenerator3.cxx | 13 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 12 | ||||
-rw-r--r-- | Source/cmOutputConverter.cxx | 94 | ||||
-rw-r--r-- | Source/cmOutputConverter.h | 32 | ||||
-rw-r--r-- | Source/cmStateDirectory.cxx | 122 | ||||
-rw-r--r-- | Source/cmStateDirectory.h | 14 | ||||
-rw-r--r-- | Source/cmStatePrivate.h | 8 | ||||
-rw-r--r-- | Source/cmSystemTools.cxx | 14 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 6 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 4 | ||||
-rw-r--r-- | Source/cmcmd.cxx | 16 |
18 files changed, 188 insertions, 257 deletions
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 6b8757c..6b35842 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 5cf37da..565b951 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 837c59f..9c3de1e 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 480c005..a3f2968 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 2b98f20..4f7c959 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 c101ff3..4db9216 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 5ebf70c..993280a 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 a652c7b..3a65a80 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 1cc8434..4542672 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 ec54537..840fdb9 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 f1a8041..865df71 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 a0bfd28..9ae2861 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 4dab9ff..ce00dbb 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 4892644..a437ce2 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 ab42810..2fba13f 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 9f9c493..474f591 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 f84d246..29e361c 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 98946b6..727e412 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; |