1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-13 17:47:49 +08:00

cmOutputConverter: Adopt relative path conversion helpers

Move them up from cmLocalGenerator and out of cmStateDirectory.
This commit is contained in:
Brad King
2021-05-14 15:38:27 -04:00
parent 013ec595c8
commit 8526756b61
12 changed files with 142 additions and 177 deletions

View File

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

View File

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

View File

@@ -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
{

View File

@@ -462,16 +462,6 @@ public:
std::string const& GetCurrentBinaryDirectory() const;
std::string const& GetCurrentSourceDirectory() const;
/**
* Convert the given remote path to a relative path with respect to
* one of our common work directories. The path must use forward
* slashes and not already be escaped or quoted.
* The conversion is skipped if the paths are not both in the source
* or both in the binary tree.
*/
std::string MaybeRelativeToTopBinDir(std::string const& path) const;
std::string MaybeRelativeToCurBinDir(std::string const& path) const;
/**
* Generate a macOS application bundle Info.plist file.
*/
@@ -558,9 +548,6 @@ public:
cmProp GetRuleLauncher(cmGeneratorTarget* target, const std::string& prop);
protected:
std::string MaybeRelativeTo(std::string const& local_path,
std::string const& remote_path) const;
// The default implementation ignores the IncludePathStyle and always
// uses absolute paths. A generator may override this to use relative
// paths in some cases.

View File

@@ -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");

View File

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

View File

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

View File

@@ -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;
};

View File

@@ -24,41 +24,6 @@ static std::string const kBUILDSYSTEM_TARGETS = "BUILDSYSTEM_TARGETS";
static std::string const kSOURCE_DIR = "SOURCE_DIR";
static std::string const kSUBDIRECTORIES = "SUBDIRECTORIES";
void cmStateDirectory::ComputeRelativePathTopSource()
{
// Walk up the buildsystem directory tree to find the highest source
// directory that contains the current source directory.
cmStateSnapshot snapshot = this->Snapshot_;
for (cmStateSnapshot parent = snapshot.GetBuildsystemDirectoryParent();
parent.IsValid(); parent = parent.GetBuildsystemDirectoryParent()) {
if (cmSystemTools::IsSubDirectory(
snapshot.GetDirectory().GetCurrentSource(),
parent.GetDirectory().GetCurrentSource())) {
snapshot = parent;
}
}
this->DirectoryState->RelativePathTopSource =
snapshot.GetDirectory().GetCurrentSource();
}
void cmStateDirectory::ComputeRelativePathTopBinary()
{
// Walk up the buildsystem directory tree to find the highest binary
// directory that contains the current binary directory.
cmStateSnapshot snapshot = this->Snapshot_;
for (cmStateSnapshot parent = snapshot.GetBuildsystemDirectoryParent();
parent.IsValid(); parent = parent.GetBuildsystemDirectoryParent()) {
if (cmSystemTools::IsSubDirectory(
snapshot.GetDirectory().GetCurrentBinary(),
parent.GetDirectory().GetCurrentBinary())) {
snapshot = parent;
}
}
this->DirectoryState->RelativePathTopBinary =
snapshot.GetDirectory().GetCurrentBinary();
}
std::string const& cmStateDirectory::GetCurrentSource() const
{
return this->DirectoryState->Location;
@@ -70,9 +35,6 @@ void cmStateDirectory::SetCurrentSource(std::string const& dir)
loc = dir;
cmSystemTools::ConvertToUnixSlashes(loc);
loc = cmSystemTools::CollapseFullPath(loc);
this->ComputeRelativePathTopSource();
this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc);
}
@@ -87,60 +49,9 @@ void cmStateDirectory::SetCurrentBinary(std::string const& dir)
loc = dir;
cmSystemTools::ConvertToUnixSlashes(loc);
loc = cmSystemTools::CollapseFullPath(loc);
this->ComputeRelativePathTopBinary();
this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc);
}
std::string const& cmStateDirectory::GetRelativePathTopSource() const
{
return this->DirectoryState->RelativePathTopSource;
}
std::string const& cmStateDirectory::GetRelativePathTopBinary() const
{
return this->DirectoryState->RelativePathTopBinary;
}
void cmStateDirectory::SetRelativePathTopSource(const char* dir)
{
this->DirectoryState->RelativePathTopSource = dir;
}
void cmStateDirectory::SetRelativePathTopBinary(const char* dir)
{
this->DirectoryState->RelativePathTopBinary = dir;
}
bool cmStateDirectory::ContainsBoth(std::string const& local_path,
std::string const& remote_path) const
{
auto PathEqOrSubDir = [](std::string const& a, std::string const& b) {
return (cmSystemTools::ComparePath(a, b) ||
cmSystemTools::IsSubDirectory(a, b));
};
bool bothInBinary =
PathEqOrSubDir(local_path, this->GetRelativePathTopBinary()) &&
PathEqOrSubDir(remote_path, this->GetRelativePathTopBinary());
bool bothInSource =
PathEqOrSubDir(local_path, this->GetRelativePathTopSource()) &&
PathEqOrSubDir(remote_path, this->GetRelativePathTopSource());
return bothInBinary || bothInSource;
}
std::string cmStateDirectory::ConvertToRelPathIfContained(
std::string const& local_path, std::string const& remote_path) const
{
if (!this->ContainsBoth(local_path, remote_path)) {
return remote_path;
}
return cmSystemTools::ForceToRelativePath(local_path, remote_path);
}
cmStateDirectory::cmStateDirectory(
cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator iter,
const cmStateSnapshot& snapshot)

View File

@@ -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_;

View File

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

View File

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