From d8d0f3ec377380af07b3185e82a4d853f556e4f9 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 14 May 2021 11:46:48 -0400 Subject: Makefiles: Remove non-functioning relative path conversion In CMake 3.6 and below, running cmake --build . --target "$(pwd)/SomeTarget" with a Makefiles generator automatically converted the target name and invoked `make SomeTarget`. This made the build command work even though make "$(pwd)/SomeTarget" would fail. This behavior was not implemented for any other generators, and does not make sense because `cmake --build` is supposed to be a thin wrapper around the native build tool. It has also been broken since commit 8d47a20f13 (cmOutputConverter: use new ConvertToRelativePath signature internally, 2016-06-16, v3.7.0-rc1~90^2~1) because cmState's relative path conversion logic is not initialized in `cmake --build`. Remove the non-functioning code. --- Source/cmGlobalUnixMakefileGenerator3.cxx | 19 ------------------- 1 file changed, 19 deletions(-) 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 const& makeOptions) { - std::unique_ptr 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(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)); } -- cgit v0.12 From b4f07bfe5ad822b6e07372ceb06485aafc68a774 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 14 May 2021 15:27:56 -0400 Subject: cmStateDirectory: Fix comment on relative path top directory selection Fix the comment added by commit f6d4fa63f8 (cmStateDirectory: Comment relative path top directory selection approach, 2021-05-13) to describe the actual behavior. --- Source/cmStateDirectory.cxx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index a0bfd28..804b776 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -45,8 +45,7 @@ void cmStateDirectory::ComputeRelativePathTopSource() 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. + // directory that contains the current source directory. for (cmStateSnapshot const& snp : cmMakeRange(snapshots).advance(1)) { std::string currentSource = snp.GetDirectory().GetCurrentSource(); if (cmSystemTools::IsSubDirectory(result, currentSource)) { @@ -73,8 +72,7 @@ void cmStateDirectory::ComputeRelativePathTopBinary() 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. + // directory that contains the current binary directory. for (cmStateSnapshot const& snp : cmMakeRange(snapshots).advance(1)) { std::string currentBinary = snp.GetDirectory().GetCurrentBinary(); if (cmSystemTools::IsSubDirectory(result, currentBinary)) { -- cgit v0.12 From 2d9109df7cae62138d7d0347f4e90330d053424b Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 14 May 2021 15:29:36 -0400 Subject: cmStateDirectory: Remove network path logic from relative path top selection The logic skipping relative paths for build trees on network paths came from commit b5035770bc (BUG: On Windows network paths do not really work..., 2003-12-24, v2.4.0~3517). However, since commit ad4055f3e2 (ENH: Set RelativePathTopSource and RelativePathTopBinary independently ..., 2007-03-07, v2.6.0~2061) we effectively ignore this logic if the build tree is inside the source tree on a network path. Also, it is not clear that logic using `RelativePathTopBinary` is prepared for it to be empty. Remove the logic for now. If a problem comes up, we can choose a new approach. --- Source/cmStateDirectory.cxx | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index 804b776..31ee458 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -26,10 +26,6 @@ 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 snapshots; snapshots.push_back(snapshot); @@ -80,14 +76,7 @@ void cmStateDirectory::ComputeRelativePathTopBinary() } } - // 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(); - } + this->DirectoryState->RelativePathTopBinary = result; } std::string const& cmStateDirectory::GetCurrentSource() const -- cgit v0.12 From ea9b1d36b8cdf384903021d41ca665848895480f Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 14 May 2021 14:58:45 -0400 Subject: cmStateDirectory: Clarify relative path top selection logic Re-implement the same algorithm using direct iteration without collecting a vector first. --- Source/cmStateDirectory.cxx | 56 +++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index 31ee458..140ff0d 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -26,57 +26,37 @@ static std::string const kSUBDIRECTORIES = "SUBDIRECTORIES"; void cmStateDirectory::ComputeRelativePathTopSource() { - cmStateSnapshot snapshot = this->Snapshot_; - std::vector 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. - for (cmStateSnapshot const& snp : cmMakeRange(snapshots).advance(1)) { - std::string currentSource = snp.GetDirectory().GetCurrentSource(); - if (cmSystemTools::IsSubDirectory(result, currentSource)) { - result = currentSource; + 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 = result; + this->DirectoryState->RelativePathTopSource = + snapshot.GetDirectory().GetCurrentSource(); } void cmStateDirectory::ComputeRelativePathTopBinary() { - cmStateSnapshot snapshot = this->Snapshot_; - std::vector 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. - for (cmStateSnapshot const& snp : cmMakeRange(snapshots).advance(1)) { - std::string currentBinary = snp.GetDirectory().GetCurrentBinary(); - if (cmSystemTools::IsSubDirectory(result, currentBinary)) { - result = currentBinary; + 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 = result; + this->DirectoryState->RelativePathTopBinary = + snapshot.GetDirectory().GetCurrentBinary(); } std::string const& cmStateDirectory::GetCurrentSource() const -- cgit v0.12 From 5b3a71a83faf913aa4a9644779ae35c9d5eda733 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 14 May 2021 12:57:06 -0400 Subject: cmSystemTools: Adopt RelativeIfUnder helper This returns a relative path if it does not start in `../`. --- Source/cmFileAPICodemodel.cxx | 10 +--------- Source/cmSystemTools.cxx | 14 ++++++++++++++ Source/cmSystemTools.h | 6 ++++++ 3 files changed, 21 insertions(+), 9 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/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); -- cgit v0.12 From 4cb6a53bf524258c34440fc573ab6a9a4de0f0b2 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 14 May 2021 13:09:56 -0400 Subject: cmListFileCache: Simplify relative path conversion in backtraces Printing paths to CMake input files does not need to use the generator-wide relative path conversion rules because we are not actually generating a relative path for the build system that needs to be consistent with anything else. Instead, simply print a relative path if it does not need to start in `../`, and otherwise an absolute path. --- Source/cmListFileCache.cxx | 5 ++--- Source/cmTarget.cxx | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) 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/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'; } -- cgit v0.12 From d6fe1bdb6d79516a68a88d5f5a11d2531dae7074 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 14 May 2021 12:33:34 -0400 Subject: cmLocalGenerator: Localize logic mapping source path to object file name We select an object file name based on the path to its source file. Localize the logic for shortening this via relative paths. It does not need to use the generator-wide relative path conversion rules because we are not actually generating a relative path that needs to be consistent with anything else. --- Source/cmLocalGenerator.cxx | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index c101ff3..79ad46f 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -3532,6 +3532,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 +3556,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] != '.'; -- cgit v0.12 From 24bfdbcffba42fc0aac6ef3b575bd50a180d26ea Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 14 May 2021 12:43:35 -0400 Subject: cmLocalGenerator: Remove unused MaybeRelativeToCurSrcDir method With the recent update to `GetObjectFileNameWithoutTarget`, we no longer have any call sites for `MaybeRelativeToCurSrcDir`. It does not make sense for the generator to produce paths relative to the source tree in general, so remove the method. --- Source/cmLocalGenerator.cxx | 6 ------ Source/cmLocalGenerator.h | 1 - 2 files changed, 7 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 79ad46f..4a35909 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -3698,12 +3698,6 @@ std::string cmLocalGenerator::MaybeRelativeToCurBinDir( 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..1f8970f 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -471,7 +471,6 @@ public: */ 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. -- cgit v0.12 From 013ec595c8d6971c568cff4f8e457d90a6e8be88 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 14 May 2021 14:16:53 -0400 Subject: cmLocalGenerator: De-duplicate StateSnapshot member We have the member from the cmOutputConverter parent. --- Source/cmLocalGenerator.cxx | 1 - Source/cmLocalGenerator.h | 1 - Source/cmOutputConverter.h | 5 +++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 4a35909..3b01b1f 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; diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 1f8970f..0d65267 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -594,7 +594,6 @@ protected: virtual bool CheckDefinition(std::string const& define) const; cmMakefile* Makefile; - cmStateSnapshot StateSnapshot; cmListFileBacktrace DirectoryBacktrace; cmGlobalGenerator* GlobalGenerator; std::map UniqueObjectNamesMap; diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h index f1a8041..c67e74b 100644 --- a/Source/cmOutputConverter.h +++ b/Source/cmOutputConverter.h @@ -102,6 +102,9 @@ public: }; static FortranPreprocess GetFortranPreprocess(cm::string_view value); +protected: + cmStateSnapshot StateSnapshot; + private: cmState* GetState() const; @@ -111,7 +114,5 @@ 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; }; -- cgit v0.12 From 8526756b61014f780348346ba5fdf0604a02d158 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 14 May 2021 15:38:27 -0400 Subject: cmOutputConverter: Adopt relative path conversion helpers Move them up from cmLocalGenerator and out of cmStateDirectory. --- Source/cmGlobalNinjaGenerator.cxx | 4 +- Source/cmLinkLineComputer.cxx | 10 +--- Source/cmLocalGenerator.cxx | 19 ------- Source/cmLocalGenerator.h | 13 ----- Source/cmLocalUnixMakefileGenerator3.cxx | 13 ++--- Source/cmMakefileTargetGenerator.cxx | 12 +--- Source/cmOutputConverter.cxx | 94 ++++++++++++++++++++++++++++++++ Source/cmOutputConverter.h | 27 +++++++++ Source/cmStateDirectory.cxx | 89 ------------------------------ Source/cmStateDirectory.h | 14 ----- Source/cmStatePrivate.h | 8 --- Source/cmcmd.cxx | 16 ++++-- 12 files changed, 142 insertions(+), 177 deletions(-) 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(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/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/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 3b01b1f..4db9216 100644 --- a/Source/cmLocalGenerator.cxx +++ b/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 { diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 0d65267..993280a 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -463,16 +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; - - /** * Generate a macOS application bundle Info.plist file. */ void GenerateAppleInfoPList(cmGeneratorTarget* target, @@ -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. 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& 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 #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 c67e74b..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, @@ -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; }; diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index 140ff0d..9ae2861 100644 --- a/Source/cmStateDirectory.cxx +++ b/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::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::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 IncludeDirectories; std::vector IncludeDirectoryBacktraces; 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 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 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; -- cgit v0.12