Why is not accessible the library built on top level directory under the test subdirectory?

I have a library module which has some tests under test subdirectory.
The test binaries are built and linked to the library from the top level, but when the tests are executed, does not find the shared object. The shared object it is there, I guess in the right place, but I need to manually copy to test subdirectory in order to execute. I try to explain in more details…

The top level CMakeLists.txt use a construction based on target_sources

add_library(${PROJECT_NAME} SHARED) 
add_library(COMMON::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
target_sources(${PROJECT_NAME}
  ...)
enable_testing()
add_subdirectory(test)

(of course more stuff are there, which I skipped to copy here)

Then the test directory has a CMakeLists.txt like

project(lib-tests)

# Macro for the gtest framework.
macro(create_unit_test testname execname)
    target_sources(tsdb-lib
        PRIVATE ${execname})
    add_executable(${testname}) # ${execname})
    set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX)
    target_link_libraries(${testname} gtest)
    target_link_libraries(${testname} gtest_main)
    target_link_libraries(${testname} pthread)
    target_link_libraries(${testname} COMMON::tsdb-lib)
    add_test(${testname} ${testname})
endmacro(create_unit_test)

create_unit_test(aggregation_test aggregation_test.cpp)

The name of the library built and to be tested is called ‘tsdb-lib’.
All the tests fails with not finding the libtsdb-lib.so as the following

1/6 Test #1: aggregation_test …***Failed 0.00 sec
/build/lib/build/test/aggregation_test: error while loading shared libraries: libtsdb-lib.so: cannot open shared object file: No such file or directory

I am running this cmake using Nix, which leaves me the unfinished working directory, I navigate there and I see the build directory where it is the libtsdb-lib.so and the test files under test subdirectory.
If I copy the libtsdb-lib.so to the test subdirectory, manually I can run the tests.

The question is, why is not accessible the library built on top level directory under the test, specifically only at runtime, because the linking it works?

Please provide a complete, minimal project which reproduces the problem. The process of creating that will likely already uncover the cause for you. Based on the details provided so far, I suspect the problem will be in some part of the project that hasn’t been shown.

I took one public repo which is the closest to reproduce the problem. I cloned that and I made two commits, which you can find it here: https://github.com/tiborkiss/cmake_cpp_example/commits/addtest

The earliest commit adds a test using gtest and I also changed to generate SHARED target from the library which I am testing it. That is the case I would like to have. (In my production system if I generate static library, it will be too big, then everywhere I don’t want to link as static.)

If I run the test with linked shared library, it cannot find the shared library even if is there in build directory. I don’t know how to use gtest with shared library, maybe is possible to test only with static library.

In the next commit I added another target postfixed with _static. In that case the test works.

Now my question has been reduced. I just would like to know, if there is a way to link the test only to shared target, or I must make this duplicated target, just to have the static for test?

Here are the steps to reproduce:

  1. We need to install a nix build system with one single command
    curl -L https://nixos.org/nix/install | sh
  2. Build using nix command
    nix-build release.nix -A myapp -K
    There the -Kwill make nix to not delete the working directory. When building through nix, the entire scope (source files) are copied into that temporary working directory and the build directory will remain there. In order to check what’s wrong, we need to go into that directory, find the build and there we see that the shared library it was generated, but I don’t know the mechanism to tell the test binary to find it because the test is in a subdirectory.

The big advantage of nix in this case is that gtest is downloaded by nix, reducing the complexity in CMakeLists.txt. In my concrete case, nix has deeper implication, we have too many big dependencies linked as shared libraries, which we just prepare within nix and cmake just deals with what is local in the scope.

One more note:

In the case when I have just shared library, the test fails to find the .so file. Manually I go into the build directory and I copy the .so file into the subdirectory where is the test, then it works. Means that the test executable is correctly linked to a shared library, just the library search path is not good.

Finally I figured out how to set load library path just for the test.
I made another diff, where I removed the _static postfixed target and I just use shared.
In the test I added this.

set_property(TEST a-lib-tests PROPERTY ENVIRONMENT “LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}”)