# Unexpected build of unused target

**URL:** <https://discourse.cmake.org/t/unexpected-build-of-unused-target/9626>\
**Category:** Code\
**Tags:** gen:ninja\
**Created:** [December 13, 2023, 5:52pm UTC](https://discourse.cmake.org/t/unexpected-build-of-unused-target/9626 "2023-12-13T17:52:19Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![geertj](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/g/a698b9/32.png) [@geertj](https://discourse.cmake.org/u/geertj)\
**Post date:** [December 13, 2023, 5:52pm UTC](https://discourse.cmake.org/t/unexpected-build-of-unused-target/9626/1 "2023-12-13T17:52:20Z")

</div>

Hi,

In my project, I have a library called “Library” and a library called “LibraryTest”. They both compile from the same sources. The former is exported, the latter is compiled with address sanitation and linked against the test suite.

To get faster builds, I want to link the test suite against “Library” in the “Devel” configuration, with the intention/expectation that “LibraryTest” would not have to be compiled. In Release mode, both are compiled and the test suite is run. I’m using the Ninja Multi-Config generator. My list file looks like this:

```auto
cmake_minimum_required(VERSION 3.27)
project(Example LANGUAGES CXX)
add_library(Library lib.cc)
add_library(LibraryTest lib.cc)
target_compile_options(LibraryTest PUBLIC -fsanitize=address)
target_link_libraries(LibraryTest PUBLIC -fsanitize=address)
add_executable(test test.cc)
target_link_libraries(test Library$<$<CONFIG:Release>:Test>)

```

The list file works as expected, and the correct library is linked depending on the configuration. However, both libraries are always compiled.

Looking at the generated Ninja file for “Debug”, the “Devel/test” target has an order-only dependency on the test library:

```auto
build Devel/test: CXX_EXECUTABLE_LINKER__test_Devel CMakeFiles/test.dir/Devel/test.cc.o | Devel/libLibrary.a || Devel/libLibrary.a Devel/libLibraryTest.a

```

Removing this order-only dependency stops building the test library.

Is this behavior expected? Any thoughts on how I could make my approach work?

---

<div class="post-metadata">

**Author:** ![jtxa](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jtxa/32/1535_2.png) [@jtxa](https://discourse.cmake.org/u/jtxa)\
**Post date:** [December 13, 2023, 10:24pm UTC](https://discourse.cmake.org/t/unexpected-build-of-unused-target/9626/2 "2023-12-13T22:24:59Z")

</div>

AFAIK order-only dependencies are not built, it’s just defining the order, in case somewhere else a build was required.

Do you explicitly build the executable with e.g. `ninja test`, then it should not be built.  
Or do you simply call `ninja`, which means all targets?  
Libraries and executables are automatically added to all. To avoid this, you need to use the option `EXCLUDE_FROM_ALL`.

---

<div class="post-metadata">

**Author:** ![geertj](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/g/a698b9/32.png) [@geertj](https://discourse.cmake.org/u/geertj)\
**Post date:** [December 14, 2023, 12:23am UTC](https://discourse.cmake.org/t/unexpected-build-of-unused-target/9626/3 "2023-12-14T00:23:38Z")

</div>

I am building the executable with “ninja test,” and both Library and LibraryTest get built… This is CMake 3.27.8 and Ninja 1.11.1.

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [December 19, 2023, 3:14am UTC](https://discourse.cmake.org/t/unexpected-build-of-unused-target/9626/4 "2023-12-19T03:14:12Z")

</div>

> [@jtxa](#):
>
> AFAIK order-only dependencies are not built, it’s just defining the order, in case somewhere else a build was required.

They do tend to get built as the default order-only behavior includes the linker output.

My guess is that there’s some config-unaware processing that joins the per-config dependencies improperly. A new issue would be appreciated.

Cc: @kyle.edwards

---

<div class="post-metadata">

**Author:** ![geertj](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/g/a698b9/32.png) [@geertj](https://discourse.cmake.org/u/geertj)\
**Post date:** [December 19, 2023, 11:36pm UTC](https://discourse.cmake.org/t/unexpected-build-of-unused-target/9626/5 "2023-12-19T23:36:22Z")

</div>

Issue: [https://gitlab.kitware.com/cmake/cmake/-/issues/25521](https://gitlab.kitware.com/cmake/cmake/-/issues/25521)

If other folks are running into this, a workaround is to only add sources to the LibraryTest target in the Release configuration. In the Devel configuration, the test library will still be built, but it will be empty and therefore very fast to build. Something like:

```auto
target_sources(LibraryTest PRIVATE $<$<CONFIG:Release>:${Library_SOURCES}>)

```
