# Evaluating effective target setting via generator expression

**URL:** <https://discourse.cmake.org/t/evaluating-effective-target-setting-via-generator-expression/2389>\
**Category:** Code\
**Created:** [December 17, 2020, 1:58pm UTC](https://discourse.cmake.org/t/evaluating-effective-target-setting-via-generator-expression/2389 "2020-12-17T13:58:11Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![hsattler](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/h/59ef9b/32.png) [@hsattler](https://discourse.cmake.org/u/hsattler)\
**Post date:** [December 17, 2020, 1:58pm UTC](https://discourse.cmake.org/t/evaluating-effective-target-setting-via-generator-expression/2389/1 "2020-12-17T13:58:11Z")

</div>

Hi,

I want to add a link flag when the target effectively used LTO optimization. So somwhere top-level I write:

`add_link_options ( $<$<BOOL:$<TARGET_PROPERTY:INTERPROCEDURAL_OPTIMIZATION>>:-flto=8> )`

This works, if I set this property directly on the target or by setting CMAKE\_INTERPROCEDURAL\_OPTIMIZATION globally.

However, the cases are more difficult as there are also properties with the `_<CONFIG>` suffix that override this property.

Q1:  
How do I check in a generator expression that a property is actually set?

Additionally, there are also directory properties with these names. However, the above generator expression does _NOT_ evaluate the directory expression. So if the property is set for the directory (or any parent directory) but not for the target directly and not via global variable, the generator expression evaluates to false ☹

Q2:  
How do I get the effective setting? Is that even possible with generator expressions?

---

<div class="post-metadata">

**Author:** ![ferdnyc](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ferdnyc/32/267_2.png) [@ferdnyc](https://discourse.cmake.org/u/ferdnyc)\
**Post date:** [December 24, 2020, 7:34am UTC](https://discourse.cmake.org/t/evaluating-effective-target-setting-via-generator-expression/2389/2 "2020-12-24T07:34:32Z")

</div>

Taking the last question first,

> [@hsattler](#):
>
> Q2:  
> How do I get the effective setting? Is that even possible with generator expressions?

Not _as such_, no. “Effective setting” isn’t even really a correct way of describing it, since as the `cmake-generator` documentation [says](https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#debugging):

> generator expressions are evaluated during generation of the buildsystem, and not during processing of `CMakeLists.txt` files

IOW,

```cmake
target_link_options(targetname PRIVATE
  $<$<BOOL:$<TARGET_PROPERTY:foo>>:bar>)

```

doesn’t evaluate the `foo` property of `targetname` and insert `bar` into the `LINK_OPTIONS` property if it evaluates to true. It literally inserts `$<$<BOOL:$<TARGET_PROPERTY:foo>>:bar>` into the `LINK_OPTIONS` property (a `;`-separated list). The generator expression isn’t evaluated until the build system is being generated, _after_ the processing of `CMakeLists.txt` is completed.

> [@hsattler](#):
>
> I want to add a link flag when the target effectively used LTO optimization. So somwhere top-level I write:
> 
> `add_link_options ( $<$<BOOL:$<TARGET_PROPERTY:INTERPROCEDURAL_OPTIMIZATION>>:-flto=8> )`
> 
> This works, if I set this property directly on the target or by setting CMAKE\_INTERPROCEDURAL\_OPTIMIZATION globally.
> 
> However, the cases are more difficult as there are also properties with the `_<CONFIG>` suffix that override this property.

That’s true, but all you really care about is the _current_ config. So, you could do this:

~~ 

```cmake
target_link_options(${target_name} PRIVATE
  $<$<TARGET_PROPERTY:INTERPROCEDURAL_OPTIMIZATION>:-flto=8> 
  $<$<TARGET_PROPERTY:INTERPROCEDURAL_OPTIMIZATION_$<CONFIG>>:-flto=8>
)

```

 ~~

**Correction** : You _should_ be able to do that (in fact there are even examples in the documentation written that way), but for some reason in my testing it doesn’t actually work. (I end up with “Expression did not evaluate to a known generator expression” errors.) To get around that, it has to be written in the form you had it:

```cmake
target_link_options(${target_name} PRIVATE
  $<$<BOOL:$<TARGET_PROPERTY:INTERPROCEDURAL_OPTIMIZATION>>:-flto=8> 
  $<$<BOOL:$<TARGET_PROPERTY:INTERPROCEDURAL_OPTIMIZATION_$<CONFIG>>>:-flto=8>
)

```

Not sure why that’s the case.

> [@hsattler](#):
>
> Q1:  
> How do I check in a generator expression that a property is actually set?
> 
> Additionally, there are also directory properties with these names. However, the above generator expression does _NOT_ evaluate the directory expression. So if the property is set for the directory (or any parent directory) but not for the target directly and not via global variable, the generator expression evaluates to false ☹

Right, generator expressions can only examine target properties. If a property is set at `DIRECTORY`, `SOURCE`, or any other scope, a genex can’t see it.

But I don’t think this is actually as much of a problem as it may seem. Don’t forget, _you_ are the one defining the build system config. IOW, a property doesn’t just magically “get set” at directory scope, out of thin air — _ **you set it** _ that way, if you choose to.

If you want to set the `INTERPROCEDURAL_OPTIMIZATION` property on a directory basis, then you should check it with `get_property(_some_var DIRECTORY ...)` and use `$<$<BOOL:${_some_var}>:-flto=8>` to set the flag on the target.

If you choose to use `set_property(TARGET targetname PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)` instead, then you can use a `$<TARGET_PROPERTY>` generator expression.

But in most cases that’ll be totally up to you either way. Unless you’re writing a library of CMake code and have no control over the larger configuration. Then, for maximum flexibility, you may have to do “all of the above”.
