macOS: Allow IMPORTED_LOCATION to be a framework folder

Issue: #24946
This commit is contained in:
Kyle Edwards 2023-06-16 11:54:24 -04:00 committed by Brad King
parent acc7e6a144
commit d605f728f7
10 changed files with 86 additions and 56 deletions

View File

@ -15,6 +15,11 @@ is the location of the ``.dll`` part of the library. For ``UNKNOWN``
libraries this is the location of the file to be linked. Ignored for
non-imported targets.
.. versionadded:: 3.28
For frameworks on macOS, this may be the location of the framework folder
itself.
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,

View File

@ -0,0 +1,5 @@
imported-target-framework-path
------------------------------
* The :prop_tgt:`IMPORTED_LOCATION` property of a macOS framework may now be
the location of the framework folder itself.

View File

@ -1579,7 +1579,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);
@ -1597,16 +1599,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,

View File

@ -3828,7 +3828,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
if (lib.Target == nullptr) {
libDir = cmSystemTools::CollapseFullPath(
lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
} else if (lib.Target->Target->IsFrameworkOnApple()) {
} else if (lib.Target->Target->IsFrameworkOnApple() ||
this->IsImportedFrameworkFolderOnApple(config)) {
libDir = lib.Target->GetLocation(config);
} else {
continue;
@ -8572,6 +8573,16 @@ bool cmGeneratorTarget::IsFrameworkOnApple() const
return this->Target->IsFrameworkOnApple();
}
bool cmGeneratorTarget::IsImportedFrameworkFolderOnApple(
const std::string& config) const
{
return this->IsApple() && this->IsImported() &&
(this->GetType() == cmStateEnums::STATIC_LIBRARY ||
this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::UNKNOWN_LIBRARY) &&
cmSystemTools::IsPathToFramework(this->GetLocation(config));
}
bool cmGeneratorTarget::IsAppBundleOnApple() const
{
return this->Target->IsAppBundleOnApple();

View File

@ -812,6 +812,10 @@ public:
Apple. */
bool IsFrameworkOnApple() const;
/** Return whether this target is an IMPORTED library target on Apple
with a .framework folder as its location. */
bool IsImportedFrameworkFolderOnApple(const std::string& config) const;
/** Return whether this target is an executable Bundle on Apple. */
bool IsAppBundleOnApple() const;

View File

@ -1,17 +1,4 @@
^CMake Error in CMakeLists.txt:
IMPORTED_LOCATION not set for imported target "unknown_lib"( configuration
"[^"]+")?.
+
CMake Error in CMakeLists.txt:
IMPORTED_LOCATION not set for imported target "static_lib"( configuration
"[^"]+")?.
+
CMake Error in CMakeLists.txt:
IMPORTED_IMPLIB not set for imported target "shared_lib"( configuration
"[^"]+")?.(
+
CMake Error in CMakeLists.txt:
^(CMake Error in CMakeLists.txt:
IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static|shared)_lib"( configuration
"[^"]+")?.)*
+
CMake Generate step failed. Build files cannot be regenerated correctly.$
"[^"]+")?.
+)+CMake Generate step failed. Build files cannot be regenerated correctly.$

View File

@ -1,34 +1,4 @@
^CMake Warning \(dev\) in CMakeLists.txt:
Policy CMP0111 is not set: An imported target missing its location property
fails during generation. Run "cmake --help-policy CMP0111" for policy
details. Use the cmake_policy command to set the policy and suppress this
warning.
IMPORTED_LOCATION not set for imported target "unknown_lib"( configuration
"[^"]+")?.
This warning is for project developers. Use -Wno-dev to suppress it.
+
CMake Warning \(dev\) in CMakeLists.txt:
Policy CMP0111 is not set: An imported target missing its location property
fails during generation. Run "cmake --help-policy CMP0111" for policy
details. Use the cmake_policy command to set the policy and suppress this
warning.
IMPORTED_LOCATION not set for imported target "static_lib"( configuration
"[^"]+")?.
This warning is for project developers. Use -Wno-dev to suppress it.
+
CMake Warning \(dev\) in CMakeLists.txt:
Policy CMP0111 is not set: An imported target missing its location property
fails during generation. Run "cmake --help-policy CMP0111" for policy
details. Use the cmake_policy command to set the policy and suppress this
warning.
IMPORTED_IMPLIB not set for imported target "shared_lib"( configuration
"[^"]+")?.
This warning is for project developers. Use -Wno-dev to suppress it.(
+
CMake Warning \(dev\) in CMakeLists.txt:
^(CMake Warning \(dev\) in CMakeLists.txt:
Policy CMP0111 is not set: An imported target missing its location property
fails during generation. Run "cmake --help-policy CMP0111" for policy
details. Use the cmake_policy command to set the policy and suppress this
@ -36,4 +6,13 @@ CMake Warning \(dev\) in CMakeLists.txt:
IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static|shared)_lib"( configuration
"[^"]+")?.
This warning is for project developers. Use -Wno-dev to suppress it.)*$
This warning is for project developers. Use -Wno-dev to suppress it.
+)+CMake Warning \(dev\) in CMakeLists.txt:
Policy CMP0111 is not set: An imported target missing its location property
fails during generation. Run "cmake --help-policy CMP0111" for policy
details. Use the cmake_policy command to set the policy and suppress this
warning.
IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static|shared)_lib"( configuration
"[^"]+")?.
This warning is for project developers. Use -Wno-dev to suppress it.$

View File

@ -1,5 +1,7 @@
enable_language(C)
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install")
# Create framework and ensure header is placed in Headers
set(input_header "${CMAKE_SOURCE_DIR}/Gui.h")
add_library(Gui SHARED Gui.c "${input_header}")
@ -8,6 +10,8 @@ set_target_properties(Gui PROPERTIES
FRAMEWORK TRUE
)
install(TARGETS Gui DESTINATION .)
add_executable(app main.c)
target_link_libraries(app PRIVATE Gui)

View File

@ -0,0 +1,7 @@
enable_language(C)
add_library(Gui IMPORTED UNKNOWN)
set_property(TARGET Gui PROPERTY IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/../FrameworkConsumption-build/install/Gui.framework")
add_executable(app main.c)
target_link_libraries(app PRIVATE Gui)

View File

@ -113,7 +113,16 @@ function(framework_consumption)
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
run_cmake(FrameworkConsumption)
run_cmake_command(FrameworkConsumption-build ${CMAKE_COMMAND} --build .)
run_cmake_command(FrameworkConsumption-build ${CMAKE_COMMAND} --build . --config Release)
run_cmake_command(FrameworkConsumption-install ${CMAKE_COMMAND} --install . --config Release)
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/ImportedFrameworkConsumption-build")
set(RunCMake_TEST_NO_CLEAN 1)
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
run_cmake(ImportedFrameworkConsumption)
run_cmake_command(ImportedFrameworkConsumption-build ${CMAKE_COMMAND} --build . --config Release)
endfunction()
framework_consumption()