# Link issues with CMake, CTest and Catch2

**URL:** <https://discourse.cmake.org/t/link-issues-with-cmake-ctest-and-catch2/8343>\
**Category:** Code\
**Created:** [June 16, 2023, 5:38pm UTC](https://discourse.cmake.org/t/link-issues-with-cmake-ctest-and-catch2/8343 "2023-06-16T17:38:36Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![antoniovazquezblanco](https://discourse.cmake.org/user_avatar/discourse.cmake.org/antoniovazquezblanco/32/3448_2.png) [@antoniovazquezblanco](https://discourse.cmake.org/u/antoniovazquezblanco)\
**Post date:** [June 16, 2023, 5:38pm UTC](https://discourse.cmake.org/t/link-issues-with-cmake-ctest-and-catch2/8343/1 "2023-06-16T17:38:36Z")

</div>

I’ve been helping a friend improve it’s SDR (Software Defined Radio) project by trying to improve the build system.

The project has gotten to a point where everything seems to be quite stable and functional so I wanted to start hacking on a unit testing infrastructure. My tech stack is CMake + CTest + Catch2.

The project structure is as follows:

- `src` - source code of the sigutils library.
- `tests` - source code that generates the test binaries.

The source code can be found at [GitHub - antoniovazquezblanco/sigutils at dev/tests](https://github.com/antoniovazquezblanco/sigutils/tree/dev/tests).

Currently, the base `CMakeLists.txt` adds the `src` dir. In the `src/CMakeLists.txt` the sigutils library target is defined and everything seems to be working as expected. In linux, this target generates an `.so` file, a `.dll` in windows and a `.dylib` in MacOS…

At the bottom, the base `CMakeLists.txt` adds the `tests` dir and attempts to generate an executable for CTest to execute later on…

I am having problems compiling and executing the tests:

- On linux things seem to be working…
- On MacOS things break during the compilation phase due to a `dyld[6621]: Library not loaded: '@rpath/libsigutils.1.dylib' Referenced from: '/Users/runner/work/sigutils/sigutils/build/tests/sigutils_test' Reason: tried: '/usr/local/lib/libsigutils.1.dylib' (no such file), '/usr/lib/libsigutils.1.dylib' (no such file)`
- On Windows things break when calling CTest with an exception while executing the tests due to being unable to load our library when executing the test; `1/1 Test #1: Test normalized frecuency scale ...Exit code 0xc0000135`

Build and test logs:

- Linux [Add a sample testing structure · antoniovazquezblanco/sigutils@7b1feb2 · GitHub](https://github.com/antoniovazquezblanco/sigutils/actions/runs/5292386560/jobs/9579212691)
- MacOS [Add a sample testing structure · antoniovazquezblanco/sigutils@7b1feb2 · GitHub](https://github.com/antoniovazquezblanco/sigutils/actions/runs/5292386560/jobs/9579212972)
- Windows [Add a sample testing structure · antoniovazquezblanco/sigutils@7b1feb2 · GitHub](https://github.com/antoniovazquezblanco/sigutils/actions/runs/5292386560/jobs/9579212838)

I am currently linking the library with the following command:

```plaintext
target_link_libraries(sigutils_test $<TARGET_LINKER_FILE:sigutils>)

```

I am also trying to execute the tests in the `src` working directory to be able to find the lib:

```plaintext
catch_discover_tests(sigutils_test WORKING_DIRECTORY "$<TARGET_FILE_DIR:sigutils>")

```

I don’t know if I am making things difficult for myself or if my approach is generally oriented with good CMake practices. Any orientation in this regard is appreciated… Some of the doubts I had during the process include:

- Should I compile a static version of the lib and always statically link the tests? This may take longer but it ensures everything works…
- I would rather not mix library code and test code but, is there any alternative?
- Should the library be copied to the tests folder on library compilation? Seems a weird approach…

Thanks in advance!

---

<div class="post-metadata">

**Author:** ![antoniovazquezblanco](https://discourse.cmake.org/user_avatar/discourse.cmake.org/antoniovazquezblanco/32/3448_2.png) [@antoniovazquezblanco](https://discourse.cmake.org/u/antoniovazquezblanco)\
**Post date:** [June 17, 2023, 8:39pm UTC](https://discourse.cmake.org/t/link-issues-with-cmake-ctest-and-catch2/8343/2 "2023-06-17T20:39:24Z")

</div>

After some research I concluded that, in my case, one of the best options is to flatten the target destinations while keeping the source in different folders.

```plaintext
# Always use top level dir for generated targets to avoid linker problems
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

```

This causes generated targets to be placed in my build directory root.

I am still facing problems in Windows but they seem non-related to the original issue…

For those interested, the new logs are located at:

- Linux [Add a sample testing structure · antoniovazquezblanco/sigutils@c474298 · GitHub](https://github.com/antoniovazquezblanco/sigutils/actions/runs/5299885833/jobs/9593118688)
- MacOS [Add a sample testing structure · antoniovazquezblanco/sigutils@c474298 · GitHub](https://github.com/antoniovazquezblanco/sigutils/actions/runs/5299885833/jobs/9593118743)
- Windows [Add a sample testing structure · antoniovazquezblanco/sigutils@c474298 · GitHub](https://github.com/antoniovazquezblanco/sigutils/actions/runs/5299885833/jobs/9593118719)

---

<div class="post-metadata">

**Author:** ![Lecris](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lecris/32/3193_2.png) [@Lecris](https://discourse.cmake.org/u/Lecris)\
**Post date:** [February 15, 2024, 5:25pm UTC](https://discourse.cmake.org/t/link-issues-with-cmake-ctest-and-catch2/8343/3 "2024-02-15T17:25:09Z")

</div>

I’ve also been trying to tackle this problem recently I have tried your approach, but no luck yet

> <https://github.com/spglib/spglib/actions/runs/7919826777/job/21621486014?pr=437>

I have seen an alternative \[1\], but that one is also painful to implement here. I’ve tried setting up the `PATH` variable \[2\], and that didn’t do anything either.

* * *

1. [Using gtest\_discover\_tests from cmake.test() in conan2 · Issue #12782 · conan-io/conan · GitHub](https://github.com/conan-io/conan/issues/12782#issuecomment-1372233374) 

2. [Using gtest\_discover\_tests from cmake.test() in conan2 · Issue #12782 · conan-io/conan · GitHub](https://github.com/conan-io/conan/issues/12782#issuecomment-1372270581)

---

<div class="post-metadata">

**Author:** ![Lecris](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lecris/32/3193_2.png) [@Lecris](https://discourse.cmake.org/u/Lecris)\
**Post date:** [February 15, 2024, 7:10pm UTC](https://discourse.cmake.org/t/link-issues-with-cmake-ctest-and-catch2/8343/4 "2024-02-15T19:10:59Z")

</div>

Apparently the folder structure is important, the following worked:

```cmake
	set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
	set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
	set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})

```
