Merge topic 'install-export-xcframework'

37bc3400cd CMakePackageConfigHelpers: Add generate_apple_platform_selection_file()
256bb0cc40 install(EXPORT): Add ability to point to .xcframework file
a90968e044 cmExportBuildFileGenerator: Add structs for target exports

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Jason Juang <jasjuang@gmail.com>
Merge-request: !8969
This commit is contained in:
Brad King
2023-11-16 14:13:02 +00:00
committed by Kitware Robot
37 changed files with 549 additions and 58 deletions
+13
View File
@@ -170,6 +170,9 @@ Configuring Exports
[ENABLED (<bool-true>|<bool-false>|AUTO)]
[EXTRA_ARGS <args>...]
] [...]
[TARGET <target>
[XCFRAMEWORK_LOCATION <location>]
] [...]
)
.. versionadded:: 3.29
@@ -202,3 +205,13 @@ Configure the parameters of an export. The arguments are as follows:
``EXTRA_ARGS <args>``
Specify additional arguments to pass to :command:`find_dependency` after
the ``REQUIRED`` argument.
``TARGET <target>``
Specify a target to configure in this export. This argument accepts the
following additional arguments:
``XCFRAMEWORK_LOCATION``
Specify the location of an ``.xcframework`` which contains the library from
this target. If specified, the generated code will check to see if the
``.xcframework`` exists, and if it does, it will use the ``.xcframework``
as its imported location instead of the installed library.
@@ -0,0 +1,9 @@
install-export-xcframework
--------------------------
* The :command:`export(SETUP)` command gained a new ``XCFRAMEWORK_LOCATION``
argument, which can be used to specify the location of a ``.xcframework``
that can be substituted for the installed library.
* The :module:`CMakePackageConfigHelpers` module gained a new
:command:`generate_apple_platform_selection_file` function, which can be
used to generate a file that includes another Apple-platform-specific file.
+104
View File
@@ -190,6 +190,68 @@ Please note that these files are internal to CMake and you should not call
:command:`configure_file()` on them yourself, but they can be used as starting
point to create more sophisticated custom ``ConfigVersion.cmake`` files.
Generating an Apple Platform Selection File
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. versionadded:: 3.29
.. command:: generate_apple_platform_selection_file
Create an Apple platform selection file:
generate_apple_platform_selection_file(<filename>
INSTALL_DESTINATION <path>
[MACOS_CONFIG_FILE <file>]
[IOS_CONFIG_FILE <file>]
[IOS_SIMULATOR_CONFIG_FILE <file>]
[TVOS_CONFIG_FILE <file>]
[TVOS_SIMULATOR_CONFIG_FILE <file>]
[WATCHOS_CONFIG_FILE <file>]
[WATCHOS_SIMULATOR_CONFIG_FILE <file>]
[VISIONOS_CONFIG_FILE <file>]
[VISIONOS_SIMULATOR_CONFIG_FILE <file>]
)
Writes a file for use as ``<PackageName>Config.cmake`` which can include an
Apple-platform-specific ``<PackageName>Config.cmake`` from a different
directory. This can be used in conjunction with the ``XCFRAMEWORK_LOCATION``
argument of :command:`export(SETUP)` to export packages in a way that a project
built for any Apple platform can use them.
``INSTALL_DESTINATION <path>``
Path that the file will be installed to.
``MACOS_CONFIG_FILE <file>``
File to include if the platform is macOS.
``IOS_CONFIG_FILE <file>``
File to include if the platform is iOS.
``IOS_SIMULATOR_CONFIG_FILE <file>``
File to include if the platform is iOS Simulator.
``TVOS_CONFIG_FILE <file>``
File to include if the platform is tvOS.
``TVOS_SIMULATOR_CONFIG_FILE <file>``
File to include if the platform is tvOS Simulator.
``WATCHOS_CONFIG_FILE <file>``
File to include if the platform is watchOS.
``WATCHOS_SIMULATOR_CONFIG_FILE <file>``
File to include if the platform is watchOS Simulator.
``VISIONOS_CONFIG_FILE <file>``
File to include if the platform is visionOS.
``VISIONOS_SIMULATOR_CONFIG_FILE <file>``
File to include if the platform is visionOS Simulator.
If any of the optional config files are not specified, and the consuming
project is built for their corresponding platform, an error will be thrown
when including the generated file.
Example Generating Package Files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -344,3 +406,45 @@ endmacro()
configure_file("${_inputFile}" "${_outputFile}" @ONLY)
endfunction()
function(generate_apple_platform_selection_file _output_file)
set(_config_file_options
MACOS_CONFIG_FILE
IOS_CONFIG_FILE
IOS_SIMULATOR_CONFIG_FILE
TVOS_CONFIG_FILE
TVOS_SIMULATOR_CONFIG_FILE
WATCHOS_CONFIG_FILE
WATCHOS_SIMULATOR_CONFIG_FILE
VISIONOS_CONFIG_FILE
VISIONOS_SIMULATOR_CONFIG_FILE
)
set(_options)
set(_single
INSTALL_DESTINATION
${_config_file_options}
)
set(_multi)
cmake_parse_arguments(PARSE_ARGV 0 _gpsf "${_options}" "${_single}" "${_multi}")
set(_have_relative 0)
foreach(_opt IN LISTS _config_file_options)
if(_gpsf_${_opt})
set(_config_file "${_gpsf_${_opt}}")
if(NOT IS_ABSOLUTE "${_config_file}")
string(PREPEND _config_file [[${PACKAGE_PREFIX_DIR}/]])
set(_have_relative 1)
endif()
set(_branch_${_opt} "include(\"${_config_file}\")")
else()
set(_branch_${_opt} "message(FATAL_ERROR \"Platform not supported\")")
endif()
endforeach()
configure_package_config_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/PlatformSelectionFile.cmake.in" "${_output_file}"
INSTALL_DESTINATION "${_gpsf_INSTALL_DESTINATION}"
NO_SET_AND_CHECK_MACRO
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
endfunction()
+24
View File
@@ -0,0 +1,24 @@
@PACKAGE_INIT@
string(TOLOWER "${CMAKE_OSX_SYSROOT}" _CMAKE_OSX_SYSROOT_LOWER)
if(_CMAKE_OSX_SYSROOT_LOWER MATCHES "(^|/)iphonesimulator")
@_branch_IOS_SIMULATOR_CONFIG_FILE@
elseif(_CMAKE_OSX_SYSROOT_LOWER MATCHES "(^|/)iphoneos")
@_branch_IOS_CONFIG_FILE@
elseif(_CMAKE_OSX_SYSROOT_LOWER MATCHES "(^|/)tvsimulator")
@_branch_TVOS_SIMULATOR_CONFIG_FILE@
elseif(_CMAKE_OSX_SYSROOT_LOWER MATCHES "(^|/)tvos")
@_branch_TVOS_CONFIG_FILE@
elseif(_CMAKE_OSX_SYSROOT_LOWER MATCHES "(^|/)watchsimulator")
@_branch_WATCHOS_SIMULATOR_CONFIG_FILE@
elseif(_CMAKE_OSX_SYSROOT_LOWER MATCHES "(^|/)watchos")
@_branch_WATCHOS_CONFIG_FILE@
elseif(_CMAKE_OSX_SYSROOT_LOWER MATCHES "(^|/)xrsimulator")
@_branch_VISIONOS_SIMULATOR_CONFIG_FILE@
elseif(_CMAKE_OSX_SYSROOT_LOWER MATCHES "(^|/)xros")
@_branch_VISIONOS_CONFIG_FILE@
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
@_branch_MACOS_CONFIG_FILE@
else()
message(FATAL_ERROR "Platform not supported")
endif()
+4 -2
View File
@@ -242,14 +242,16 @@ Json::Value CollationInformationExports(cmGeneratorTarget const* gt)
auto const& all_build_exports = gt->Makefile->GetExportBuildFileGenerators();
for (auto const& exp : all_build_exports) {
std::vector<std::string> targets;
std::vector<cmExportBuildFileGenerator::TargetExport> targets;
exp->GetTargets(targets);
// Ignore exports sets which are not for this target.
auto const& name = gt->GetName();
bool has_current_target =
std::any_of(targets.begin(), targets.end(),
[name](std::string const& tname) { return tname == name; });
[name](cmExportBuildFileGenerator::TargetExport const& te) {
return te.Name == name;
});
if (!has_current_target) {
continue;
}
+2 -2
View File
@@ -57,8 +57,8 @@ void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode(
}
void cmExportBuildAndroidMKGenerator::GenerateImportPropertyCode(
std::ostream&, const std::string&, cmGeneratorTarget const*,
ImportPropertyMap const&)
std::ostream&, const std::string&, const std::string&,
cmGeneratorTarget const*, ImportPropertyMap const&, const std::string&)
{
}
+3 -3
View File
@@ -51,9 +51,9 @@ protected:
void GenerateExpectedTargetsCode(
std::ostream& os, const std::string& expectedTargets) override;
void GenerateImportPropertyCode(
std::ostream& os, const std::string& config,
cmGeneratorTarget const* target,
ImportPropertyMap const& properties) override;
std::ostream& os, const std::string& config, const std::string& suffix,
cmGeneratorTarget const* target, ImportPropertyMap const& properties,
const std::string& importedXcFrameworkLocation) override;
void GenerateMissingTargetsCheckCode(std::ostream& os) override;
void GenerateFindDependencyCalls(std::ostream&) override {}
void GenerateInterfaceProperties(
+32 -12
View File
@@ -10,7 +10,6 @@
#include <utility>
#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>
#include "cmExportSet.h"
@@ -54,15 +53,15 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
{
std::string expectedTargets;
std::string sep;
std::vector<std::string> targets;
std::vector<TargetExport> targets;
bool generatedInterfaceRequired = false;
this->GetTargets(targets);
for (std::string const& tei : targets) {
cmGeneratorTarget* te = this->LG->FindGeneratorTargetToUse(tei);
for (auto const& tei : targets) {
cmGeneratorTarget* te = this->LG->FindGeneratorTargetToUse(tei.Name);
expectedTargets += sep + this->Namespace + te->GetExportName();
sep = " ";
if (this->ExportedTargets.insert(te).second) {
this->Exports.push_back(te);
this->Exports.emplace_back(te, tei.XcFrameworkLocation);
} else {
std::ostringstream e;
e << "given target \"" << te->GetName() << "\" more than once.";
@@ -82,7 +81,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
}
// Create all the imported targets.
for (cmGeneratorTarget* gte : this->Exports) {
for (auto const& exp : this->Exports) {
cmGeneratorTarget* gte = exp.Target;
this->GenerateImportTargetCode(os, gte, this->GetExportTargetType(gte));
gte->Target->AppendBuildInterfaceIncludes();
@@ -176,7 +176,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
void cmExportBuildFileGenerator::GenerateImportTargetsConfig(
std::ostream& os, const std::string& config, std::string const& suffix)
{
for (cmGeneratorTarget* target : this->Exports) {
for (auto const& exp : this->Exports) {
cmGeneratorTarget* target = exp.Target;
// Collect import properties for this target.
ImportPropertyMap properties;
@@ -200,7 +202,23 @@ void cmExportBuildFileGenerator::GenerateImportTargetsConfig(
// properties);
// Generate code in the export file.
this->GenerateImportPropertyCode(os, config, target, properties);
std::string importedXcFrameworkLocation = exp.XcFrameworkLocation;
if (!importedXcFrameworkLocation.empty()) {
importedXcFrameworkLocation = cmGeneratorExpression::Preprocess(
importedXcFrameworkLocation,
cmGeneratorExpression::PreprocessContext::BuildInterface);
importedXcFrameworkLocation = cmGeneratorExpression::Evaluate(
importedXcFrameworkLocation, exp.Target->GetLocalGenerator(), config,
exp.Target, nullptr, exp.Target);
if (!importedXcFrameworkLocation.empty() &&
!cmSystemTools::FileIsFullPath(importedXcFrameworkLocation)) {
importedXcFrameworkLocation =
cmStrCat(this->LG->GetCurrentBinaryDirectory(), '/',
importedXcFrameworkLocation);
}
}
this->GenerateImportPropertyCode(os, config, suffix, target, properties,
importedXcFrameworkLocation);
}
}
}
@@ -308,7 +326,7 @@ void cmExportBuildFileGenerator::HandleMissingTarget(
}
void cmExportBuildFileGenerator::GetTargets(
std::vector<std::string>& targets) const
std::vector<TargetExport>& targets) const
{
if (this->ExportSet) {
for (std::unique_ptr<cmTargetExport> const& te :
@@ -316,7 +334,7 @@ void cmExportBuildFileGenerator::GetTargets(
if (te->NamelinkOnly) {
continue;
}
targets.push_back(te->TargetName);
targets.emplace_back(te->TargetName, te->XcFrameworkLocation);
}
return;
}
@@ -334,9 +352,11 @@ cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg,
for (auto const& exp : exportSets) {
const auto& exportSet = exp.second;
std::vector<std::string> targets;
std::vector<TargetExport> targets;
exportSet->GetTargets(targets);
if (cm::contains(targets, name)) {
if (std::any_of(
targets.begin(), targets.end(),
[&name](const TargetExport& te) { return te.Name == name; })) {
exportFiles.push_back(exp.first);
ns = exportSet->GetNamespace();
}
+30 -5
View File
@@ -33,15 +33,27 @@ class cmTargetExport;
class cmExportBuildFileGenerator : public cmExportFileGenerator
{
public:
struct TargetExport
{
TargetExport(std::string name, std::string xcFrameworkLocation)
: Name(std::move(name))
, XcFrameworkLocation(std::move(xcFrameworkLocation))
{
}
std::string Name;
std::string XcFrameworkLocation;
};
cmExportBuildFileGenerator();
/** Set the list of targets to export. */
void SetTargets(std::vector<std::string> const& targets)
void SetTargets(std::vector<TargetExport> const& targets)
{
this->Targets = targets;
}
void GetTargets(std::vector<std::string>& targets) const;
void AppendTargets(std::vector<std::string> const& targets)
void GetTargets(std::vector<TargetExport>& targets) const;
void AppendTargets(std::vector<TargetExport> const& targets)
{
cm::append(this->Targets, targets);
}
@@ -99,9 +111,22 @@ protected:
std::pair<std::vector<std::string>, std::string> FindBuildExportInfo(
cmGlobalGenerator* gg, const std::string& name);
std::vector<std::string> Targets;
struct TargetExportPrivate
{
TargetExportPrivate(cmGeneratorTarget* target,
std::string xcFrameworkLocation)
: Target(target)
, XcFrameworkLocation(std::move(xcFrameworkLocation))
{
}
cmGeneratorTarget* Target;
std::string XcFrameworkLocation;
};
std::vector<TargetExport> Targets;
cmExportSet* ExportSet;
std::vector<cmGeneratorTarget*> Exports;
std::vector<TargetExportPrivate> Exports;
cmLocalGenerator* LG;
// The directory for C++ module information.
std::string CxxModulesDirectory;
+30 -2
View File
@@ -72,6 +72,8 @@ bool cmExportCommand(std::vector<std::string> const& args,
std::vector<std::vector<std::string>> PackageDependencyArgs;
bool ExportPackageDependencies = false;
std::vector<std::vector<std::string>> TargetArgs;
};
auto parser =
@@ -87,6 +89,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
} else if (args[0] == "SETUP") {
parser.Bind("SETUP"_s, &Arguments::ExportSetName);
parser.Bind("PACKAGE_DEPENDENCY"_s, &Arguments::PackageDependencyArgs);
parser.Bind("TARGET"_s, &Arguments::TargetArgs);
} else {
parser.Bind("TARGETS"_s, &Arguments::Targets);
parser.Bind("ANDROID_MK"_s, &Arguments::AndroidMKFile);
@@ -159,6 +162,31 @@ bool cmExportCommand(std::vector<std::string> const& args,
packageDependencyArguments.ExtraArgs);
}
struct TargetArguments
{
std::string XcFrameworkLocation;
};
auto targetParser = cmArgumentParser<TargetArguments>{}.Bind(
"XCFRAMEWORK_LOCATION"_s, &TargetArguments::XcFrameworkLocation);
for (auto const& targetArgs : arguments.TargetArgs) {
if (targetArgs.empty()) {
continue;
}
TargetArguments const targetArguments =
targetParser.Parse(cmMakeRange(targetArgs).advance(1), &unknownArgs);
if (!unknownArgs.empty()) {
status.SetError("Unknown argument: \"" + unknownArgs.front() + "\".");
return false;
}
exportSet.SetXcFrameworkLocation(targetArgs.front(),
targetArguments.XcFrameworkLocation);
}
return true;
}
@@ -204,7 +232,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
fname = dir + "/" + fname;
}
std::vector<std::string> targets;
std::vector<cmExportBuildFileGenerator::TargetExport> targets;
cmGlobalGenerator* gg = mf.GetGlobalGenerator();
@@ -242,7 +270,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
status.SetError(e.str());
return false;
}
targets.push_back(currentTarget);
targets.emplace_back(currentTarget, std::string{});
}
if (arguments.Append) {
if (cmExportBuildFileGenerator* ebfg =
+47 -17
View File
@@ -1154,8 +1154,9 @@ void cmExportFileGenerator::GenerateImportTargetCode(
}
void cmExportFileGenerator::GenerateImportPropertyCode(
std::ostream& os, const std::string& config, cmGeneratorTarget const* target,
ImportPropertyMap const& properties)
std::ostream& os, const std::string& config, const std::string& suffix,
cmGeneratorTarget const* target, ImportPropertyMap const& properties,
const std::string& importedXcFrameworkLocation)
{
// Construct the imported target name.
std::string targetName = this->Namespace;
@@ -1174,12 +1175,31 @@ void cmExportFileGenerator::GenerateImportPropertyCode(
}
os << ")\n";
os << "set_target_properties(" << targetName << " PROPERTIES\n";
std::string importedLocationProp = cmStrCat("IMPORTED_LOCATION", suffix);
for (auto const& property : properties) {
os << " " << property.first << " "
<< cmExportFileGeneratorEscape(property.second) << "\n";
if (importedXcFrameworkLocation.empty() ||
property.first != importedLocationProp) {
os << " " << property.first << " "
<< cmExportFileGeneratorEscape(property.second) << "\n";
}
}
os << " )\n"
<< "\n";
os << " )\n";
if (!importedXcFrameworkLocation.empty()) {
auto importedLocationIt = properties.find(importedLocationProp);
if (importedLocationIt != properties.end()) {
os << "if(NOT CMAKE_VERSION VERSION_LESS \"3.28\" AND IS_DIRECTORY "
<< cmExportFileGeneratorEscape(importedXcFrameworkLocation)
<< ")\n"
" set_property(TARGET "
<< targetName << " PROPERTY " << importedLocationProp << " "
<< cmExportFileGeneratorEscape(importedXcFrameworkLocation)
<< ")\nelse()\n set_property(TARGET " << targetName << " PROPERTY "
<< importedLocationProp << " "
<< cmExportFileGeneratorEscape(importedLocationIt->second)
<< ")\nendif()\n";
}
}
os << "\n";
}
void cmExportFileGenerator::GenerateFindDependencyCalls(std::ostream& os)
@@ -1310,10 +1330,16 @@ void cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
/* clang-format off */
os << "# Loop over all imported files and verify that they actually exist\n"
"foreach(_cmake_target IN LISTS _cmake_import_check_targets)\n"
" foreach(_cmake_file IN LISTS \"_cmake_import_check_files_for_${_cmake_target}\")\n"
" if(NOT EXISTS \"${_cmake_file}\")\n"
" message(FATAL_ERROR \"The imported target \\\"${_cmake_target}\\\""
" references the file\n"
" if(CMAKE_VERSION VERSION_LESS \"3.28\"\n"
" OR NOT DEFINED "
"_cmake_import_check_xcframework_for_${_cmake_target}\n"
" OR NOT IS_DIRECTORY "
"\"${_cmake_import_check_xcframework_for_${_cmake_target}}\")\n"
" foreach(_cmake_file IN LISTS "
"\"_cmake_import_check_files_for_${_cmake_target}\")\n"
" if(NOT EXISTS \"${_cmake_file}\")\n"
" message(FATAL_ERROR \"The imported target "
"\\\"${_cmake_target}\\\" references the file\n"
" \\\"${_cmake_file}\\\"\n"
"but this file does not exist. Possible reasons include:\n"
"* The file was deleted, renamed, or moved to another location.\n"
@@ -1322,8 +1348,9 @@ void cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
" \\\"${CMAKE_CURRENT_LIST_FILE}\\\"\n"
"but not all the files it references.\n"
"\")\n"
" endif()\n"
" endforeach()\n"
" endif()\n"
" endforeach()\n"
" endif()\n"
" unset(_cmake_file)\n"
" unset(\"_cmake_import_check_files_for_${_cmake_target}\")\n"
"endforeach()\n"
@@ -1336,15 +1363,18 @@ void cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
void cmExportFileGenerator::GenerateImportedFileChecksCode(
std::ostream& os, cmGeneratorTarget* target,
ImportPropertyMap const& properties,
const std::set<std::string>& importedLocations)
const std::set<std::string>& importedLocations,
const std::string& importedXcFrameworkLocation)
{
// Construct the imported target name.
std::string targetName = cmStrCat(this->Namespace, target->GetExportName());
os << "list(APPEND _cmake_import_check_targets " << targetName
<< " )\n"
"list(APPEND _cmake_import_check_files_for_"
<< targetName << " ";
os << "list(APPEND _cmake_import_check_targets " << targetName << " )\n";
if (!importedXcFrameworkLocation.empty()) {
os << "set(_cmake_import_check_xcframework_for_" << targetName << ' '
<< cmExportFileGeneratorEscape(importedXcFrameworkLocation) << ")\n";
}
os << "list(APPEND _cmake_import_check_files_for_" << targetName << " ";
for (std::string const& li : importedLocations) {
auto pi = properties.find(li);
+6 -5
View File
@@ -84,14 +84,15 @@ protected:
virtual void GenerateImportTargetCode(std::ostream& os,
cmGeneratorTarget const* target,
cmStateEnums::TargetType targetType);
virtual void GenerateImportPropertyCode(std::ostream& os,
const std::string& config,
cmGeneratorTarget const* target,
ImportPropertyMap const& properties);
virtual void GenerateImportPropertyCode(
std::ostream& os, const std::string& config, const std::string& suffix,
cmGeneratorTarget const* target, ImportPropertyMap const& properties,
const std::string& importedXcFrameworkLocation);
virtual void GenerateImportedFileChecksCode(
std::ostream& os, cmGeneratorTarget* target,
ImportPropertyMap const& properties,
const std::set<std::string>& importedLocations);
const std::set<std::string>& importedLocations,
const std::string& importedXcFrameworkLocation);
virtual void GenerateImportedFileCheckLoop(std::ostream& os);
virtual void GenerateMissingTargetsCheckCode(std::ostream& os);
virtual void GenerateFindDependencyCalls(std::ostream& os);
+3 -3
View File
@@ -80,8 +80,8 @@ void cmExportInstallAndroidMKGenerator::GenerateExpectedTargetsCode(
}
void cmExportInstallAndroidMKGenerator::GenerateImportPropertyCode(
std::ostream&, const std::string&, cmGeneratorTarget const*,
ImportPropertyMap const&)
std::ostream&, const std::string&, const std::string&,
cmGeneratorTarget const*, ImportPropertyMap const&, const std::string&)
{
}
@@ -122,7 +122,7 @@ void cmExportInstallAndroidMKGenerator::GenerateImportedFileCheckLoop(
void cmExportInstallAndroidMKGenerator::GenerateImportedFileChecksCode(
std::ostream&, cmGeneratorTarget*, ImportPropertyMap const&,
const std::set<std::string>&)
const std::set<std::string>&, const std::string&)
{
}
+5 -4
View File
@@ -45,9 +45,9 @@ protected:
void GenerateExpectedTargetsCode(
std::ostream& os, const std::string& expectedTargets) override;
void GenerateImportPropertyCode(
std::ostream& os, const std::string& config,
cmGeneratorTarget const* target,
ImportPropertyMap const& properties) override;
std::ostream& os, const std::string& config, const std::string& suffix,
cmGeneratorTarget const* target, ImportPropertyMap const& properties,
const std::string& importedXcFrameworkLocation) override;
void GenerateMissingTargetsCheckCode(std::ostream& os) override;
void GenerateFindDependencyCalls(std::ostream&) override {}
void GenerateInterfaceProperties(
@@ -60,6 +60,7 @@ protected:
void GenerateImportedFileChecksCode(
std::ostream& os, cmGeneratorTarget* target,
ImportPropertyMap const& properties,
const std::set<std::string>& importedLocations) override;
const std::set<std::string>& importedLocations,
const std::string& importedXcFrameworkLocation) override;
bool GenerateImportFileConfig(const std::string& config) override;
};
+20 -3
View File
@@ -375,9 +375,26 @@ void cmExportInstallFileGenerator::GenerateImportTargetsConfig(
// properties);
// Generate code in the export file.
this->GenerateImportPropertyCode(os, config, gtgt, properties);
this->GenerateImportedFileChecksCode(os, gtgt, properties,
importedLocations);
std::string importedXcFrameworkLocation = te->XcFrameworkLocation;
if (!importedXcFrameworkLocation.empty()) {
importedXcFrameworkLocation = cmGeneratorExpression::Preprocess(
importedXcFrameworkLocation,
cmGeneratorExpression::PreprocessContext::InstallInterface, true);
importedXcFrameworkLocation = cmGeneratorExpression::Evaluate(
importedXcFrameworkLocation, te->Target->GetLocalGenerator(), config,
te->Target, nullptr, te->Target);
if (!importedXcFrameworkLocation.empty() &&
!cmSystemTools::FileIsFullPath(importedXcFrameworkLocation) &&
!cmHasLiteralPrefix(importedXcFrameworkLocation,
"${_IMPORT_PREFIX}/")) {
importedXcFrameworkLocation =
cmStrCat("${_IMPORT_PREFIX}/", importedXcFrameworkLocation);
}
}
this->GenerateImportPropertyCode(os, config, suffix, gtgt, properties,
importedXcFrameworkLocation);
this->GenerateImportedFileChecksCode(
os, gtgt, properties, importedLocations, importedXcFrameworkLocation);
}
}
}
+10
View File
@@ -72,6 +72,16 @@ void cmExportSet::AddInstallation(cmInstallExportGenerator const* installation)
this->Installations.push_back(installation);
}
void cmExportSet::SetXcFrameworkLocation(const std::string& name,
const std::string& location)
{
for (auto& te : this->TargetExports) {
if (name == te->TargetName) {
te->XcFrameworkLocation = location;
}
}
}
cmExportSet& cmExportSetMap::operator[](const std::string& name)
{
auto it = this->find(name);
+3
View File
@@ -33,6 +33,9 @@ public:
void AddInstallation(cmInstallExportGenerator const* installation);
void SetXcFrameworkLocation(const std::string& name,
const std::string& location);
std::string const& GetName() const { return this->Name; }
std::vector<std::unique_ptr<cmTargetExport>> const& GetTargetExports() const
+1
View File
@@ -38,4 +38,5 @@ public:
///@}
bool NamelinkOnly = false;
std::string XcFrameworkLocation;
};
@@ -119,3 +119,128 @@ unset(RunCMake_TEST_BINARY_DIR)
run_cmake(find-library)
run_cmake_command(find-library-script ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/find-library.cmake)
file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/export-install)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/export-macos-build)
run_cmake_with_options(export-macos -DCMAKE_SYSTEM_NAME=Darwin -DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/export-install)
set(RunCMake_TEST_NO_CLEAN 1)
set(_config_arg)
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(_config_arg --config Release)
endif()
run_cmake_command(export-macos-build ${CMAKE_COMMAND} --build . ${_config_arg})
run_cmake_command(export-macos-install ${CMAKE_COMMAND} --install . ${_config_arg})
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_BINARY_DIR)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/import-macos-install-specific-no-xcframework-build)
run_cmake_with_options(import-macos-install-specific-no-xcframework -DCMAKE_SYSTEM_NAME=Darwin -Dmylib_DIR=${RunCMake_BINARY_DIR}/export-install/lib/macos/cmake/mylib)
set(RunCMake_TEST_NO_CLEAN 1)
set(_config_arg)
set(_config_dir)
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(_config_arg --config Release)
set(_config_dir /Release)
endif()
run_cmake_command(import-macos-install-specific-no-xcframework-build ${CMAKE_COMMAND} --build . ${_config_arg})
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_BINARY_DIR)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/export-macos-build)
set(RunCMake_TEST_NO_CLEAN 1)
if(CMake_TEST_XCODE_VERSION VERSION_GREATER_EQUAL 15)
# 'xcodebuild -create-xcframework' fails on symlinked paths.
file(REAL_PATH "${RunCMake_SOURCE_DIR}" src_dir)
file(REAL_PATH "${RunCMake_BINARY_DIR}" bld_dir)
else()
set(src_dir "${RunCMake_SOURCE_DIR}")
set(bld_dir "${RunCMake_BINARY_DIR}")
endif()
run_cmake_command(export-install-xcframework xcodebuild -create-xcframework
-output ${bld_dir}/export-install/lib/mylib.xcframework
-library ${bld_dir}/export-install/lib/macos/libmylib.a
-headers ${src_dir}/mylib/include
)
run_cmake_command(export-build-xcframework xcodebuild -create-xcframework
-output ${bld_dir}/export-macos-build/lib/mylib.xcframework
-library ${bld_dir}/export-macos-build/lib/macos${_config_dir}/libmylib.a
-headers ${src_dir}/mylib/include
)
run_cmake_command(export-install-xcframework-genex xcodebuild -create-xcframework
-output ${bld_dir}/export-install/lib2/mylib-genex.xcframework
-library ${bld_dir}/export-install/lib/macos/libmylib-genex.a
-headers ${src_dir}/mylib/include
)
run_cmake_command(export-build-xcframework-genex xcodebuild -create-xcframework
-output ${bld_dir}/export-macos-build/lib/mylib-genex.xcframework
-library ${bld_dir}/export-macos-build/lib/macos${_config_dir}/libmylib-genex.a
-headers ${src_dir}/mylib/include
)
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_BINARY_DIR)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/import-macos-install-specific-build)
run_cmake_with_options(import-macos-install-specific -DCMAKE_SYSTEM_NAME=Darwin -Dmylib_DIR=${RunCMake_BINARY_DIR}/export-install/lib/macos/cmake/mylib)
set(RunCMake_TEST_NO_CLEAN 1)
set(_config_arg)
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(_config_arg --config Release)
endif()
run_cmake_command(import-macos-install-specific-build ${CMAKE_COMMAND} --build . ${_config_arg})
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_BINARY_DIR)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/import-macos-build-specific-build)
run_cmake_with_options(import-macos-build-specific -DCMAKE_SYSTEM_NAME=Darwin -Dmylib_DIR=${RunCMake_BINARY_DIR}/export-macos-build/lib/macos/cmake/mylib)
set(RunCMake_TEST_NO_CLEAN 1)
set(_config_arg)
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(_config_arg --config Release)
endif()
run_cmake_command(import-macos-build-specific-build ${CMAKE_COMMAND} --build . ${_config_arg})
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_BINARY_DIR)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/import-macos-install-specific-genex-build)
run_cmake_with_options(import-macos-install-specific-genex -DCMAKE_SYSTEM_NAME=Darwin -Dmylib_DIR=${RunCMake_BINARY_DIR}/export-install/lib/macos/cmake/mylib)
set(RunCMake_TEST_NO_CLEAN 1)
set(_config_arg)
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(_config_arg --config Release)
endif()
run_cmake_command(import-macos-install-specific-genex-build ${CMAKE_COMMAND} --build . ${_config_arg})
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_BINARY_DIR)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/import-macos-build-specific-genex-build)
run_cmake_with_options(import-macos-build-specific-genex -DCMAKE_SYSTEM_NAME=Darwin -Dmylib_DIR=${RunCMake_BINARY_DIR}/export-macos-build/lib/macos/cmake/mylib)
set(RunCMake_TEST_NO_CLEAN 1)
set(_config_arg)
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(_config_arg --config Release)
endif()
run_cmake_command(import-macos-build-specific-genex-build ${CMAKE_COMMAND} --build . ${_config_arg})
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_BINARY_DIR)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/import-macos-install-general-build)
run_cmake_with_options(import-macos-install-general -DCMAKE_SYSTEM_NAME=Darwin -Dmylib_DIR=${RunCMake_BINARY_DIR}/export-install/lib/cmake/mylib)
set(RunCMake_TEST_NO_CLEAN 1)
set(_config_arg)
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(_config_arg --config Release)
endif()
run_cmake_command(import-macos-install-general-build ${CMAKE_COMMAND} --build . ${_config_arg})
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_BINARY_DIR)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/import-macos-build-general-build)
run_cmake_with_options(import-macos-build-general -DCMAKE_SYSTEM_NAME=Darwin -Dmylib_DIR=${RunCMake_BINARY_DIR}/export-macos-build/lib/cmake/mylib)
set(RunCMake_TEST_NO_CLEAN 1)
set(_config_arg)
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(_config_arg --config Release)
endif()
run_cmake_command(import-macos-build-general-build ${CMAKE_COMMAND} --build . ${_config_arg})
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_BINARY_DIR)
@@ -0,0 +1,44 @@
enable_language(C)
include(CMakePackageConfigHelpers)
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)
target_include_directories(mylib INTERFACE $<INSTALL_INTERFACE:include>)
set_property(TARGET mylib PROPERTY ARCHIVE_OUTPUT_DIRECTORY lib/macos)
add_library(mylib-genex STATIC mylib/mylib.c)
target_include_directories(mylib-genex INTERFACE $<INSTALL_INTERFACE:include>)
set_property(TARGET mylib-genex PROPERTY ARCHIVE_OUTPUT_DIRECTORY lib/macos)
install(TARGETS mylib mylib-genex DESTINATION lib/macos EXPORT mylib)
install(FILES mylib/include/mylib/mylib.h DESTINATION include/mylib)
export(SETUP mylib
TARGET mylib XCFRAMEWORK_LOCATION lib/mylib.xcframework
TARGET mylib-genex XCFRAMEWORK_LOCATION "$<BUILD_INTERFACE:lib/$<TARGET_PROPERTY:NAME>.xcframework>$<INSTALL_INTERFACE:lib2/$<TARGET_PROPERTY:NAME>.xcframework>"
)
install(EXPORT mylib DESTINATION lib/macos/cmake/mylib FILE mylib-targets.cmake)
export(EXPORT mylib FILE lib/macos/cmake/mylib/mylib-targets.cmake)
configure_package_config_file(mylib-config.cmake.in mylib-config-sub.cmake INSTALL_DESTINATION lib/macos/cmake/mylib)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mylib-config-sub.cmake DESTINATION lib/macos/cmake/mylib RENAME mylib-config.cmake)
configure_package_config_file(mylib-config.cmake.in lib/macos/cmake/mylib/mylib-config.cmake INSTALL_DESTINATION lib/macos/cmake/mylib)
generate_apple_platform_selection_file(mylib-config-top.cmake
INSTALL_DESTINATION lib/cmake/mylib
MACOS_CONFIG_FILE lib/macos/cmake/mylib/mylib-config.cmake
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mylib-config-top.cmake DESTINATION lib/cmake/mylib RENAME mylib-config.cmake)
generate_apple_platform_selection_file(lib/cmake/mylib/mylib-config.cmake
INSTALL_DESTINATION lib/cmake/mylib
MACOS_CONFIG_FILE lib/macos/cmake/mylib/mylib-config.cmake
)
@@ -0,0 +1,5 @@
enable_language(C)
find_package(mylib REQUIRED)
add_custom_target(print_loc ALL COMMAND ${CMAKE_COMMAND} -E echo "mylib location: $<TARGET_FILE:mylib>")
@@ -0,0 +1,5 @@
enable_language(C)
find_package(mylib REQUIRED)
add_custom_target(print_loc ALL COMMAND ${CMAKE_COMMAND} -E echo "mylib-genex location: $<TARGET_FILE:mylib-genex>")
@@ -0,0 +1,2 @@
mylib location: [^
]*/Tests/RunCMake/XcFramework/export-macos-build/lib/mylib\.xcframework/macos-(arm64|x86_64|arm64_x86_64)/libmylib\.a
@@ -0,0 +1 @@
include(import-common.cmake)
@@ -0,0 +1,2 @@
mylib location: [^
]*/Tests/RunCMake/XcFramework/export-macos-build/lib/mylib\.xcframework/macos-(arm64|x86_64|arm64_x86_64)/libmylib\.a
@@ -0,0 +1,2 @@
mylib-genex location: [^
]*/Tests/RunCMake/XcFramework/export-macos-build/lib/mylib-genex\.xcframework/macos-(arm64|x86_64|arm64_x86_64)/libmylib-genex\.a
@@ -0,0 +1 @@
include(import-genex-common.cmake)
@@ -0,0 +1 @@
include(import-common.cmake)
@@ -0,0 +1,2 @@
mylib location: [^
]*/Tests/RunCMake/XcFramework/export-install/lib/mylib\.xcframework/macos-(arm64|x86_64|arm64_x86_64)/libmylib\.a
@@ -0,0 +1 @@
include(import-common.cmake)
@@ -0,0 +1,2 @@
mylib location: [^
]*/Tests/RunCMake/XcFramework/export-install/lib/mylib\.xcframework/macos-(arm64|x86_64|arm64_x86_64)/libmylib\.a
@@ -0,0 +1,2 @@
mylib-genex location: [^
]*/Tests/RunCMake/XcFramework/export-install/lib2/mylib-genex\.xcframework/macos-(arm64|x86_64|arm64_x86_64)/libmylib-genex\.a
@@ -0,0 +1 @@
include(import-genex-common.cmake)
@@ -0,0 +1,2 @@
mylib location: [^
]*/Tests/RunCMake/XcFramework/export-install/lib/macos/libmylib\.a
@@ -0,0 +1 @@
include(import-common.cmake)
@@ -0,0 +1 @@
include(import-common.cmake)
@@ -0,0 +1,3 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/mylib-targets.cmake")