# Propagation of compile definitions

**URL:** https://discourse.cmake.org/t/propagation-of-compile-definitions/15386
**Category:** Usage
**Created:** [December 11, 2025, 3:34pm UTC](https://discourse.cmake.org/t/propagation-of-compile-definitions/15386 "2025-12-11T15:34:47Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![adaldev](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/9dc877/32.png) [@adaldev](https://discourse.cmake.org/u/adaldev)
#### Post date: [December 11, 2025, 3:34pm UTC](https://discourse.cmake.org/t/propagation-of-compile-definitions/15386/1 "2025-12-11T15:34:47Z")

</div>

Hi,

I’ve got a static library target L where I do:

```cmake
target_compile_definitions(L PUBLIC SOMESYMBOL)

```

In an application A, I’m linking against L:

```cmake
target_link_library(A PRIVATE L)

```

I’m then expecting A to inherit `SOMESYMBOL` but:

```cmake
get_target_property(ouputvar A <INTERFACE_>COMPILE_DEFINITIONS)
message(${ouputvar})

```

displays only

> outputvar-NOTFOUND

What is happening?

Regards  
A.

---

<div class="post-metadata">

### Author: ![Andrej730](https://discourse.cmake.org/user_avatar/discourse.cmake.org/andrej730/32/5752_2.png) [@Andrej730](https://discourse.cmake.org/u/Andrej730)
#### Post date: [December 11, 2025, 7:59pm UTC](https://discourse.cmake.org/t/propagation-of-compile-definitions/15386/2 "2025-12-11T19:59:07Z")

</div>

They do propagate, you can see it when running the build.

```cmake
cmake_minimum_required(VERSION 3.15)
project(mypkg CXX)

add_library(L src/mypkg.cpp)
target_compile_definitions(L PUBLIC SOMESYMBOL)
add_library(A src/mypkg.cpp)
target_link_libraries(A PRIVATE L)

```

Output (note `SOMESYMBOL` present in both commands):

```auto
# ninja -v -n
[1/4] L:\Software\MICROS~2\2022\COMMUN~1\VC\Tools\MSVC\1444~1.352\bin\Hostx64\x64\cl.exe /nologo /TP -DSOMESYMBOL /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od /RTC1 -MDd /showIncludes /FoCMakeFiles\L.dir\src\mypkg.cpp.obj /FdCMakeFiles\L.dir\L.pdb /FS -c L:\oblivion\conan-test\src\mypkg.cpp
[2/4] L:\Software\MICROS~2\2022\COMMUN~1\VC\Tools\MSVC\1444~1.352\bin\Hostx64\x64\cl.exe /nologo /TP -DSOMESYMBOL /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od /RTC1 -MDd /showIncludes /FoCMakeFiles\A.dir\src\mypkg.cpp.obj /FdCMakeFiles\A.dir\A.pdb /FS -c L:\oblivion\conan-test\src\mypkg.cpp

```

When you do `target_link_library` you don’t copy properties of all linked targets to another, you just reference the target as linked to another and it’s properties then inherited later during project build files generation.

---

<div class="post-metadata">

### Author: ![adaldev](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/9dc877/32.png) [@adaldev](https://discourse.cmake.org/u/adaldev)
#### Post date: [December 12, 2025, 5:21pm UTC](https://discourse.cmake.org/t/propagation-of-compile-definitions/15386/3 "2025-12-12T17:21:07Z")

</div>

Thanks Andrej,

There is no way to test for the symbol from `A` `CMakeLists.txt` at configuration time?

At worse, can I display a message at build time, based on the existence of the symbol?

Regards,  
A.

---

<div class="post-metadata">

### Author: ![Chardrazle](https://discourse.cmake.org/user_avatar/discourse.cmake.org/chardrazle/32/4362_2.png) [@Chardrazle](https://discourse.cmake.org/u/Chardrazle)
#### Post date: [December 22, 2025, 8:24am UTC](https://discourse.cmake.org/t/propagation-of-compile-definitions/15386/4 "2025-12-22T08:24:45Z")

</div>

There are various ways that checks can be performed at configuration time, but it depends on what you are ultimately trying to achieve.  
If your `L` target is visible (IOW added to the cmake processing) before the `A` target is processed then you can acquire that property from `L`. I.e. change the `get_target_property` to acquire from `L` instead.

As for at build time, generally this is the point of having compiler definitions, right?  
That is, they are typically used for `#ifdef` condition blocks, so presumably somewhere you are making use of the definition. So you can emit a diagnostic from your particular compiler (e.g. `#pragma message …`).  
If you need to make it more compiler-agnostic then a dependent custom target can be added that performs an echo (via cmake’s `-E echo`).

---

<div class="post-metadata">

### Author: ![Andrej730](https://discourse.cmake.org/user_avatar/discourse.cmake.org/andrej730/32/5752_2.png) [@Andrej730](https://discourse.cmake.org/u/Andrej730)
#### Post date: [December 22, 2025, 4:25pm UTC](https://discourse.cmake.org/t/propagation-of-compile-definitions/15386/5 "2025-12-22T16:25:19Z")

</div>

What do you mean by “test for the symbol”? You mean whether `A` library has definition for some symbol or you’re referring to `SOMESYMBOL` flag being passed to compilation of `A`?..

Either way, sounds like [https://xyproblem.info/](https://xyproblem.info/)

---

<div class="post-metadata">

### Author: ![adaldev](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/9dc877/32.png) [@adaldev](https://discourse.cmake.org/u/adaldev)
#### Post date: [December 30, 2025, 1:43pm UTC](https://discourse.cmake.org/t/propagation-of-compile-definitions/15386/6 "2025-12-30T13:43:15Z")

</div>

Hi,

One use case is for `L` to test if some OpenCV functionality is available, which I do with a `try_run` on a minimal test program. If it succeeds, I define a symbol to pass to the code (through `target_compile_definitions`).

My goal is to let the client `A` also know if the functionality is available without running the `try_run` again (the test program being not necessarily available to the client) and emit a log at configuration time.

So far, the symbol is correctly defines also inside `A` but it allows to emit the message only at run-time or, possibly, compile-time, through a non-standard pragma.

I hope my intent is clearer. Regards,  
A.

---

<div class="post-metadata">

### Author: ![Andrej730](https://discourse.cmake.org/user_avatar/discourse.cmake.org/andrej730/32/5752_2.png) [@Andrej730](https://discourse.cmake.org/u/Andrej730)
#### Post date: [December 31, 2025, 6:41am UTC](https://discourse.cmake.org/t/propagation-of-compile-definitions/15386/7 "2025-12-31T06:41:59Z")

</div>

It seems you need [`try_compile`](https://cmake.org/cmake/help/latest/command/try_compile.html).

---

<div class="post-metadata">

### Author: ![Chardrazle](https://discourse.cmake.org/user_avatar/discourse.cmake.org/chardrazle/32/4362_2.png) [@Chardrazle](https://discourse.cmake.org/u/Chardrazle)
#### Post date: [January 4, 2026, 10:14am UTC](https://discourse.cmake.org/t/propagation-of-compile-definitions/15386/8 "2026-01-04T10:14:59Z")

</div>

The approach might be driven by how tightly coupled your lib and client are.

If your client is always being built within the same cmake configuration (hierarchy) as your library then using a property, as described above, would be one approach. Although you could insulate the components more by using your own custom property, rather than a built-in cmake one.  
E.g. in the lib’s cmake configuration: `set_target_properties(mylib PROPERTIES MY_LIB_HAS_FEATURE_X ON)`  
and in the client’s cmake configuration: `get_target_property(hasFeatureX mylib MY_LIB_HAS_FEATURE_X)`  
then test `hasFeatureX`.

If your client is being built independently from the lib, i.e. in another cmake hierarchy, then as you’ve said the decision that the feature is available has been determined by the lib (via `try_run`) at _configuration_ time, that suggests the client is being built for the same platform with the same capabilities - so it must honour the lib. In that case, the lib is like a prebuilt distribution, so it can provide something in that distribution that advertises its capabilities.  
For example, the lib’s configuration step could generate a header file (e.g. via cmake’s `file` or `configure_file`). The client can use that file to do what it needs to do.

---

<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: [February 9, 2026, 5:14am UTC](https://discourse.cmake.org/t/propagation-of-compile-definitions/15386/9 "2026-02-09T05:14:07Z")

</div>

> [@adaldev](#):
>
> There is no way to test for the symbol from `A` `CMakeLists.txt` at configuration time?

No. The definition could be `$<$<BOOL:$<TARGET_PROPERTY:foo>>:SYMBOL>` where it is only defined if the consuming target has its `foo` property set to a truthy value.

As for the end goal of detecting feature support in a library, the `Find` module or `Config.cmake` file should, ideally, be able to specify this. Detection usually tries to grep headers before doing `try_compile`. `try_run` is awful for such things (cross-compilation sadness abounds).

---

<div class="post-metadata">

### Author: ![adaldev](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/9dc877/32.png) [@adaldev](https://discourse.cmake.org/u/adaldev)
#### Post date: [February 9, 2026, 9:45am UTC](https://discourse.cmake.org/t/propagation-of-compile-definitions/15386/10 "2026-02-09T09:45:32Z")

</div>

Hi, just for the context. The feature I’m trying to detect is `cv::xfeatures2d::SURF`. If I remember correctly, the way OpenCV is designed, this can be compiled but may issue an error (possibly an exception “not implemented”) only at runtime. Thus the need for `try_run`.  
NB I didn’t check but maybe it is not the case anymore in more recent versions…

---

<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: [February 9, 2026, 2:47pm UTC](https://discourse.cmake.org/t/propagation-of-compile-definitions/15386/11 "2026-02-09T14:47:39Z")

</div>

IIRC, that feature was patent-encumbered. I think you want to only detect if it compiles at configure time. If it compiles, you still need to handle runtime failure as your build-time OpenCV might not match your runtime OpenCV.
