[CMake] getting the rpath right on osx

clinton at elemtech.com clinton at elemtech.com
Mon Nov 2 08:23:56 EST 2015



----- On Nov 2, 2015, at 2:26 AM, Boudewijn Rempt boud at valdyas.org wrote:

> I checked the manual and the blog post about rpath on osx, but I'm still
> confused, and still not getting it right...
> 
> I build and installed Qt 5.6 alpha like this:
> 
> ./configure -prefix /Users/boudewijnrempt/kf5/i
> 
> Then I made a small test project, consisting of nothing but a main that links to
> QtCore.
> 
> If I build that with qmake, with this .pro file:
> 
> QT       += core
> QT       -= gui
> TARGET = rpathqmake
> CONFIG   += console
> CONFIG   -= app_bundle
> TEMPLATE = app
> SOURCES += main.cpp
> 
> The r-path is set:
> 
> Boudewijns-Mac-mini:test boudewijnrempt$ otool -L rpathqmake
> rpathqmake:
>     @rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.6.0, current
>     version 5.6.0)
>     /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration
>     (compatibility version 1.0.0, current version 1.0.0)
>     /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility
>     version 1.0.0, current version 275.0.0)
>     /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
>     /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version
>     1213.0.0)
> 
> Boudewijns-Mac-mini:test boudewijnrempt$ otool -L rpathqmake | grep -i rpath
> rpathqmake:
>     @rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.6.0, current
>     version 5.6.0

Keep in mind, "otool -L" doesn't show rpaths.
@rpath/QtCore.framework/Versions/5/QtCore is not an rpath.
@rpath is a place holder where an rpath can be substituted.
Anytime you see "@rpath" what it means is that the dependent library wants to be found using rpaths.
Use "otool -l" | grep -A2 LC_RPATH to see the rpaths.

> 
> If I try a minimal cmakelists.txt, the rpath isn't set, I tried with and without
> all those RPATH related lines,
> they don't seem to make a difference. I'm using cmake 3.3.2.
> 
> cmake_minimum_required(VERSION 2.8.12)
> cmake_policy(SET CMP0042 NEW)
> set(CMAKE_MACOSX_RPATH ON)
> SET(CMAKE_SKIP_BUILD_RPATH TRUE)
> SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
> SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
> set(REQUIRED_QT_VERSION 5.3.0)
> find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Core)
> add_executable(rpathcmake main.cpp)
> target_link_libraries(rpathcmake Qt5::Core)
> install(TARGETS rpathcmake DESTINATION /Users/boudewijnrempt/kf5/i/bin)

If you remove 
 set(CMAKE_MACOSX_RPATH ON)
 SET(CMAKE_SKIP_BUILD_RPATH TRUE)
 SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
 SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
then, it would probably be a minimal example.

> 
> Only adding something like this makes it work:
> 
> set_target_properties(rpathcmake PROPERTIES INSTALL_RPATH
> "/Users/boudewijnrempt/kf5/i/lib")
> 
> Which I'm pretty sure is something I don't want.

To fix the errors below, you actually to do something like this.
set_target_properties(rpathcmake PROPERTIES INSTALL_RPATH
 "/Users/boudewijnrempt/kf5/i/lib")

What you probably want is to use a variable instead of an absolute path.
set_target_properties(rpathcmake PROPERTIES INSTALL_RPATH
 "@loader_path/../lib")

That property along with MACOSX_RPATH, or the global property CMAKE_MACOSX_RPATH are the 2 first variables you would set.
MACOSX_RPATH property on a target indicates that its install 'ID' contains @rpath, and it wants to be found using rpaths.  INSTALL_RPATH property is a list of rpaths to help find dependencies which want to be found using rpaths.

> 
> Boudewijns-Mac-mini:test boudewijnrempt$ make install
> [100%] Built target rpathcmake
> Install the project...
> -- Install configuration: ""
> -- Up-to-date: /Users/boudewijnrempt/kf5/i/bin/rpathcmake
> Boudewijns-Mac-mini:test boudewijnrempt$ otool -L
> /Users/boudewijnrempt/kf5/i/bin/rpathcmake
> /Users/boudewijnrempt/kf5/i/bin/rpathcmake:
>     @rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.6.0, current
>     version 5.6.0)
>     /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
>     /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version
>     1197.1.1)
> Boudewijns-Mac-mini:test boudewijnrempt$ ~/kf5/i/bin/rpathcmake
> dyld: Library not loaded: @rpath/QtCore.framework/Versions/5/QtCore
>   Referenced from: /Users/boudewijnrempt/kf5/i/bin/rpathcmake
>   Reason: image not found
> Trace/BPT trap: 5
> Boudewijns-Mac-mini:test boudewijnrempt$ otool -L
> /Users/boudewijnrempt/kf5/i/bin/rpathcmake
> /Users/boudewijnrempt/kf5/i/bin/rpathcmake:
>     @rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.6.0, current
>     version 5.6.0)
>     /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
>     /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version
>     1197.1.1)
> 
> What should I do?

Set the INSTALL_RPATH target property.

Clint



More information about the CMake mailing list