summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2022-02-10 18:16:18 (GMT)
committerMarc Chevrier <marc.chevrier@gmail.com>2022-02-13 14:39:14 (GMT)
commit40178f3c908795a993148553a04be25748942efc (patch)
treef5fbc0d7f48fb80a450fbf438ef21b8376d69ac3 /Source
parent350c1fd60717fc4bd4a1ec32baefc510d8caa6bd (diff)
downloadCMake-40178f3c908795a993148553a04be25748942efc.zip
CMake-40178f3c908795a993148553a04be25748942efc.tar.gz
CMake-40178f3c908795a993148553a04be25748942efc.tar.bz2
cmGlobalGenerator: Add helper to split framework path
cmComputeLinkInformation and cmGlobalXCodeGenerator now rely on this method to handle framework paths.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmComputeLinkInformation.cxx11
-rw-r--r--Source/cmComputeLinkInformation.h1
-rw-r--r--Source/cmGlobalGenerator.cxx31
-rw-r--r--Source/cmGlobalGenerator.h4
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx54
-rw-r--r--Source/cmGlobalXCodeGenerator.h2
6 files changed, 58 insertions, 45 deletions
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 15e9d60..16f2003 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -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)
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index ce9f393..ccb22bd 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -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;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 156ecce..79d637d 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -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
{
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index a43d4a6..683968e 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -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;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 489c7fb..7a8bbcd 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -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);
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index ff6ffe8..98cebef 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -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,