# How are circular generator expressions evaluated?

**URL:** <https://discourse.cmake.org/t/how-are-circular-generator-expressions-evaluated/3933>\
**Category:** Code\
**Created:** [August 14, 2021, 6:25pm UTC](https://discourse.cmake.org/t/how-are-circular-generator-expressions-evaluated/3933 "2021-08-14T18:25:44Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![alex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/alex/32/125_2.png) [@alex](https://discourse.cmake.org/u/alex)\
**Post date:** [August 14, 2021, 6:25pm UTC](https://discourse.cmake.org/t/how-are-circular-generator-expressions-evaluated/3933/1 "2021-08-14T18:25:44Z")

</div>

Consider the following:

```auto
cmake_minimum_required(VERSION 3.21)
project(test)

add_executable(foo foo.cpp)
target_compile_definitions(foo
  PRIVATE "FOO$<TARGET_PROPERTY:bar,COMPILE_DEFINITIONS>") 

add_executable(bar bar.cpp)
target_compile_definitions(bar
  PRIVATE "BAR$<TARGET_PROPERTY:foo,COMPILE_DEFINITIONS>")

```

This puts `-DFOOBAR` on `foo.cpp`'s command line and `-DBARFOO` on `bar.cpp`'s. How does that happen? Why isn’t this an error?

---

<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:** [August 16, 2021, 3:30pm UTC](https://discourse.cmake.org/t/how-are-circular-generator-expressions-evaluated/3933/2 "2021-08-16T15:30:51Z")

</div>

Hmm. That is interesting. I would expect this to be an error as well. I see `BadSelfReference` tests, but it seems that cycles are not detected in general. This would likely need a policy to resolve.

Cc: @brad.king

---

<div class="post-metadata">

**Author:** ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)\
**Post date:** [August 18, 2021, 7:16pm UTC](https://discourse.cmake.org/t/how-are-circular-generator-expressions-evaluated/3933/3 "2021-08-18T19:16:33Z")

</div>

The implementation avoids repeatedly following the same target multiple times, which is needed even in non-cyclical DAGs. On repeat encounter, evaluation produces an empty string.

---

<div class="post-metadata">

**Author:** ![alex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/alex/32/125_2.png) [@alex](https://discourse.cmake.org/u/alex)\
**Post date:** [August 18, 2021, 9:01pm UTC](https://discourse.cmake.org/t/how-are-circular-generator-expressions-evaluated/3933/4 "2021-08-18T21:01:51Z")

</div>

> [@brad.king](#):
>
> The implementation avoids repeatedly following the same target multiple times

I’m not sure what “repeatedly following the same target multiple times” means. If I write instead:

```auto
add_executable(foo foo.cpp)
target_compile_definitions(foo
  PRIVATE "FOO$<TARGET_PROPERTY:bar,COMPILE_DEFINITIONS>") 
set_property(TARGET foo PROPERTY COMPILE_DEFINITIONS_2 "BAZ")

add_executable(bar bar.cpp)
target_compile_definitions(bar
  PRIVATE "BAR$<TARGET_PROPERTY:foo,COMPILE_DEFINITIONS_2>")

```

Then `foo` gets `-DFOOBARBAZ` and `bar` gets `-DBARBAZ`. It looks like we went `foo` → `bar` → `foo` just fine.

---

<div class="post-metadata">

**Author:** ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)\
**Post date:** [August 19, 2021, 3:14pm UTC](https://discourse.cmake.org/t/how-are-circular-generator-expressions-evaluated/3933/5 "2021-08-19T15:14:45Z")

</div>

I meant that the same property on the same target is not repeated.

---

<div class="post-metadata">

**Author:** ![alex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/alex/32/125_2.png) [@alex](https://discourse.cmake.org/u/alex)\
**Post date:** [August 19, 2021, 3:29pm UTC](https://discourse.cmake.org/t/how-are-circular-generator-expressions-evaluated/3933/6 "2021-08-19T15:29:11Z")

</div>

That makes more sense, thanks.

I don’t believe this is documented anywhere. I think it would be helpful to add some text on the genex evaluation strategy to the docs. For another instance, the fact that all sub-genex are always evaluated prevents using `$<IF:...>` to check if a string names a target before using it to access a target property (and therefore avoid a fatal error).
