# Portable install packages with find package on frameworks?

**URL:** https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809
**Category:** Usage
**Created:** [August 23, 2023, 4:53pm UTC](https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809 "2023-08-23T16:53:15Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![rebpdx](https://discourse.cmake.org/user_avatar/discourse.cmake.org/rebpdx/32/3748_2.png) [@rebpdx](https://discourse.cmake.org/u/rebpdx)
#### Post date: [August 23, 2023, 4:53pm UTC](https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809/1 "2023-08-23T16:53:15Z")

</div>

I’m seeing conflicting information and wondering what the best practice is for handling frameworks with installed packages. Since find\_package is setting a hard coded path on some of the macOS system frameworks I’m seeing the path in the installed package from using the install export commands.

I was originally going to suggest that someone skip find\_package for system frameworks and use something such as -framework CoreFoundation as a variable instead. However I’m seeing conflicting information on why not to do that after looking to see if there was a bug on this.

[https://gitlab.kitware.com/cmake/cmake/-/issues/20871](https://gitlab.kitware.com/cmake/cmake/-/issues/20871)  
[https://gitlab.kitware.com/cmake/cmake/-/issues/18753](https://gitlab.kitware.com/cmake/cmake/-/issues/18753)

What is the proper way to handle making sure the install package is portable with target names?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [August 23, 2023, 7:13pm UTC](https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809/2 "2023-08-23T19:13:43Z")

</div>

I think one should always use `IMPORTED` targets and re-find them once installed so that things are fully relocatable (basically, you find the package again so that if it moved, it doesn’t need to be tracked explicitly).

---

<div class="post-metadata">

### Author: ![rebpdx](https://discourse.cmake.org/user_avatar/discourse.cmake.org/rebpdx/32/3748_2.png) [@rebpdx](https://discourse.cmake.org/u/rebpdx)
#### Post date: [August 23, 2023, 8:30pm UTC](https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809/3 "2023-08-23T20:30:02Z")

</div>

I don’t think I’m following. Since find\_package on system frameworks such as CoreFoundation is putting hard coded paths in INTERFACE\_LINK\_LIBRARIES doesn’t that kind of negate any downstream call on find\_package since it’s not a target?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [August 23, 2023, 10:14pm UTC](https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809/4 "2023-08-23T22:14:11Z")

</div>

No, because your targets will refer to it as `Apple::CoreFoundation` (or whatever). When that target gets remade, it can re-find the framework and provide a new path.

---

<div class="post-metadata">

### Author: ![rebpdx](https://discourse.cmake.org/user_avatar/discourse.cmake.org/rebpdx/32/3748_2.png) [@rebpdx](https://discourse.cmake.org/u/rebpdx)
#### Post date: [August 24, 2023, 4:11pm UTC](https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809/5 "2023-08-24T16:11:56Z")

</div>

That sounds like an ideal state and what I was expecting to see, however it’s not what I’m observing. I’m seeing the hard coded paths in INTERFACE\_LINK\_LIBRARIES instead of a target.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [August 25, 2023, 9:41pm UTC](https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809/6 "2023-08-25T21:41:08Z")

</div>

Interesting. Can you share a minimal example that shows this?

---

<div class="post-metadata">

### Author: ![rebpdx](https://discourse.cmake.org/user_avatar/discourse.cmake.org/rebpdx/32/3748_2.png) [@rebpdx](https://discourse.cmake.org/u/rebpdx)
#### Post date: [August 25, 2023, 11:13pm UTC](https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809/7 "2023-08-25T23:13:20Z")

</div>

Here’s an example, I did the following with these three files.

1. `mkdir build && cd build`
2. `cmake ..`
3. `cmake --build .`
4. `cmake --install .`
5. open install/lib/cmake/libtestLibTargets.cmake and observe the INTERFACE\_LINK\_LIBRARIES for target testLib::testLib

CMakeLists.txt

```auto
cmake_minimum_required(VERSION 3.23)
project("Example Framework")

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install)
set(CMAKE_INSTALL_INCLUDEDIR ${CMAKE_BINARY_DIR}/install/include)

find_library(APPKIT_LIBRARY AppKit)

set(targetName "testLib")

add_library(${targetName} SHARED dummy.cpp)

target_link_libraries(${targetName} PUBLIC ${APPKIT_LIBRARY})

install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dummy.h DESTINATION include)
install(TARGETS ${targetName} EXPORT ${targetName}Targets
    RUNTIME DESTINATION bin
    ARCHIVE DESTINATION lib
    LIBRARY DESTINATION lib
    FRAMEWORK DESTINATION lib
)
install(EXPORT ${targetName}Targets
    FILE lib${targetName}Targets.cmake
    NAMESPACE ${targetName}::
    DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/cmake/lib${targetName}
    COMPONENT ${targetName}
)

```

dummy.h

```cpp
#include <string>

class dummy {
public:
    dummy(std::string inputString);

private:
    std::string _myString;
};

```

dummy.cpp

```cpp
#include "dummy.h"

dummy::dummy(std::string inputString) : _myString{ inputString } {}

```

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [August 26, 2023, 9:45pm UTC](https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809/8 "2023-08-26T21:45:14Z")

</div>

I don’t know if it is related to your core issue, but you’ve used absolute paths in a couple of places that should use relative paths:

- The `CMAKE_INSTALL_INCLUDEDIR` variable should be relative to the install prefix, so you should only be setting it to `include`, not `${CMAKE_BINARY_DIR}/install/include`.
- Similar for installing the export file. The `install(EXPORT ...)` command should use a relative `DESTINATION`. It should be just `lib/cmake/lib${targetName}`, not `${CMAKE_INSTALL_PREFIX}/lib/cmake/lib${targetName}`.

As for linking AppKit, don’t use `find_library()` for that. In a multi-architecture world like Xcode on Apple platforms, `find_library()` isn’t appropriate because it typically will only find a library for one architecture. In this case, AppKit is expected to be provided by the SDK, so it should be linked by name only. There’s a couple of ways of doing that. With CMake 3.24 or later, I’d recommend using the generator expression that specifies to treat its argument as a framework:

```cmake
target_link_libraries(${targeTName} PUBLIC $<LINK_LIBRARY:FRAMEWORK,AppKit>)

```

If you need to support older CMake versions, you can list the framework name with the `-framework` flag as a single quoted argument:

```cmake
target_link_libraries(${targeTName} PUBLIC "-framework AppKit")

```

---

<div class="post-metadata">

### Author: ![rebpdx](https://discourse.cmake.org/user_avatar/discourse.cmake.org/rebpdx/32/3748_2.png) [@rebpdx](https://discourse.cmake.org/u/rebpdx)
#### Post date: [September 8, 2023, 12:28am UTC](https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809/9 "2023-09-08T00:28:02Z")

</div>

Thanks that clears things up.

---

<div class="post-metadata">

### Author: ![Joymaker](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/j/59ef9b/32.png) [@Joymaker](https://discourse.cmake.org/u/Joymaker)
#### Post date: [May 26, 2025, 2:08pm UTC](https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809/10 "2025-05-26T14:08:49Z")

</div>

Could you explain in detail the syntax of that generator expression? Or point us to an article? What exactly does LINK\_LIBRARY:FRAMEWORK mean and from what set of options do those words come?

---

<div class="post-metadata">

### Author: ![Angew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/angew/32/229_2.png) [@Angew](https://discourse.cmake.org/u/Angew)
#### Post date: [May 27, 2025, 7:40am UTC](https://discourse.cmake.org/t/portable-install-packages-with-find-package-on-frameworks/8809/11 "2025-05-27T07:40:35Z")

</div>

See [CMake docs](https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#link-features)
