I am working on a Project, which is installed by defining export LD_DIBRARY_PATH=...
.
My Problem is, that when I'm developing, the compiled test files linking to the installed library and not to the currently compiled library.
My project is depended on another project inside my LD_DIBRARY_PATH
, so I cannot unset the path for testing.
I found the following questions, however they could not help me:
I could reproduce this with the following example:
./CMakeLists.txt
./src/libA.cpp
./src/CMakeLists.txt
./include/libA.hpp
./test/test_libA.cpp
./test/CMakeLists.txt
CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
project(
LibraryTest
VERSION 0.1
LANGUAGES CXX)
add_subdirectory(src)
enable_testing()
add_subdirectory(test)
install(
TARGETS ${PROJECT_NAME}Lib
EXPORT ${PROJECT_NAME}Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(
EXPORT ${PROJECT_NAME}Targets
FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
include/libA.hpp
#pragma one
bool foo();
src/CMakeLists.txt
add_library(
${PROJECT_NAME}Lib SHARED
libA.cpp)
target_include_directories(
${PROJECT_NAME}Lib PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/>)
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}Lib )
src/libA.cpp
#include "libA.hpp"
bool foo()
{
return true;
}
test/CMakeLists.txt
# Download GTest
include(FetchContent)
option(INSTALL_GTEST "Enable installation of googletest." OFF)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest
GIT_TAG v1.13.0)
FetchContent_MakeAvailable(googletest)
include(GoogleTest)
# Add test
add_executable(test_libA test_libA.cpp)
target_link_libraries(
test_libA
${PROJECT_NAME}::${PROJECT_NAME}
GTest::gtest_main
GTest::gtest
GTest::gmock
)
gtest_add_tests(TARGET test_libA)
test/test_libA.cpp
#include "libA.hpp"
#include <gtest/gtest.h>
TEST(libA, dummy)
{
EXPECT_TRUE(foo());
}
int main(int argc, char *argv[])
{
::testing::InitGoogleTest(&argc, argv);
auto result = RUN_ALL_TESTS();
return result;
}
Building with cmake 3.22.1
and g++ 12.1.0
:
mkdir build
cd build
cmake ..
make
make install
ldd
results in the following output
ldd test/test_libA
libLibraryTestOut.so => $LD_LIBRARY_PATH/lib/libLibraryTestLib.so
so I cannot unset the path for testing
Oh yes you can. Each process has its own environment (set of environment variables). You could set the LD_LIBRARY_PATH
environment variable to a version with the path to your installed library is removed, or a version where your build-directory version of your library has a higher precedence (shows up earlier in the list) than the installed one.
You can use your shell's mechanism for setting environment variables for a process (such as Bash, where you can set the variable at the start of the command line), or use your system's command for doing so (Ex. env
), or use CMake's cross-platform alternative (cmake -E env
), or if you're using CTest, use the ENVIRONMENT
test property, or if you're additionally using CMake presets, use the environment
field of a test preset.
But the fact that you're using it for an installation in the first place is not great. Quoting from the Linux Documentation Project:
LD_LIBRARY_PATH
is handy for development and testing, but shouldn't be modified by an installation process for normal use by normal users; see "Why LD_LIBRARY_PATH is Bad" at http://www.visi.com/~barr/ldpath.html for an explanation of why. But it's still useful for development or testing, and for working around problems that can't be worked around otherwise.
You could stop doing that and instead use other mechanisms of your system such as the PATH
environment variable or RPATH
.