Skip to content

Build rpaths should not have the CMAKE_STAGING_PREFIX -> CMAKE_INSTALL_PREFIX transformation done to them

CMake has logic which looks for CMAKE_STAGING_PREFIX in rpaths. When such a prefix is encountered, it is instead replaced with the value of CMAKE_INSTALL_PREFIX.

Code https://gitlab.kitware.com/cmake/cmake/-/blob/45ac71d8bcb9c6bc0238a1a772029170cbf354dc/Source/cmComputeLinkInformation.cxx#L2348

Commit 7cd65c97

I think this makes sense to do for install rpaths, but not build rpaths, because it breaks the execution of application binaries from the build dir.

Sample projects, reproducible on Linux and macOS. The library project needs to be built separately, so that CMake considers it an external library outside of any explicit link dirs, and embeds an rpath to the external library inside the application.

# library project
cmake_minimum_required(VERSION 3.16)
project(issue LANGUAGES CXX)

file(GENERATE OUTPUT "lib.cpp" CONTENT "void method() {}")
add_library(mylib SHARED ${CMAKE_BINARY_DIR}/lib.cpp)
install(TARGETS mylib)
# app project
cmake_minimum_required(VERSION 3.16)
project(issue LANGUAGES CXX)

find_library(mylib mylib HINTS ${MYLIB_DIR})

file(GENERATE OUTPUT "main.cpp" CONTENT "
void method();
int main(int, char**) {
  method();
  return 0;
}
")
add_executable(app ${CMAKE_BINARY_DIR}/main.cpp)
target_link_libraries(app PRIVATE ${mylib})
mkdir lib_build && cmake ~/lib_project -DCMAKE_STAGING_PREFIX=/tmp/my_sysroot && ninja && ninja install
cd ..
mkdir app_build && cmake ~/app_project -DMYLIB_DIR=/tmp/my_sysroot -DCMAKE_STAGING_PREFIX=/tmp/my_sysroot
ninja
/usr/bin/c++ CMakeFiles/app.dir/main.cpp.o -o app  -Wl,-rpath,/usr/local/lib  /tmp/my_sysroot/lib/libmylib.dylib
./app                                                                                                                                                                                                                                                               130 ↵
dyld: Library not loaded: @rpath/libmylib.dylib
  Referenced from: build/./app
  Reason: image not found

Note how -Wl,-rpath,/usr/local/lib contains the value of the default CMAKE_INSTALL_PREFIX, which was replaced by the logic mentioned above.

If I configure the application project without setting CMAKE_STAGING_PREFIX to the same location where the library is, then the embedded rpath remains -Wl,-rpath,/tmp/my_sysroot/lib and the built app launches fine.

I expect the application to be runnable from the build dir, relying on the default build rpath mechanism that CMake provides, regardless of what value CMAKE_STAGING_PREFIX might have.

Upstream Qt issue where this is hit https://bugreports.qt.io/browse/QTBUG-102592

Edited by alcroito
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information