I have an issue very similar to How can I point C++ tests to my build-directory copy of my library and not to the installed library when LD_LIBRARY_PATH points to the installed one? but unrelated to LD_LIBRARY_PATH
.
In my project, I first create a library using the standard cmake functions. Here is a simplified version:
# Installation directories
include(GNUInstallDirs)
# Build library
add_library(${PROJECT_NAME} SHARED
${SRC_FILES}
)
# Definitions
target_compile_definitions(${PROJECT_NAME} PUBLIC ${DEFINITIONS})
# Properties
set_target_properties(${PROJECT_NAME} PROPERTIES
CXX_STANDARD 20
)
# Compile options
target_compile_options(${PROJECT_NAME} PRIVATE
-Wall -Wextra -Wpedantic
)
# Include directories
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
# System include directories
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC
${SYSTEM_INCLUDE_DIRS}
)
# Link libraries
target_link_libraries(${PROJECT_NAME} PUBLIC
${SYSTEM_LIBRARIES}
)
I then want to build some tests, which I do through a similar procedure, and link these tests to my library (this CMakeLists.txt is in a test subfolder):
# Build tests
add_executable(${PROJECT_NAME}_tests
${TEST_SRC_FILES}
)
# Definitions
target_compile_definitions(${PROJECT_NAME}_tests PUBLIC ${TEST_DEFINITIONS})
# Properties
set_target_properties(${PROJECT_NAME}_tests PROPERTIES
CXX_STANDARD 20
)
# Compile Options
target_compile_options(${PROJECT_NAME}_tests PRIVATE
-Wall -Wextra -Wpedantic
)
# Include Directories
target_include_directories(${PROJECT_NAME}_tests PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
)
# System Include Directories
target_include_directories(${PROJECT_NAME}_tests SYSTEM PUBLIC
${TEST_SYSTEM_INCLUDE_DIRS}
)
# Link Libraries
target_link_libraries(${PROJECT_NAME}_tests PUBLIC
${PROJECT_NAME}
${TEST_SYSTEM_LIBRARIES}
)
# Enable ctest
enable_testing()
add_test(NAME ${PROJECT_NAME}_tests COMMAND ${PROJECT_NAME}_tests)
When I build, everything is great. The tests link to my library and life is good. If I examine the executable with ldd
I see:
libmycoolproject.so => /home/username/src/mycoolproject/build/libmycoolproject.so (0x00007ffd2c8c3000)
And with readelf -d
:
0x0000000000000001 (NEEDED) Shared library: [libconvert.so]
... (more libraries)
0x000000000000001d (RUNPATH) Library runpath: [/home/username/src/mycoolproject/build:/usr/local/lib:/home/username/src/mycoolproject/build/gtest/lib]
Note that one of the system libraries I depend on lives in /usr/local/lib
.
However as soon as I install my library with sudo make install
, ldd
tells me:
libmycoolproject.so => /usr/local/lib/libmycoolproject.so (0x00007ffb480b3000)
The problem is then that if I make local changes, build, and run my tests, the tests link to the installed library rather than the one in my build folder.
How can I ensure that my tests link with the build directory version at runtime? What is going on here with the link order / RUNPATH
?
Things I’ve tried without successful result:
- putting
BUILD_RPATH ${CMAKE_BINARY_DIR}
inset_target_properties
- appending to
CMAKE_BUILD_RPATH
- changing the order of the libraries in
target_link_libraries
- linking against
${CMAKE_BINARY_DIR}/lib${PROJECT_NAME}.so
instead of${PROJECT_NAME}