diff options
Diffstat (limited to 'Source/cmComputeLinkInformation.cxx')
-rw-r--r-- | Source/cmComputeLinkInformation.cxx | 150 |
1 files changed, 125 insertions, 25 deletions
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 4804565..91395e2 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -29,6 +29,7 @@ #include "cmSystemTools.h" #include "cmTarget.h" #include "cmValue.h" +#include "cmXcFramework.h" #include "cmake.h" // #define CM_COMPUTE_LINK_INFO_DEBUG @@ -373,6 +374,10 @@ cmComputeLinkInformation::cmComputeLinkInformation( this->LibraryFeatureDescriptors.emplace( "__CMAKE_LINK_FRAMEWORK", LibraryFeatureDescriptor{ "__CMAKE_LINK_FRAMEWORK", "<LIBRARY>" }); + // To link xcframework using a full path + this->LibraryFeatureDescriptors.emplace( + "__CMAKE_LINK_XCFRAMEWORK", + LibraryFeatureDescriptor{ "__CMAKE_LINK_XCFRAMEWORK", "<LIBRARY>" }); // Check the platform policy for missing soname case. this->NoSONameUsesPath = @@ -519,16 +524,16 @@ cmComputeLinkInformation::GetFrameworkPathsEmitted() const return this->FrameworkPathsEmitted; } -const std::set<const cmGeneratorTarget*>& -cmComputeLinkInformation::GetSharedLibrariesLinked() const +std::vector<std::string> const& +cmComputeLinkInformation::GetXcFrameworkHeaderPaths() const { - return this->SharedLibrariesLinked; + return this->XcFrameworkHeaderPaths; } -const std::vector<const cmGeneratorTarget*>& -cmComputeLinkInformation::GetObjectLibrariesLinked() const +const std::set<const cmGeneratorTarget*>& +cmComputeLinkInformation::GetSharedLibrariesLinked() const { - return this->ObjectLibrariesLinked; + return this->SharedLibrariesLinked; } bool cmComputeLinkInformation::Compute() @@ -1156,12 +1161,14 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry) this->AddItem(BT<std::string>(libName, item.Backtrace)); } } else if (tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) { - if (!tgt->HaveCxx20ModuleSources() && !tgt->HaveFortranSources(config)) { - // Ignore object library! - // Its object-files should already have been extracted for linking. - } else { - this->ObjectLibrariesLinked.push_back(entry.Target); - } + this->Items.emplace_back(entry.Item, ItemIsPath::No, entry.Target); + } else if (this->GlobalGenerator->IsXcode() && + !tgt->GetImportedXcFrameworkPath(config).empty()) { + this->Items.emplace_back( + tgt->GetImportedXcFrameworkPath(config), ItemIsPath::Yes, tgt, + this->FindLibraryFeature(entry.Feature == DEFAULT + ? "__CMAKE_LINK_XCFRAMEWORK" + : entry.Feature)); } else { // Decide whether to use an import library. cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config) @@ -1201,6 +1208,25 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry) this->AddRuntimeDLL(tgt); } } + + auto xcFrameworkPath = tgt->GetImportedXcFrameworkPath(config); + if (!xcFrameworkPath.empty()) { + auto plist = cmParseXcFrameworkPlist(xcFrameworkPath, *this->Makefile, + item.Backtrace); + if (!plist) { + return; + } + if (auto const* library = + plist->SelectSuitableLibrary(*this->Makefile, item.Backtrace)) { + if (!library->HeadersPath.empty()) { + this->AddXcFrameworkHeaderPath(cmStrCat(xcFrameworkPath, '/', + library->LibraryIdentifier, + '/', library->HeadersPath)); + } + } else { + return; + } + } } else { // This is not a CMake target. Use the name given. if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s) || @@ -1209,6 +1235,12 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry) this->Target->IsApple())) { // This is a framework. this->AddFrameworkItem(entry); + } else if (cmHasSuffix(entry.Feature, "XCFRAMEWORK"_s) || + (entry.Feature == DEFAULT && + cmSystemTools::IsPathToXcFramework(item.Value) && + this->Target->IsApple())) { + // This is a framework. + this->AddXcFrameworkItem(entry); } else if (cmSystemTools::FileIsFullPath(item.Value)) { if (cmSystemTools::FileIsDirectory(item.Value)) { // This is a directory. @@ -1592,7 +1624,9 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry) this->OldLinkDirItems.push_back(item.Value); } - if (target->IsFrameworkOnApple()) { + const bool isImportedFrameworkFolderOnApple = + target->IsImportedFrameworkFolderOnApple(this->Config); + if (target->IsFrameworkOnApple() || isImportedFrameworkFolderOnApple) { // Add the framework directory and the framework item itself auto fwDescriptor = this->GlobalGenerator->SplitFrameworkPath( item.Value, cmGlobalGenerator::FrameworkFormat::Extended); @@ -1610,16 +1644,33 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry) } if (this->GlobalGenerator->IsXcode()) { - this->Items.emplace_back( - item, ItemIsPath::Yes, target, - this->FindLibraryFeature(entry.Feature == DEFAULT - ? "__CMAKE_LINK_FRAMEWORK" - : entry.Feature)); + if (isImportedFrameworkFolderOnApple) { + if (entry.Feature == DEFAULT) { + this->AddLibraryFeature("FRAMEWORK"); + this->Items.emplace_back(item, ItemIsPath::Yes, target, + this->FindLibraryFeature("FRAMEWORK")); + } else { + this->Items.emplace_back(item, ItemIsPath::Yes, target, + this->FindLibraryFeature(entry.Feature)); + } + } else { + this->Items.emplace_back( + item, ItemIsPath::Yes, target, + this->FindLibraryFeature(entry.Feature == DEFAULT + ? "__CMAKE_LINK_FRAMEWORK" + : entry.Feature)); + } } else { if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s)) { this->Items.emplace_back(fwDescriptor->GetLinkName(), ItemIsPath::Yes, target, this->FindLibraryFeature(entry.Feature)); + } else if (entry.Feature == DEFAULT && + isImportedFrameworkFolderOnApple) { + this->AddLibraryFeature("FRAMEWORK"); + this->Items.emplace_back(fwDescriptor->GetLinkName(), ItemIsPath::Yes, + target, + this->FindLibraryFeature("FRAMEWORK")); } else { this->Items.emplace_back( item, ItemIsPath::Yes, target, @@ -1929,6 +1980,46 @@ void cmComputeLinkInformation::AddFrameworkItem(LinkEntry const& entry) } } +void cmComputeLinkInformation::AddXcFrameworkItem(LinkEntry const& entry) +{ + auto plist = cmParseXcFrameworkPlist(entry.Item.Value, *this->Makefile, + entry.Item.Backtrace); + if (!plist) { + return; + } + + if (auto const* lib = + plist->SelectSuitableLibrary(*this->Makefile, entry.Item.Backtrace)) { + if (this->GlobalGenerator->IsXcode()) { + this->Items.emplace_back( + entry.Item.Value, ItemIsPath::Yes, nullptr, + this->FindLibraryFeature(entry.Feature == DEFAULT + ? "__CMAKE_LINK_XCFRAMEWORK" + : entry.Feature)); + } else { + auto libraryPath = cmStrCat( + entry.Item.Value, '/', lib->LibraryIdentifier, '/', lib->LibraryPath); + LinkEntry libraryEntry( + BT<std::string>(libraryPath, entry.Item.Backtrace), entry.Target); + + if (cmSystemTools::IsPathToFramework(libraryPath) && + this->Target->IsApple()) { + // This is a framework. + this->AddFrameworkItem(libraryEntry); + } else { + this->Depends.push_back(libraryPath); + this->AddFullItem(libraryEntry); + this->AddLibraryRuntimeInfo(libraryPath); + if (!lib->HeadersPath.empty()) { + this->AddXcFrameworkHeaderPath(cmStrCat(entry.Item.Value, '/', + lib->LibraryIdentifier, '/', + lib->HeadersPath)); + } + } + } + } +} + void cmComputeLinkInformation::DropDirectoryItem(BT<std::string> const& item) { // A full path to a directory was found as a link item. Warn the @@ -1966,6 +2057,11 @@ void cmComputeLinkInformation::AddFrameworkPath(std::string const& p) } } +void cmComputeLinkInformation::AddXcFrameworkHeaderPath(std::string const& p) +{ + this->XcFrameworkHeaderPaths.push_back(p); +} + bool cmComputeLinkInformation::CheckSharedLibNoSOName(LinkEntry const& entry) { // This platform will use the path to a library as its soname if the @@ -2235,16 +2331,20 @@ void cmComputeLinkInformation::AddLibraryRuntimeInfo( if (target->GetType() != cmStateEnums::SHARED_LIBRARY) { return; } + auto const* info = target->GetImportInfo(this->Config); // Try to get the soname of the library. Only files with this name // could possibly conflict. - std::string soName = target->GetSOName(this->Config); - const char* soname = soName.empty() ? nullptr : soName.c_str(); - - // Include this library in the runtime path ordering. - this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname); - if (this->LinkWithRuntimePath) { - this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname); + const char* soname = + (!info || info->SOName.empty()) ? nullptr : info->SOName.c_str(); + + // If this shared library has a known runtime artifact (IMPORTED_LOCATION), + // include its location in the runtime path ordering. + if (!info || !info->Location.empty()) { + this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname); + if (this->LinkWithRuntimePath) { + this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname); + } } } |