macOS: Add support for linking against .xcframework folders
Issue: #21752stage/master/nightly/2023/07/27^2
parent
93ed53790c
commit
7050ac56a1
|
@ -66,6 +66,12 @@ Each ``<item>`` may be:
|
|||
:ref:`usage requirement <Target Usage Requirements>`. This has the same
|
||||
effect as passing the framework directory as an include directory.
|
||||
|
||||
.. versionadded:: 3.28
|
||||
|
||||
The library file may point to a ``.xcframework`` folder on macOS. If it
|
||||
does, the target will get the selected library's ``Headers`` directory as
|
||||
a usage requirement.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
On :ref:`Visual Studio Generators` for VS 2010 and above, library files
|
||||
ending in ``.targets`` will be treated as MSBuild targets files and
|
||||
|
|
|
@ -20,6 +20,12 @@ non-imported targets.
|
|||
For frameworks on macOS, this may be the location of the framework folder
|
||||
itself.
|
||||
|
||||
.. versionadded:: 3.28
|
||||
|
||||
This may be the location of a ``.xcframework`` folder on macOS. If it is,
|
||||
any target that links against it will get the selected library's ``Headers``
|
||||
directory as a usage requirement.
|
||||
|
||||
The ``IMPORTED_LOCATION`` target property may be overridden for a
|
||||
given configuration ``<CONFIG>`` by the configuration-specific
|
||||
:prop_tgt:`IMPORTED_LOCATION_<CONFIG>` target property. Furthermore,
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
xcframework-target-link-libraries
|
||||
---------------------------------
|
||||
|
||||
* Targets may now link against an ``.xcframework`` folder in
|
||||
:command:`target_link_libraries`.
|
||||
* The :prop_tgt:`IMPORTED_LOCATION` property of a target may now be an
|
||||
``.xcframework`` folder.
|
|
@ -371,6 +371,8 @@ add_library(
|
|||
cmNewLineStyle.cxx
|
||||
cmOrderDirectories.cxx
|
||||
cmOrderDirectories.h
|
||||
cmPlistParser.cxx
|
||||
cmPlistParser.h
|
||||
cmPolicies.h
|
||||
cmPolicies.cxx
|
||||
cmProcessOutput.cxx
|
||||
|
@ -451,6 +453,8 @@ add_library(
|
|||
cmWorkerPool.h
|
||||
cmWorkingDirectory.cxx
|
||||
cmWorkingDirectory.h
|
||||
cmXcFramework.cxx
|
||||
cmXcFramework.h
|
||||
cmXMLParser.cxx
|
||||
cmXMLParser.h
|
||||
cmXMLSafe.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,6 +524,12 @@ cmComputeLinkInformation::GetFrameworkPathsEmitted() const
|
|||
return this->FrameworkPathsEmitted;
|
||||
}
|
||||
|
||||
std::vector<std::string> const&
|
||||
cmComputeLinkInformation::GetXcFrameworkHeaderPaths() const
|
||||
{
|
||||
return this->XcFrameworkHeaderPaths;
|
||||
}
|
||||
|
||||
const std::set<const cmGeneratorTarget*>&
|
||||
cmComputeLinkInformation::GetSharedLibrariesLinked() const
|
||||
{
|
||||
|
@ -1159,6 +1170,13 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry)
|
|||
} else {
|
||||
this->ObjectLibrariesLinked.push_back(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)
|
||||
|
@ -1198,6 +1216,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) ||
|
||||
|
@ -1206,6 +1243,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.
|
||||
|
@ -1945,6 +1988,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
|
||||
|
@ -1982,6 +2065,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
|
||||
|
|
|
@ -88,6 +88,7 @@ public:
|
|||
std::vector<std::string> const& GetDepends() const;
|
||||
std::vector<std::string> const& GetFrameworkPaths() const;
|
||||
std::set<std::string> const& GetFrameworkPathsEmitted() const;
|
||||
std::vector<std::string> const& GetXcFrameworkHeaderPaths() const;
|
||||
std::string GetLinkLanguage() const { return this->LinkLanguage; }
|
||||
std::vector<std::string> const& GetRuntimeSearchPath() const;
|
||||
std::string const& GetRuntimeFlag() const { return this->RuntimeFlag; }
|
||||
|
@ -132,6 +133,7 @@ private:
|
|||
std::vector<std::string> Directories;
|
||||
std::vector<std::string> Depends;
|
||||
std::vector<std::string> FrameworkPaths;
|
||||
std::vector<std::string> XcFrameworkHeaderPaths;
|
||||
std::vector<std::string> RuntimeSearchPath;
|
||||
std::set<cmGeneratorTarget const*> SharedLibrariesLinked;
|
||||
std::vector<cmGeneratorTarget const*> ObjectLibrariesLinked;
|
||||
|
@ -204,6 +206,7 @@ private:
|
|||
bool CheckImplicitDirItem(LinkEntry const& entry);
|
||||
void AddUserItem(LinkEntry const& entry, bool pathNotKnown);
|
||||
void AddFrameworkItem(LinkEntry const& entry);
|
||||
void AddXcFrameworkItem(LinkEntry const& entry);
|
||||
void DropDirectoryItem(BT<std::string> const& item);
|
||||
bool CheckSharedLibNoSOName(LinkEntry const& entry);
|
||||
void AddSharedLibNoSOName(LinkEntry const& entry);
|
||||
|
@ -214,6 +217,8 @@ private:
|
|||
void AddFrameworkPath(std::string const& p);
|
||||
std::set<std::string> FrameworkPathsEmitted;
|
||||
|
||||
void AddXcFrameworkHeaderPath(std::string const& p);
|
||||
|
||||
// Linker search path computation.
|
||||
std::unique_ptr<cmOrderDirectories> OrderLinkerSearchPath;
|
||||
bool FinishLinkerSearchDirectories();
|
||||
|
|
|
@ -8874,6 +8874,47 @@ std::string cmGeneratorTarget::GenerateHeaderSetVerificationFile(
|
|||
return filename;
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::GetImportedXcFrameworkPath(
|
||||
const std::string& config) const
|
||||
{
|
||||
if (!(this->IsApple() && this->IsImported() &&
|
||||
(this->GetType() == cmStateEnums::SHARED_LIBRARY ||
|
||||
this->GetType() == cmStateEnums::STATIC_LIBRARY ||
|
||||
this->GetType() == cmStateEnums::UNKNOWN_LIBRARY))) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string desiredConfig = config;
|
||||
if (config.empty()) {
|
||||
desiredConfig = "NOCONFIG";
|
||||
}
|
||||
|
||||
std::string result;
|
||||
|
||||
cmValue loc = nullptr;
|
||||
cmValue imp = nullptr;
|
||||
std::string suffix;
|
||||
|
||||
if (this->Target->GetMappedConfig(desiredConfig, loc, imp, suffix)) {
|
||||
if (loc) {
|
||||
result = *loc;
|
||||
} else {
|
||||
std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
|
||||
if (cmValue configLocation = this->GetProperty(impProp)) {
|
||||
result = *configLocation;
|
||||
} else if (cmValue location = this->GetProperty("IMPORTED_LOCATION")) {
|
||||
result = *location;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmSystemTools::IsPathToXcFramework(result)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::HaveFortranSources(std::string const& config) const
|
||||
{
|
||||
auto sources = cmGeneratorTarget::GetSourceFiles(config);
|
||||
|
|
|
@ -926,6 +926,8 @@ public:
|
|||
cmSourceFile& source, const std::string& dir,
|
||||
cm::optional<std::set<std::string>>& languages) const;
|
||||
|
||||
std::string GetImportedXcFrameworkPath(const std::string& config) const;
|
||||
|
||||
private:
|
||||
void AddSourceCommon(const std::string& src, bool before = false);
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "cmXCodeObject.h"
|
||||
#include "cmXCodeScheme.h"
|
||||
#include "cmXMLWriter.h"
|
||||
#include "cmXcFramework.h"
|
||||
#include "cmake.h"
|
||||
|
||||
#if !defined(CMAKE_BOOTSTRAP) && defined(__APPLE__)
|
||||
|
@ -1061,12 +1062,14 @@ bool IsLinkPhaseLibraryExtension(const std::string& fileExt)
|
|||
{
|
||||
// Empty file extension is a special case for paths to framework's
|
||||
// internal binary which could be MyFw.framework/Versions/*/MyFw
|
||||
return (fileExt == ".framework" || fileExt == ".a" || fileExt == ".o" ||
|
||||
fileExt == ".dylib" || fileExt == ".tbd" || fileExt.empty());
|
||||
return (fileExt == ".framework" || fileExt == ".xcframework" ||
|
||||
fileExt == ".a" || fileExt == ".o" || fileExt == ".dylib" ||
|
||||
fileExt == ".tbd" || fileExt.empty());
|
||||
}
|
||||
bool IsLibraryType(const std::string& fileType)
|
||||
{
|
||||
return (fileType == "wrapper.framework" || fileType == "archive.ar" ||
|
||||
return (fileType == "wrapper.framework" ||
|
||||
fileType == "wrapper.xcframework" || fileType == "archive.ar" ||
|
||||
fileType == "compiled.mach-o.objfile" ||
|
||||
fileType == "compiled.mach-o.dylib" ||
|
||||
fileType == "compiled.mach-o.executable" ||
|
||||
|
@ -1079,6 +1082,9 @@ std::string GetDirectoryValueFromFileExtension(const std::string& dirExt)
|
|||
if (ext == "framework") {
|
||||
return "wrapper.framework";
|
||||
}
|
||||
if (ext == "xcframework") {
|
||||
return "wrapper.xcframework";
|
||||
}
|
||||
if (ext == "xcassets") {
|
||||
return "folder.assetcatalog";
|
||||
}
|
||||
|
@ -3607,6 +3613,8 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
|
|||
bool canUseLinkPhase = !libItem.HasFeature() ||
|
||||
libItem.GetFeatureName() == "__CMAKE_LINK_FRAMEWORK"_s ||
|
||||
libItem.GetFeatureName() == "FRAMEWORK"_s ||
|
||||
libItem.GetFeatureName() == "__CMAKE_LINK_XCFRAMEWORK"_s ||
|
||||
libItem.GetFeatureName() == "XCFRAMEWORK"_s ||
|
||||
libItem.GetFeatureName() == "WEAK_FRAMEWORK"_s ||
|
||||
libItem.GetFeatureName() == "WEAK_LIBRARY"_s;
|
||||
if (canUseLinkPhase) {
|
||||
|
@ -3917,12 +3925,14 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
|
|||
if (cmSystemTools::FileIsFullPath(cleanPath)) {
|
||||
cleanPath = cmSystemTools::CollapseFullPath(cleanPath);
|
||||
}
|
||||
bool isFramework =
|
||||
bool isXcFramework =
|
||||
cmHasSuffix(libName.GetFeatureName(), "XCFRAMEWORK"_s);
|
||||
bool isFramework = !isXcFramework &&
|
||||
cmHasSuffix(libName.GetFeatureName(), "FRAMEWORK"_s);
|
||||
if (isFramework) {
|
||||
const auto fwDescriptor = this->SplitFrameworkPath(
|
||||
cleanPath, cmGlobalGenerator::FrameworkFormat::Extended);
|
||||
if (!fwDescriptor->Directory.empty() &&
|
||||
if (isFramework && !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
|
||||
|
@ -3940,13 +3950,54 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
|
|||
fwDescriptor->GetLinkName()))
|
||||
.Value);
|
||||
}
|
||||
} else if (isXcFramework) {
|
||||
auto plist = cmParseXcFrameworkPlist(
|
||||
cleanPath, *this->Makefiles.front(), libName.Value.Backtrace);
|
||||
if (!plist) {
|
||||
return;
|
||||
}
|
||||
if (auto const* library = plist->SelectSuitableLibrary(
|
||||
*this->Makefiles.front(), libName.Value.Backtrace)) {
|
||||
auto libraryPath =
|
||||
cmStrCat(cleanPath, '/', library->LibraryIdentifier, '/',
|
||||
library->LibraryPath);
|
||||
if (auto const fwDescriptor = this->SplitFrameworkPath(
|
||||
libraryPath,
|
||||
cmGlobalGenerator::FrameworkFormat::Relaxed)) {
|
||||
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
|
||||
fwSearchPaths.Add(
|
||||
this->XCodeEscapePath(fwDescriptor->Directory));
|
||||
}
|
||||
libPaths.Add(cmStrCat(
|
||||
"-framework ",
|
||||
this->XCodeEscapePath(fwDescriptor->GetLinkName())));
|
||||
} else {
|
||||
libPaths.Add(
|
||||
libName.GetFormattedItem(this->XCodeEscapePath(libraryPath))
|
||||
.Value);
|
||||
if (!library->HeadersPath.empty()) {
|
||||
this->AppendBuildSettingAttribute(
|
||||
target, "HEADER_SEARCH_PATHS",
|
||||
this->CreateString(this->XCodeEscapePath(
|
||||
cmStrCat(cleanPath, '/', library->LibraryIdentifier, '/',
|
||||
library->HeadersPath))),
|
||||
configName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
libPaths.Add(
|
||||
libName.GetFormattedItem(this->XCodeEscapePath(cleanPath))
|
||||
.Value);
|
||||
}
|
||||
if ((!libName.Target || libName.Target->IsImported()) &&
|
||||
(isFramework || IsLinkPhaseLibraryExtension(cleanPath))) {
|
||||
(isFramework || isXcFramework ||
|
||||
IsLinkPhaseLibraryExtension(cleanPath))) {
|
||||
// Create file reference for embedding
|
||||
auto it = this->ExternalLibRefs.find(cleanPath);
|
||||
if (it == this->ExternalLibRefs.end()) {
|
||||
|
|
|
@ -1659,6 +1659,8 @@ std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
|
|||
this->AppendFlags(compileFlags, mf->GetDefineFlags());
|
||||
this->AppendFlags(compileFlags,
|
||||
this->GetFrameworkFlags(lang, config, target));
|
||||
this->AppendFlags(compileFlags,
|
||||
this->GetXcFrameworkFlags(lang, config, target));
|
||||
|
||||
if (!compileFlags.empty()) {
|
||||
flags.emplace_back(std::move(compileFlags));
|
||||
|
@ -1724,6 +1726,43 @@ std::string cmLocalGenerator::GetFrameworkFlags(std::string const& lang,
|
|||
return flags;
|
||||
}
|
||||
|
||||
std::string cmLocalGenerator::GetXcFrameworkFlags(std::string const& lang,
|
||||
std::string const& config,
|
||||
cmGeneratorTarget* target)
|
||||
{
|
||||
cmLocalGenerator* lg = target->GetLocalGenerator();
|
||||
cmMakefile* mf = lg->GetMakefile();
|
||||
|
||||
if (!target->IsApple()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
cmValue includeSearchFlag =
|
||||
mf->GetDefinition(cmStrCat("CMAKE_INCLUDE_FLAG_", lang));
|
||||
cmValue sysIncludeSearchFlag =
|
||||
mf->GetDefinition(cmStrCat("CMAKE_INCLUDE_SYSTEM_FLAG_", lang));
|
||||
|
||||
if (!includeSearchFlag && !sysIncludeSearchFlag) {
|
||||
return std::string{};
|
||||
}
|
||||
|
||||
std::string flags;
|
||||
if (cmComputeLinkInformation* cli = target->GetLinkInformation(config)) {
|
||||
std::vector<std::string> const& paths = cli->GetXcFrameworkHeaderPaths();
|
||||
for (std::string const& path : paths) {
|
||||
if (sysIncludeSearchFlag &&
|
||||
target->IsSystemIncludeDirectory(path, config, lang)) {
|
||||
flags += *sysIncludeSearchFlag;
|
||||
} else {
|
||||
flags += *includeSearchFlag;
|
||||
}
|
||||
flags += lg->ConvertToOutputFormat(path, cmOutputConverter::SHELL);
|
||||
flags += " ";
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
void cmLocalGenerator::GetTargetDefines(cmGeneratorTarget const* target,
|
||||
std::string const& config,
|
||||
std::string const& lang,
|
||||
|
|
|
@ -520,6 +520,9 @@ public:
|
|||
std::string GetFrameworkFlags(std::string const& l,
|
||||
std::string const& config,
|
||||
cmGeneratorTarget* target);
|
||||
std::string GetXcFrameworkFlags(std::string const& l,
|
||||
std::string const& config,
|
||||
cmGeneratorTarget* target);
|
||||
virtual std::string GetTargetFortranFlags(cmGeneratorTarget const* target,
|
||||
std::string const& config);
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmPlistParser.h"
|
||||
|
||||
#include <cm3p/json/reader.h>
|
||||
#include <cm3p/json/value.h>
|
||||
|
||||
#include "cmUVProcessChain.h"
|
||||
#include "cmUVStream.h"
|
||||
|
||||
cm::optional<Json::Value> cmParsePlist(const std::string& filename)
|
||||
{
|
||||
cmUVProcessChainBuilder builder;
|
||||
builder.AddCommand(
|
||||
{ "/usr/bin/plutil", "-convert", "json", "-o", "-", filename });
|
||||
builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT);
|
||||
|
||||
auto chain = builder.Start();
|
||||
chain.Wait();
|
||||
|
||||
auto const& status = chain.GetStatus(0);
|
||||
if (status.ExitStatus != 0) {
|
||||
return cm::nullopt;
|
||||
}
|
||||
|
||||
Json::Reader reader;
|
||||
Json::Value value;
|
||||
cmUVPipeIStream outputStream(chain.GetLoop(), chain.OutputStream());
|
||||
if (!reader.parse(outputStream, value)) {
|
||||
return cm::nullopt;
|
||||
}
|
||||
return cm::optional<Json::Value>(value);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <cm/optional>
|
||||
|
||||
namespace Json {
|
||||
class Value;
|
||||
}
|
||||
|
||||
cm::optional<Json::Value> cmParsePlist(const std::string& filename);
|
|
@ -1900,6 +1900,12 @@ bool cmSystemTools::IsPathToFramework(const std::string& path)
|
|||
cmHasLiteralSuffix(path, ".framework"));
|
||||
}
|
||||
|
||||
bool cmSystemTools::IsPathToXcFramework(const std::string& path)
|
||||
{
|
||||
return (cmSystemTools::FileIsFullPath(path) &&
|
||||
cmHasLiteralSuffix(path, ".xcframework"));
|
||||
}
|
||||
|
||||
bool cmSystemTools::IsPathToMacOSSharedLibrary(const std::string& path)
|
||||
{
|
||||
return (cmSystemTools::FileIsFullPath(path) &&
|
||||
|
|
|
@ -111,6 +111,9 @@ public:
|
|||
//! Return true if the path is a framework
|
||||
static bool IsPathToFramework(const std::string& path);
|
||||
|
||||
//! Return true if the path is a xcframework
|
||||
static bool IsPathToXcFramework(const std::string& path);
|
||||
|
||||
//! Return true if the path is a macOS non-framework shared library (aka
|
||||
//! .dylib)
|
||||
static bool IsPathToMacOSSharedLibrary(const std::string& path);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "cmSystemTools.h"
|
||||
#include "cmTargetPropertyComputer.h"
|
||||
#include "cmValue.h"
|
||||
#include "cmXcFramework.h"
|
||||
#include "cmake.h"
|
||||
|
||||
template <>
|
||||
|
@ -2800,6 +2801,25 @@ std::string cmTarget::ImportedGetFullPath(
|
|||
}
|
||||
}
|
||||
}
|
||||
if (this->IsApple() &&
|
||||
(this->impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
|
||||
this->impl->TargetType == cmStateEnums::STATIC_LIBRARY ||
|
||||
this->impl->TargetType == cmStateEnums::UNKNOWN_LIBRARY) &&
|
||||
cmSystemTools::IsPathToXcFramework(result)) {
|
||||
auto plist = cmParseXcFrameworkPlist(result, *this->impl->Makefile,
|
||||
this->impl->Backtrace);
|
||||
if (!plist) {
|
||||
return "";
|
||||
}
|
||||
auto const* library = plist->SelectSuitableLibrary(
|
||||
*this->impl->Makefile, this->impl->Backtrace);
|
||||
if (library) {
|
||||
result = cmStrCat(result, '/', library->LibraryIdentifier, '/',
|
||||
library->LibraryPath);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case cmStateEnums::ImportLibraryArtifact:
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmXcFramework.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include <cm3p/json/value.h>
|
||||
|
||||
#include "cmJSONHelpers.h"
|
||||
#include "cmJSONState.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmPlistParser.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmake.h"
|
||||
|
||||
namespace {
|
||||
struct PlistMetadata
|
||||
{
|
||||
std::string CFBundlePackageType;
|
||||
std::string XCFrameworkFormatVersion;
|
||||
};
|
||||
|
||||
auto const PlistMetadataHelper =
|
||||
cmJSONHelperBuilder::Object<PlistMetadata>{}
|
||||
.Bind("CFBundlePackageType"_s, &PlistMetadata::CFBundlePackageType,
|
||||
cmJSONHelperBuilder::String())
|
||||
.Bind("XCFrameworkFormatVersion"_s,
|
||||
&PlistMetadata::XCFrameworkFormatVersion,
|
||||
cmJSONHelperBuilder::String());
|
||||
|
||||
bool PlistSupportedPlatformHelper(
|
||||
cmXcFrameworkPlistSupportedPlatform& platform, const Json::Value* value,
|
||||
cmJSONState* /*state*/)
|
||||
{
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!value->isString()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value->asString() == "macos") {
|
||||
platform = cmXcFrameworkPlistSupportedPlatform::macOS;
|
||||
return true;
|
||||
}
|
||||
if (value->asString() == "ios") {
|
||||
platform = cmXcFrameworkPlistSupportedPlatform::iOS;
|
||||
return true;
|
||||
}
|
||||
if (value->asString() == "tvos") {
|
||||
platform = cmXcFrameworkPlistSupportedPlatform::tvOS;
|
||||
return true;
|
||||
}
|
||||
if (value->asString() == "watchos") {
|
||||
platform = cmXcFrameworkPlistSupportedPlatform::watchOS;
|
||||
return true;
|
||||
}
|
||||
if (value->asString() == "xros") {
|
||||
platform = cmXcFrameworkPlistSupportedPlatform::visionOS;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto const PlistLibraryHelper =
|
||||
cmJSONHelperBuilder::Object<cmXcFrameworkPlistLibrary>{}
|
||||
.Bind("LibraryIdentifier"_s, &cmXcFrameworkPlistLibrary::LibraryIdentifier,
|
||||
cmJSONHelperBuilder::String())
|
||||
.Bind("LibraryPath"_s, &cmXcFrameworkPlistLibrary::LibraryPath,
|
||||
cmJSONHelperBuilder::String())
|
||||
.Bind("HeadersPath"_s, &cmXcFrameworkPlistLibrary::HeadersPath,
|
||||
cmJSONHelperBuilder::String(), false)
|
||||
.Bind("SupportedArchitectures"_s,
|
||||
&cmXcFrameworkPlistLibrary::SupportedArchitectures,
|
||||
cmJSONHelperBuilder::Vector<std::string>(
|
||||
JsonErrors::EXPECTED_TYPE("array"), cmJSONHelperBuilder::String()))
|
||||
.Bind("SupportedPlatform"_s, &cmXcFrameworkPlistLibrary::SupportedPlatform,
|
||||
PlistSupportedPlatformHelper);
|
||||
|
||||
auto const PlistHelper =
|
||||
cmJSONHelperBuilder::Object<cmXcFrameworkPlist>{}.Bind(
|
||||
"AvailableLibraries"_s, &cmXcFrameworkPlist::AvailableLibraries,
|
||||
cmJSONHelperBuilder::Vector<cmXcFrameworkPlistLibrary>(
|
||||
JsonErrors::EXPECTED_TYPE("array"), PlistLibraryHelper));
|
||||
}
|
||||
|
||||
cm::optional<cmXcFrameworkPlist> cmParseXcFrameworkPlist(
|
||||
const std::string& xcframeworkPath, const cmMakefile& mf,
|
||||
const cmListFileBacktrace& bt)
|
||||
{
|
||||
std::string plistPath = cmStrCat(xcframeworkPath, "/Info.plist");
|
||||
|
||||
auto value = cmParsePlist(plistPath);
|
||||
if (!value) {
|
||||
mf.GetCMakeInstance()->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("Unable to parse plist file:\n ", plistPath), bt);
|
||||
return cm::nullopt;
|
||||
}
|
||||
|
||||
cmJSONState state;
|
||||
|
||||
PlistMetadata metadata;
|
||||
if (!PlistMetadataHelper(metadata, &*value, &state)) {
|
||||
mf.GetCMakeInstance()->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("Invalid xcframework .plist file:\n ", plistPath), bt);
|
||||
return cm::nullopt;
|
||||
}
|
||||
if (metadata.CFBundlePackageType != "XFWK" ||
|
||||
metadata.XCFrameworkFormatVersion != "1.0") {
|
||||
mf.GetCMakeInstance()->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("Expected:\n ", plistPath,
|
||||
"\nto have CFBundlePackageType \"XFWK\" and "
|
||||
"XCFrameworkFormatVersion \"1.0\""),
|
||||
bt);
|
||||
return cm::nullopt;
|
||||
}
|
||||
|
||||
cmXcFrameworkPlist plist;
|
||||
if (!PlistHelper(plist, &*value, &state)) {
|
||||
mf.GetCMakeInstance()->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("Invalid xcframework .plist file:\n ", plistPath), bt);
|
||||
return cm::nullopt;
|
||||
}
|
||||
plist.Path = plistPath;
|
||||
return cm::optional<cmXcFrameworkPlist>(plist);
|
||||
}
|
||||
|
||||
const cmXcFrameworkPlistLibrary* cmXcFrameworkPlist::SelectSuitableLibrary(
|
||||
const cmMakefile& mf, const cmListFileBacktrace& bt) const
|
||||
{
|
||||
auto systemName = mf.GetSafeDefinition("CMAKE_SYSTEM_NAME");
|
||||
|
||||
for (auto const& lib : this->AvailableLibraries) {
|
||||
std::string supportedSystemName;
|
||||
switch (lib.SupportedPlatform) {
|
||||
case cmXcFrameworkPlistSupportedPlatform::macOS:
|
||||
supportedSystemName = "Darwin";
|
||||
break;
|
||||
case cmXcFrameworkPlistSupportedPlatform::iOS:
|
||||
supportedSystemName = "iOS";
|
||||
break;
|
||||
case cmXcFrameworkPlistSupportedPlatform::tvOS:
|
||||
supportedSystemName = "tvOS";
|
||||
break;
|
||||
case cmXcFrameworkPlistSupportedPlatform::watchOS:
|
||||
supportedSystemName = "watchOS";
|
||||
break;
|
||||
case cmXcFrameworkPlistSupportedPlatform::visionOS:
|
||||
supportedSystemName = "visionOS";
|
||||
break;
|
||||
}
|
||||
|
||||
if (systemName == supportedSystemName) {
|
||||
return &lib;
|
||||
}
|
||||
}
|
||||
|
||||
mf.GetCMakeInstance()->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("Unable to find suitable library in:\n ", this->Path,
|
||||
"\nfor system name \"", systemName, '"'),
|
||||
bt);
|
||||
return nullptr;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cm/optional>
|
||||
|
||||
#include "cmListFileCache.h"
|
||||
|
||||
class cmMakefile;
|
||||
|
||||
enum class cmXcFrameworkPlistSupportedPlatform
|
||||
{
|
||||
macOS,
|
||||
iOS,
|
||||
tvOS,
|
||||
watchOS,
|
||||
visionOS,
|
||||
};
|
||||
|
||||
struct cmXcFrameworkPlistLibrary
|
||||
{
|
||||
std::string LibraryIdentifier;
|
||||
std::string LibraryPath;
|
||||
std::string HeadersPath;
|
||||
std::vector<std::string> SupportedArchitectures;
|
||||
cmXcFrameworkPlistSupportedPlatform SupportedPlatform;
|
||||
};
|
||||
|
||||
struct cmXcFrameworkPlist
|
||||
{
|
||||
std::string Path;
|
||||
std::vector<cmXcFrameworkPlistLibrary> AvailableLibraries;
|
||||
|
||||
const cmXcFrameworkPlistLibrary* SelectSuitableLibrary(
|
||||
const cmMakefile& mf,
|
||||
const cmListFileBacktrace& bt = cmListFileBacktrace{}) const;
|
||||
};
|
||||
|
||||
cm::optional<cmXcFrameworkPlist> cmParseXcFrameworkPlist(
|
||||
const std::string& xcframeworkPath, const cmMakefile& mf,
|
||||
const cmListFileBacktrace& bt = cmListFileBacktrace{});
|
|
@ -703,6 +703,23 @@ endif()
|
|||
if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
|
||||
AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0)
|
||||
add_RunCMake_test(Framework)
|
||||
if(NOT DEFINED CMake_TEST_XcFramework)
|
||||
set(CMake_TEST_XcFramework ON)
|
||||
endif()
|
||||
if(CMake_TEST_XcFramework AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 11.0)
|
||||
set(XcFramework_ARGS -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION})
|
||||
add_RunCMake_test(XcFramework)
|
||||
|
||||
# This test can take a very long time due to lots of combinations.
|
||||
# Use a long default timeout and provide an option to customize it.
|
||||
if(NOT DEFINED CMake_TEST_XcFramework_TIMEOUT)
|
||||
set(CMake_TEST_XcFramework_TIMEOUT 3000)
|
||||
endif()
|
||||
set_tests_properties(RunCMake.XcFramework PROPERTIES
|
||||
TIMEOUT "${CMake_TEST_XcFramework_TIMEOUT}"
|
||||
RUN_SERIAL TRUE
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_RunCMake_test(File_Archive)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 3.26)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,83 @@
|
|||
include(RunCMake)
|
||||
|
||||
function(create_library type platform system_name archs)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/create-${type}-${platform}-build)
|
||||
run_cmake_with_options(create-${type}-${platform} -DCMAKE_SYSTEM_NAME=${system_name} -DCMAKE_OSX_ARCHITECTURES=${archs} -DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install)
|
||||
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(create-${type}-${platform}-build ${CMAKE_COMMAND} --build . --config Release)
|
||||
run_cmake_command(create-${type}-${platform}-install ${CMAKE_COMMAND} --install . --config Release)
|
||||
endfunction()
|
||||
|
||||
function(create_libraries type)
|
||||
create_library(${type} macos Darwin "${macos_archs_2}")
|
||||
create_library(${type} ios iOS "arm64")
|
||||
create_library(${type} tvos tvOS "arm64")
|
||||
create_library(${type} watchos watchOS "armv7k\\\\;arm64_32")
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15)
|
||||
create_library(${type} visionos visionOS "arm64")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(create_xcframework name type platforms)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/create-xcframework-${name}-build)
|
||||
set(args)
|
||||
foreach(platform IN LISTS platforms)
|
||||
if(type STREQUAL "framework")
|
||||
list(APPEND args -framework ${RunCMake_BINARY_DIR}/create-${type}-${platform}-build/install/lib/mylib.framework)
|
||||
else()
|
||||
list(APPEND args -library ${RunCMake_BINARY_DIR}/create-${type}-${platform}-build/install/lib/libmylib.a -headers ${RunCMake_SOURCE_DIR}/mylib/include)
|
||||
endif()
|
||||
endforeach()
|
||||
run_cmake_command(create-xcframework-${name} xcodebuild -create-xcframework ${args} -output ${RunCMake_TEST_BINARY_DIR}/mylib.xcframework)
|
||||
endfunction()
|
||||
|
||||
function(create_executable name xcfname system_name archs)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/create-executable-${name}-build)
|
||||
run_cmake_with_options(create-executable-${name} -DCMAKE_SYSTEM_NAME=${system_name} -DCMAKE_OSX_ARCHITECTURES=${archs} -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-${xcfname}-build/mylib.xcframework)
|
||||
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(create-executable-${name}-build ${CMAKE_COMMAND} --build . --config Release)
|
||||
endfunction()
|
||||
|
||||
function(create_executables name type)
|
||||
create_executable(${name}-macos ${type} Darwin "${macos_archs_2}")
|
||||
create_executable(${name}-ios ${type} iOS "arm64")
|
||||
create_executable(${name}-tvos ${type} tvOS "arm64")
|
||||
create_executable(${name}-watchos ${type} watchOS "armv7k\\\\;arm64_32")
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15)
|
||||
create_executable(${name}-visionos ${type} visionOS "arm64")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
set(xcframework_platforms macos ios tvos watchos)
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15)
|
||||
list(APPEND xcframework_platforms visionos)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
|
||||
set(macos_archs_1 "x86_64\\;arm64")
|
||||
set(macos_archs_2 "x86_64\\\\;arm64")
|
||||
else()
|
||||
set(macos_archs_1 "x86_64")
|
||||
set(macos_archs_2 "x86_64")
|
||||
endif()
|
||||
|
||||
create_libraries(library)
|
||||
create_libraries(framework)
|
||||
create_xcframework(library library "${xcframework_platforms}")
|
||||
create_xcframework(framework framework "${xcframework_platforms}")
|
||||
create_xcframework(incomplete framework "tvos;watchos")
|
||||
create_executables(library library)
|
||||
create_executables(framework framework)
|
||||
run_cmake_with_options(create-executable-incomplete -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
|
||||
create_executables(target-library library)
|
||||
create_executables(target-framework framework)
|
||||
run_cmake_with_options(create-executable-target-incomplete -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
|
||||
if(RunCMake_GENERATOR STREQUAL "Xcode" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
|
||||
create_executables(library-link-phase library)
|
||||
create_executables(framework-link-phase framework)
|
||||
run_cmake_with_options(create-executable-incomplete-link-phase -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
|
||||
create_executables(target-library-link-phase library)
|
||||
create_executables(target-framework-link-phase framework)
|
||||
run_cmake_with_options(create-executable-target-incomplete-link-phase -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
|
||||
endif()
|
|
@ -0,0 +1 @@
|
|||
include(create-executable.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable.cmake)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,11 @@
|
|||
CMake Error at create-executable\.cmake:[0-9]+ \(target_link_libraries\):
|
||||
Unable to find suitable library in:
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/XcFramework/create-xcframework-incomplete-build/mylib\.xcframework/Info\.plist
|
||||
|
||||
for system name "Darwin"
|
||||
Call Stack \(most recent call first\):
|
||||
create-executable-link-phase\.cmake:[0-9]+ \(include\)
|
||||
create-executable-incomplete-link-phase\.cmake:[0-9]+ \(include\)
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,10 @@
|
|||
CMake Error at create-executable\.cmake:[0-9]+ \(target_link_libraries\):
|
||||
Unable to find suitable library in:
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/XcFramework/create-xcframework-incomplete-build/mylib\.xcframework/Info\.plist
|
||||
|
||||
for system name "Darwin"
|
||||
Call Stack \(most recent call first\):
|
||||
create-executable-incomplete\.cmake:[0-9]+ \(include\)
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable.cmake)
|
|
@ -0,0 +1,2 @@
|
|||
include(create-executable.cmake)
|
||||
set_property(TARGET myexe PROPERTY XCODE_LINK_BUILD_PHASE_MODE "KNOWN_LOCATION")
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target.cmake)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,11 @@
|
|||
CMake Error at create-executable-target\.cmake:[0-9]+ \(target_link_libraries\):
|
||||
Unable to find suitable library in:
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/XcFramework/create-xcframework-incomplete-build/mylib\.xcframework/Info\.plist
|
||||
|
||||
for system name "Darwin"
|
||||
Call Stack \(most recent call first\):
|
||||
create-executable-target-link-phase\.cmake:[0-9]+ \(include\)
|
||||
create-executable-target-incomplete-link-phase\.cmake:[0-9]+ \(include\)
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,10 @@
|
|||
CMake Error at create-executable-target\.cmake:[0-9]+ \(target_link_libraries\):
|
||||
Unable to find suitable library in:
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/XcFramework/create-xcframework-incomplete-build/mylib\.xcframework/Info\.plist
|
||||
|
||||
for system name "Darwin"
|
||||
Call Stack \(most recent call first\):
|
||||
create-executable-target-incomplete\.cmake:[0-9]+ \(include\)
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target-link-phase.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-executable-target.cmake)
|
|
@ -0,0 +1,2 @@
|
|||
include(create-executable-target.cmake)
|
||||
set_property(TARGET myexe PROPERTY XCODE_LINK_BUILD_PHASE_MODE "KNOWN_LOCATION")
|
|
@ -0,0 +1,21 @@
|
|||
enable_language(C)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS" OR CMAKE_SYSTEM_NAME STREQUAL "visionOS")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")
|
||||
endif()
|
||||
|
||||
add_library(mylib IMPORTED STATIC)
|
||||
set_property(TARGET mylib PROPERTY IMPORTED_LOCATION ${MYLIB_LIBRARY})
|
||||
|
||||
add_executable(myexe myexe/myexe.c)
|
||||
target_link_libraries(myexe PRIVATE mylib)
|
|
@ -0,0 +1,18 @@
|
|||
enable_language(C)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS" OR CMAKE_SYSTEM_NAME STREQUAL "visionOS")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")
|
||||
endif()
|
||||
|
||||
add_executable(myexe myexe/myexe.c)
|
||||
target_link_libraries(myexe PRIVATE ${MYLIB_LIBRARY})
|
|
@ -0,0 +1 @@
|
|||
include(create-framework.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-framework.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-framework.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-framework.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-framework.cmake)
|
|
@ -0,0 +1,3 @@
|
|||
set(CMAKE_FRAMEWORK ON)
|
||||
include(create-library-common.cmake)
|
||||
install(FILES mylib/include/mylib/mylib.h DESTINATION lib/mylib.framework/Headers)
|
|
@ -0,0 +1,12 @@
|
|||
enable_language(C)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS" OR CMAKE_SYSTEM_NAME STREQUAL "visionOS")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")
|
||||
endif()
|
||||
|
||||
add_library(mylib STATIC mylib/mylib.c)
|
||||
install(TARGETS mylib DESTINATION lib)
|
|
@ -0,0 +1 @@
|
|||
include(create-library.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-library.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-library.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-library.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-library.cmake)
|
|
@ -0,0 +1 @@
|
|||
include(create-library-common.cmake)
|
|
@ -0,0 +1,7 @@
|
|||
#include <mylib/mylib.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
mylib();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
extern void mylib(void);
|
|
@ -0,0 +1,3 @@
|
|||
void mylib(void)
|
||||
{
|
||||
}
|
|
@ -451,6 +451,7 @@ CMAKE_CXX_SOURCES="\
|
|||
cmGccDepfileReader \
|
||||
cmReturnCommand \
|
||||
cmPlaceholderExpander \
|
||||
cmPlistParser \
|
||||
cmRulePlaceholderExpander \
|
||||
cmRuntimeDependencyArchive \
|
||||
cmScriptGenerator \
|
||||
|
@ -500,6 +501,7 @@ CMAKE_CXX_SOURCES="\
|
|||
cmWhileCommand \
|
||||
cmWindowsRegistry \
|
||||
cmWorkingDirectory \
|
||||
cmXcFramework \
|
||||
cmake \
|
||||
cmakemain \
|
||||
cmcmd \
|
||||
|
|
Loading…
Reference in New Issue