Cmake, Rpath, $Origin and @Loader_Path

How to set multiple RPATH directories using CMake on MacOS

According to the documentation, the paths should not be separated with colons, but with semicolons:

set_target_properties(mytarget
PROPERTIES
INSTALL_RPATH "@loader_path/../lib;@loader_path/../thirdparty/lib"
)

Or, using the command set to let CMake deals with the separator:

set(MY_INSTALL_RPATH
"@loader_path/../lib"
"@loader_path/../thirdparty/lib"
)
set_target_properties(mytarget
PROPERTIES
INSTALL_RPATH "${MY_INSTALL_RPATH}"
)

EDIT: (thanks Tsyvarev for the comment)

Or, using the command set_property, which accepts multivalue properties:

set_property(
TARGET mytarget
PROPERTY INSTALL_RPATH
"@loader_path/../lib"
"@loader_path/../thirdparty/lib"
)

How to set CMAKE_INSTALL_RPATH with multiple directories?

Snippet:

# note: macOS is APPLE and also UNIX !
if(APPLE)
set_target_properties(foo PROPERTIES
INSTALL_RPATH "@loader_path;@loader_path/...")
elseif(UNIX)
set_target_properties(foo PROPERTIES
INSTALL_RPATH "$ORIGIN:$ORIGIN/...")
endif()

Related CMake variable:

  • https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_RPATH.html
  • https://cmake.org/cmake/help/latest/prop_tgt/BUILD_WITH_INSTALL_RPATH.html

Related CMP:

  • https://cmake.org/cmake/help/latest/policy/CMP0068.html
  • https://cmake.org/cmake/help/latest/policy/CMP0095.html

How to link a shared library with CMake with relative path

From the documentation:

By default if you don't change any RPATH related settings, CMake will link the executables and shared libraries with full RPATH to all used libraries in the build tree.

This is the behaviour you are seeing.

However, there are a number of ways to change this to match the behaviour you require.

Some examples from the above linked docs:

# use, i.e. don't skip the full RPATH for the build tree
SET(CMAKE_SKIP_BUILD_RPATH FALSE)

# when building, don't use the install RPATH already
# (but later on when installing)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)

# the RPATH to be used when installing
SET(CMAKE_INSTALL_RPATH "")

# don't add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)

Using the above you'll likely want to set CMAKE_INSTALL_RPATH and then distribute the installed binary.

If you want to distribute from the binary in your build tree, it is also possible to bypass CMake's rpath handling and modify the rpath directly using linker flags:

set_target_properties(game PROPERTIES LINK_FLAGS "-Wl,-rpath,./")

CMAKE RPATH not working - could not find shared object file

It is because you build heart and run from the same cmake project:

CMAKE_INSTALL_RPATH_USE_LINK_PATH is an interesting and very useful option. When building a target with RPATH, CMake determines the RPATH by using the directories of all libraries to which this target links. Some of these libraries may be located in the same build tree, e.g. libbar.so, these directories are also added to the RPATH.
If this option is enabled, all these directories except those which are also in the build tree will be added to the install RPATH automatically. The only directories which may then still be missing from the RPATH are the directories where the libraries from the same project (i.e. libbar.so) are installed to. If the install directory for the libraries is not one of the systems default library directories, you have to add this directory yourself to the install RPATH by setting CMAKE_INSTALL_RPATH accordingly

You can try this:

SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

More documentation here cmake rpath handling

EDIT:

Only this should work:

set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

add_library(heart SHARED ${HEART_FILES})
add_executable(run ${RUN_FILES})
target_link_libraries(run heart)

install(
TARGETS heart run
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
)

Clean your build directory and then:

cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/home/person/target/usr/local ..
make install

At the end of the g++ line Linking CXX executable run you should see like -Wl,-rpath,/home/person/target/usr/local/lib

If you want a fully relocatable package:

set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")

PS: are you sur that it is libheart.so that is not found ?



Related Topics



Leave a reply



Submit