diff options
author | Marc Chevrier <marc.chevrier@gmail.com> | 2022-09-15 17:09:07 +0200 |
---|---|---|
committer | Marc Chevrier <marc.chevrier@gmail.com> | 2022-09-21 16:14:36 +0200 |
commit | 0bd3efffbc97783bf8b1a6dcf3132a1bca84dce9 (patch) | |
tree | ce8505ac8a9c7a8e9c09a0ee0af5beebae522682 /Source | |
parent | 2ce95133d65ed44e69543b286e47d768dbceff2b (diff) | |
download | cmake-0bd3efffbc97783bf8b1a6dcf3132a1bca84dce9.tar.gz |
Genex LINK_LIBRARY: Add support for framework with postfix
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmComputeLinkInformation.cxx | 48 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 19 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.h | 57 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 36 |
4 files changed, 106 insertions, 54 deletions
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index cda70fc1ae..044f69f004 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1566,8 +1566,9 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry) if (target->IsFrameworkOnApple() && !this->GlobalGenerator->IsXcode()) { // Add the framework directory and the framework item itself - auto fwItems = this->GlobalGenerator->SplitFrameworkPath(item.Value, true); - if (!fwItems) { + auto fwDescriptor = this->GlobalGenerator->SplitFrameworkPath( + item.Value, cmGlobalGenerator::FrameworkFormat::Extended); + if (!fwDescriptor) { this->CMakeInstance->IssueMessage( MessageType::FATAL_ERROR, cmStrCat("Could not parse framework path \"", item.Value, @@ -1575,12 +1576,13 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry) item.Backtrace); return; } - if (!fwItems->first.empty()) { + if (!fwDescriptor->Directory.empty()) { // Add the directory portion to the framework search path. - this->AddFrameworkPath(fwItems->first); + this->AddFrameworkPath(fwDescriptor->Directory); } if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s)) { - this->Items.emplace_back(fwItems->second, ItemIsPath::Yes, target, + this->Items.emplace_back(fwDescriptor->GetLinkName(), ItemIsPath::Yes, + target, this->FindLibraryFeature(entry.Feature)); } else { this->Items.emplace_back( @@ -1851,9 +1853,11 @@ void cmComputeLinkInformation::AddFrameworkItem(LinkEntry const& entry) std::string const& item = entry.Item.Value; // Try to separate the framework name and path. - auto fwItems = - this->GlobalGenerator->SplitFrameworkPath(item, entry.Feature != DEFAULT); - if (!fwItems) { + auto fwDescriptor = this->GlobalGenerator->SplitFrameworkPath( + item, + entry.Feature == DEFAULT ? cmGlobalGenerator::FrameworkFormat::Relaxed + : cmGlobalGenerator::FrameworkFormat::Extended); + if (!fwDescriptor) { std::ostringstream e; e << "Could not parse framework path \"" << item << "\" " << "linked by target " << this->Target->GetName() << "."; @@ -1861,18 +1865,14 @@ void cmComputeLinkInformation::AddFrameworkItem(LinkEntry const& entry) return; } - std::string fw_path = std::move(fwItems->first); - std::string fw = std::move(fwItems->second); - std::string full_fw = cmStrCat(fw, ".framework/", fw); - + const std::string& fw_path = fwDescriptor->Directory; if (!fw_path.empty()) { - full_fw = cmStrCat(fw_path, '/', full_fw); // Add the directory portion to the framework search path. this->AddFrameworkPath(fw_path); } // add runtime information - this->AddLibraryRuntimeInfo(full_fw); + this->AddLibraryRuntimeInfo(fwDescriptor->GetFullPath()); if (entry.Feature == DEFAULT) { // ensure FRAMEWORK feature is loaded @@ -1887,9 +1887,9 @@ void cmComputeLinkInformation::AddFrameworkItem(LinkEntry const& entry) ? "FRAMEWORK" : entry.Feature)); } else { - this->Items.emplace_back(fw, ItemIsPath::Yes, nullptr, - this->FindLibraryFeature(entry.Feature == DEFAULT - ? "FRAMEWORK" + this->Items.emplace_back( + fwDescriptor->GetLinkName(), ItemIsPath::Yes, nullptr, + this->FindLibraryFeature(entry.Feature == DEFAULT ? "FRAMEWORK" : entry.Feature)); } } @@ -2252,15 +2252,11 @@ void cmComputeLinkInformation::AddLibraryRuntimeInfo( // It could be an Apple framework if (!is_shared_library) { - if (fullPath.find(".framework") != std::string::npos) { - static cmsys::RegularExpression splitFramework( - "^(.*)/(.*).framework/(.*)$"); - if (splitFramework.find(fullPath) && - (std::string::npos != - splitFramework.match(3).find(splitFramework.match(2)))) { - is_shared_library = true; - } - } + is_shared_library = + this->GlobalGenerator + ->SplitFrameworkPath(fullPath, + cmGlobalGenerator::FrameworkFormat::Strict) + .has_value(); } if (!is_shared_library) { diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 813052164c..6962b52c7c 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2563,9 +2563,9 @@ bool cmGlobalGenerator::NameResolvesToFramework( // 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>> +cm::optional<cmGlobalGenerator::FrameworkDescriptor> cmGlobalGenerator::SplitFrameworkPath(const std::string& path, - bool extendedFormat) const + FrameworkFormat format) const { // Check for framework structure: // (/path/to/)?FwName.framework @@ -2580,20 +2580,29 @@ cmGlobalGenerator::SplitFrameworkPath(const std::string& path, auto name = frameworkPath.match(3); auto libname = cmSystemTools::GetFilenameWithoutExtension(frameworkPath.match(6)); + if (format == FrameworkFormat::Strict && libname.empty()) { + return cm::nullopt; + } if (!libname.empty() && !cmHasPrefix(libname, name)) { return cm::nullopt; } - return std::pair<std::string, std::string>{ frameworkPath.match(2), name }; + + if (libname.empty() || name.size() == libname.size()) { + return FrameworkDescriptor{ frameworkPath.match(2), name }; + } + + return FrameworkDescriptor{ frameworkPath.match(2), name, + libname.substr(name.size()) }; } - if (extendedFormat) { + if (format == FrameworkFormat::Extended) { // path format can be more flexible: (/path/to/)?fwName(.framework)? auto fwDir = cmSystemTools::GetParentDirectory(path); auto name = cmSystemTools::GetFilenameLastExtension(path) == ".framework" ? cmSystemTools::GetFilenameWithoutExtension(path) : cmSystemTools::GetFilenameName(path); - return std::pair<std::string, std::string>{ fwDir, name }; + return FrameworkDescriptor{ fwDir, name }; } return cm::nullopt; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 6e3072bf5d..89b2ea8d74 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -17,6 +17,7 @@ #include <cm/optional> #include <cmext/algorithm> +#include <cmext/string_view> #include "cm_codecvt.hxx" @@ -367,13 +368,61 @@ 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 + /** Split a framework path to the directory and name of the framework as well + * as optiona; suffix. + * Returns std::nullopt if the path does not match with framework format * when extendedFormat is true, required format is relaxed (i.e. extension * `.framework' is optional). Used when FRAMEWORK link feature is * specified */ - cm::optional<std::pair<std::string, std::string>> SplitFrameworkPath( - const std::string& path, bool extendedFormat = false) const; + struct FrameworkDescriptor + { + FrameworkDescriptor(std::string directory, std::string name) + : Directory(std::move(directory)) + , Name(std::move(name)) + { + } + FrameworkDescriptor(std::string directory, std::string name, + std::string suffix) + : Directory(std::move(directory)) + , Name(std::move(name)) + , Suffix(std::move(suffix)) + { + } + std::string GetLinkName() const + { + return this->Suffix.empty() ? this->Name + : cmStrCat(this->Name, ',', this->Suffix); + } + std::string GetFullName() const + { + return cmStrCat(this->Name, ".framework/"_s, this->Name, this->Suffix); + } + std::string GetFrameworkPath() const + { + return this->Directory.empty() + ? cmStrCat(this->Name, ".framework"_s) + : cmStrCat(this->Directory, '/', this->Name, ".framework"_s); + } + std::string GetFullPath() const + { + return this->Directory.empty() + ? this->GetFullName() + : cmStrCat(this->Directory, '/', this->GetFullName()); + } + + const std::string Directory; + const std::string Name; + const std::string Suffix; + }; + enum class FrameworkFormat + { + Strict, + Relaxed, + Extended + }; + cm::optional<FrameworkDescriptor> SplitFrameworkPath( + const std::string& path, + FrameworkFormat format = FrameworkFormat::Relaxed) 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 2c455cf190..9739a4e0aa 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1192,13 +1192,9 @@ std::string GetTargetObjectDirArch(T const& target, std::string cmGlobalXCodeGenerator::GetLibraryOrFrameworkPath( const std::string& path) const { - auto fwItems = this->SplitFrameworkPath(path); - if (fwItems) { - if (fwItems->first.empty()) { - return cmStrCat(fwItems->second, ".framework"); - } else { - return cmStrCat(fwItems->first, '/', fwItems->second, ".framework"); - } + auto fwDescriptor = this->SplitFrameworkPath(path); + if (fwDescriptor) { + return fwDescriptor->GetFrameworkPath(); } return path; @@ -3641,9 +3637,10 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target) linkDir = libItem->Value.Value; } if (cmHasSuffix(libItem->GetFeatureName(), "FRAMEWORK"_s)) { - auto fwItems = this->SplitFrameworkPath(linkDir, true); - if (fwItems && !fwItems->first.empty()) { - linkDir = std::move(fwItems->first); + auto fwDescriptor = this->SplitFrameworkPath( + linkDir, cmGlobalGenerator::FrameworkFormat::Extended); + if (fwDescriptor && !fwDescriptor->Directory.empty()) { + linkDir = fwDescriptor->Directory; if (std::find(frameworkSearchPaths.begin(), frameworkSearchPaths.end(), linkDir) == frameworkSearchPaths.end()) { frameworkSearchPaths.push_back(linkDir); @@ -3839,13 +3836,14 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target) bool isFramework = cmHasSuffix(libName.GetFeatureName(), "FRAMEWORK"_s); if (isFramework) { - const auto fwItems = - this->SplitFrameworkPath(cleanPath, isFramework); - if (!fwItems->first.empty() && - emitted.insert(fwItems->first).second) { + const auto fwDescriptor = this->SplitFrameworkPath( + cleanPath, cmGlobalGenerator::FrameworkFormat::Extended); + if (!fwDescriptor->Directory.empty() && + emitted.insert(fwDescriptor->Directory).second) { // This is a search path we had not added before and it isn't // an implicit search path, so we need it - libPaths.Add("-F " + this->XCodeEscapePath(fwItems->first)); + libPaths.Add("-F " + + this->XCodeEscapePath(fwDescriptor->Directory)); } if (libName.GetFeatureName() == "__CMAKE_LINK_FRAMEWORK"_s) { // use the full path @@ -3853,10 +3851,10 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target) libName.GetFormattedItem(this->XCodeEscapePath(cleanPath)) .Value); } else { - libPaths.Add( - libName - .GetFormattedItem(this->XCodeEscapePath(fwItems->second)) - .Value); + libPaths.Add(libName + .GetFormattedItem(this->XCodeEscapePath( + fwDescriptor->GetLinkName())) + .Value); } } else { libPaths.Add( |