# Mapping lists in generator expressions

**URL:** https://discourse.cmake.org/t/mapping-lists-in-generator-expressions/12833
**Category:** Usage
**Created:** [October 24, 2024, 4:25pm UTC](https://discourse.cmake.org/t/mapping-lists-in-generator-expressions/12833 "2024-10-24T16:25:03Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![jhol](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jhol/32/5042_2.png) [@jhol](https://discourse.cmake.org/u/jhol)
#### Post date: [October 24, 2024, 4:25pm UTC](https://discourse.cmake.org/t/mapping-lists-in-generator-expressions/12833/1 "2024-10-24T16:25:03Z")

</div>

I would like to write a generator expression which takes a list of targets, and retrieves a target property for each one producing a list of values.

Is there a way to do this? I can’t see an obvious way.

I thought of one very tricky way to do this using `$<GENEX_EVAL:expr>`:

`$<GENEX_EVAL:$<LIST:TRANSFORM,${targets},REPLACE,(.+),$<DOLLAR>$<ANGLE-L>TARGET_PROPERTY:\\1$<COMMA>${prop}$<ANGLE-R>>>`

…except it doesn’t work because there are no `$<DOLLAR>` and `$<ANGLE-L>` expressions, so how can I escape the inner expression?

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [October 25, 2024, 4:49am UTC](https://discourse.cmake.org/t/mapping-lists-in-generator-expressions/12833/2 "2024-10-25T04:49:45Z")

</div>

Do things work if you replace `$<DOLLAR>` with `$<1:$>`, or `$<ANGLE-L>` with `$<1:<>`? I think the latter might be a bit problematic, but the former might work.

---

<div class="post-metadata">

### Author: ![jhol](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jhol/32/5042_2.png) [@jhol](https://discourse.cmake.org/u/jhol)
#### Post date: [October 25, 2024, 6:50pm UTC](https://discourse.cmake.org/t/mapping-lists-in-generator-expressions/12833/3 "2024-10-25T18:50:58Z")

</div>

Ok, that works! Thank you. It even works recursively!:

```auto
set(targets picolibc::picolibc ZLIB::ZLIB)

function(escape_generator_expression var)
    string(REPLACE ">" " __ANGLE_R__" ${var} "${${var}}")
    string(REPLACE "$" "$<1:$>" ${var} "${${var}}")
    string(REPLACE "," "$<COMMA>" ${var} "${${var}}")
    string(REPLACE " __ANGLE_R__" "$<ANGLE-R>" ${var} "${${var}}")
    return(PROPAGATE ${var})
endfunction()

set(prop "INTERFACE_INCLUDE_DIRECTORIES")
set(get_prop "$<TARGET_PROPERTY:\\1,${prop}>")
escape_generator_expression(get_prop)
escape_generator_expression(get_prop)

set(expr "$<GENEX_EVAL:$<GENEX_EVAL:$<LIST:TRANSFORM,${targets},REPLACE,(.+),${get_prop}>>>")

```
