cmGlobalGenerator: Add helper to split framework path
cmComputeLinkInformation and cmGlobalXCodeGenerator now rely on this method to handle framework paths.
This commit is contained in:
parent
350c1fd607
commit
40178f3c90
@ -8,6 +8,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include <cm/memory>
|
||||
#include <cm/optional>
|
||||
#include <cmext/algorithm>
|
||||
|
||||
#include "cmComputeLinkDepends.h"
|
||||
@ -1679,7 +1680,8 @@ void cmComputeLinkInformation::AddFrameworkItem(LinkEntry const& entry)
|
||||
std::string const& item = entry.Item.Value;
|
||||
|
||||
// Try to separate the framework name and path.
|
||||
if (!this->SplitFramework.find(item)) {
|
||||
auto fwItems = this->GlobalGenerator->SplitFrameworkPath(item);
|
||||
if (!fwItems) {
|
||||
std::ostringstream e;
|
||||
e << "Could not parse framework path \"" << item << "\" "
|
||||
<< "linked by target " << this->Target->GetName() << ".";
|
||||
@ -1687,8 +1689,8 @@ void cmComputeLinkInformation::AddFrameworkItem(LinkEntry const& entry)
|
||||
return;
|
||||
}
|
||||
|
||||
std::string fw_path = this->SplitFramework.match(1);
|
||||
std::string fw = this->SplitFramework.match(2);
|
||||
std::string fw_path = std::move(fwItems->first);
|
||||
std::string fw = std::move(fwItems->second);
|
||||
std::string full_fw = cmStrCat(fw_path, '/', fw, ".framework/", fw);
|
||||
|
||||
// Add the directory portion to the framework search path.
|
||||
@ -1739,9 +1741,6 @@ void cmComputeLinkInformation::ComputeFrameworkInfo()
|
||||
|
||||
this->FrameworkPathsEmitted.insert(implicitDirVec.begin(),
|
||||
implicitDirVec.end());
|
||||
|
||||
// Regular expression to extract a framework path and name.
|
||||
this->SplitFramework.compile("(.*)/(.*)\\.framework$");
|
||||
}
|
||||
|
||||
void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
|
||||
|
@ -205,7 +205,6 @@ private:
|
||||
void ComputeFrameworkInfo();
|
||||
void AddFrameworkPath(std::string const& p);
|
||||
std::set<std::string> FrameworkPathsEmitted;
|
||||
cmsys::RegularExpression SplitFramework;
|
||||
|
||||
// Linker search path computation.
|
||||
std::unique_ptr<cmOrderDirectories> OrderLinkerSearchPath;
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "cmsys/Directory.hxx"
|
||||
#include "cmsys/FStream.hxx"
|
||||
#include "cmsys/RegularExpression.hxx"
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# include <windows.h>
|
||||
@ -2522,6 +2523,36 @@ bool cmGlobalGenerator::NameResolvesToFramework(
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the file has no extension it's either a raw executable or might
|
||||
// be a direct reference to a binary within a framework (bad practice!).
|
||||
// This is where we change the path to point to the framework directory.
|
||||
// .tbd files also can be located in SDK frameworks (they are
|
||||
// placeholders for actual libraries shipped with the OS)
|
||||
cm::optional<std::pair<std::string, std::string>>
|
||||
cmGlobalGenerator::SplitFrameworkPath(const std::string& path) const
|
||||
{
|
||||
// Check for framework structure:
|
||||
// (/path/to/)?FwName.framework
|
||||
// or (/path/to/)?FwName.framework/FwName(.tbd)?
|
||||
// or (/path/to/)?FwName.framework/Versions/*/FwName(.tbd)?
|
||||
static cmsys::RegularExpression frameworkPath(
|
||||
"((.+)/)?(.+)\\.framework(/Versions/[^/]+)?(/(.+))?$");
|
||||
|
||||
auto ext = cmSystemTools::GetFilenameLastExtension(path);
|
||||
if ((ext.empty() || ext == ".tbd" || ext == ".framework") &&
|
||||
frameworkPath.find(path)) {
|
||||
auto name = frameworkPath.match(3);
|
||||
auto libname =
|
||||
cmSystemTools::GetFilenameWithoutExtension(frameworkPath.match(6));
|
||||
if (!libname.empty() && name != libname) {
|
||||
return cm::nullopt;
|
||||
}
|
||||
return std::pair<std::string, std::string>{ frameworkPath.match(2), name };
|
||||
}
|
||||
|
||||
return cm::nullopt;
|
||||
}
|
||||
|
||||
bool cmGlobalGenerator::CheckCMP0037(std::string const& targetName,
|
||||
std::string const& reason) const
|
||||
{
|
||||
|
@ -367,6 +367,10 @@ public:
|
||||
/** Determine if a name resolves to a framework on disk or a built target
|
||||
that is a framework. */
|
||||
bool NameResolvesToFramework(const std::string& libname) const;
|
||||
/** Split a framework path to the directory and name of the framework
|
||||
* returns std::nullopt if the path does not match with framework format */
|
||||
cm::optional<std::pair<std::string, std::string>> SplitFrameworkPath(
|
||||
const std::string& path) const;
|
||||
|
||||
cmMakefile* FindMakefile(const std::string& start_dir) const;
|
||||
cmLocalGenerator* FindLocalGenerator(cmDirectoryId const& id) const;
|
||||
|
@ -1154,47 +1154,25 @@ std::string GetSourcecodeValueFromFileExtension(
|
||||
return sourcecode;
|
||||
}
|
||||
|
||||
// If the file has no extension it's either a raw executable or might
|
||||
// be a direct reference to a binary within a framework (bad practice!).
|
||||
// This is where we change the path to point to the framework directory.
|
||||
// .tbd files also can be located in SDK frameworks (they are
|
||||
// placeholders for actual libraries shipped with the OS)
|
||||
std::string GetLibraryOrFrameworkPath(const std::string& path)
|
||||
} // anonymous
|
||||
|
||||
// Extracts the framework directory, if path matches the framework syntax
|
||||
// otherwise returns the path untouched
|
||||
std::string cmGlobalXCodeGenerator::GetLibraryOrFrameworkPath(
|
||||
const std::string& path) const
|
||||
{
|
||||
auto ext = cmSystemTools::GetFilenameLastExtension(path);
|
||||
if (ext.empty() || ext == ".tbd") {
|
||||
auto name = cmSystemTools::GetFilenameWithoutExtension(path);
|
||||
// Check for iOS framework structure:
|
||||
// FwName.framework/FwName (and also on macOS where FwName lib is a
|
||||
// symlink)
|
||||
auto parentDir = cmSystemTools::GetParentDirectory(path);
|
||||
auto parentName = cmSystemTools::GetFilenameWithoutExtension(parentDir);
|
||||
ext = cmSystemTools::GetFilenameLastExtension(parentDir);
|
||||
if (ext == ".framework" && name == parentName) {
|
||||
return parentDir;
|
||||
}
|
||||
// Check for macOS framework structure:
|
||||
// FwName.framework/Versions/*/FwName
|
||||
std::vector<std::string> components;
|
||||
cmSystemTools::SplitPath(path, components);
|
||||
if (components.size() > 3 &&
|
||||
components[components.size() - 3] == "Versions") {
|
||||
ext = cmSystemTools::GetFilenameLastExtension(
|
||||
components[components.size() - 4]);
|
||||
parentName = cmSystemTools::GetFilenameWithoutExtension(
|
||||
components[components.size() - 4]);
|
||||
if (ext == ".framework" && name == parentName) {
|
||||
components.erase(components.begin() + components.size() - 3,
|
||||
components.end());
|
||||
return cmSystemTools::JoinPath(components);
|
||||
}
|
||||
auto fwItems = this->SplitFrameworkPath(path);
|
||||
if (fwItems) {
|
||||
if (fwItems->first.empty()) {
|
||||
return cmStrCat(fwItems->second, ".framework");
|
||||
} else {
|
||||
return cmStrCat(fwItems->first, '/', fwItems->second, ".framework");
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
} // anonymous
|
||||
|
||||
cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
|
||||
const std::string& fullpath, cmGeneratorTarget* target,
|
||||
const std::string& lang, cmSourceFile* sf)
|
||||
@ -1217,7 +1195,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
|
||||
ext = ext.substr(1);
|
||||
}
|
||||
if (fileType.empty()) {
|
||||
path = GetLibraryOrFrameworkPath(path);
|
||||
path = this->GetLibraryOrFrameworkPath(path);
|
||||
ext = cmSystemTools::GetFilenameLastExtension(path);
|
||||
if (!ext.empty()) {
|
||||
ext = ext.substr(1);
|
||||
@ -3541,7 +3519,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
|
||||
} else {
|
||||
linkDir = libItem->Value.Value;
|
||||
}
|
||||
linkDir = GetLibraryOrFrameworkPath(linkDir);
|
||||
linkDir = this->GetLibraryOrFrameworkPath(linkDir);
|
||||
bool isFramework = cmSystemTools::IsPathToFramework(linkDir);
|
||||
linkDir = cmSystemTools::GetParentDirectory(linkDir);
|
||||
if (isFramework) {
|
||||
@ -3729,7 +3707,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
|
||||
if (cmSystemTools::FileIsFullPath(cleanPath)) {
|
||||
cleanPath = cmSystemTools::CollapseFullPath(cleanPath);
|
||||
}
|
||||
const auto libPath = GetLibraryOrFrameworkPath(cleanPath);
|
||||
const auto libPath = this->GetLibraryOrFrameworkPath(cleanPath);
|
||||
if (cmSystemTools::StringEndsWith(libPath.c_str(), ".framework")) {
|
||||
const auto fwName =
|
||||
cmSystemTools::GetFilenameWithoutExtension(libPath);
|
||||
|
@ -330,6 +330,8 @@ private:
|
||||
{
|
||||
}
|
||||
|
||||
std::string GetLibraryOrFrameworkPath(const std::string& path) const;
|
||||
|
||||
std::string GetObjectsDirectory(const std::string& projName,
|
||||
const std::string& configName,
|
||||
const cmGeneratorTarget* t,
|
||||
|
Loading…
Reference in New Issue
Block a user