# How to create a custom target that only runs a command for a subset of configurations?

**URL:** <https://discourse.cmake.org/t/how-to-create-a-custom-target-that-only-runs-a-command-for-a-subset-of-configurations/3093>\
**Category:** Code\
**Tags:** gen:vs\
**Created:** [April 7, 2021, 12:05pm UTC](https://discourse.cmake.org/t/how-to-create-a-custom-target-that-only-runs-a-command-for-a-subset-of-configurations/3093 "2021-04-07T12:05:19Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Knitschi](https://discourse.cmake.org/user_avatar/discourse.cmake.org/knitschi/32/205_2.png) [@Knitschi](https://discourse.cmake.org/u/Knitschi)\
**Post date:** [April 7, 2021, 12:05pm UTC](https://discourse.cmake.org/t/how-to-create-a-custom-target-that-only-runs-a-command-for-a-subset-of-configurations/3093/1 "2021-04-07T12:05:19Z")

</div>

CMake 3.20 enables using generator expressions in the `add_custom_command(OUTPUT)` argument.

I am now trying to create a custom command that only runs a command for a subset of the available `CMAKE_CONFIGURATION_TYPES`. After a lot of trial and error I came up with an example that works for a single configuration:

```

# Works with warning when compiling in non-Debug
add_custom_command(
	COMMAND $<$<CONFIG:Debug>:${CMAKE_COMMAND}> $<$<CONFIG:Debug>:-E> $<$<CONFIG:Debug>:touch> $<$<CONFIG:Debug>:${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp> 
	OUTPUT $<$<CONFIG:Debug>:${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp>
)

add_custom_target(
	testConfigCommands
	DEPENDS $<$<CONFIG:Debug>:${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp> 
)

```

I failed to create an example that works for multiple configurations. I tried something like:

```

add_custom_command(
	COMMAND $<$<IN_LIST:$<CONFIG>,Debug;Release>:${CMAKE_COMMAND}> $<$<IN_LIST:$<CONFIG>,Debug;Release>:-E> $<$<IN_LIST:$<CONFIG>,Debug;Release>:touch> $<$<IN_LIST:$<CONFIG>,Debug;Release>:${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp>
	OUTPUT $<$<IN_LIST:$<CONFIG>,Debug;Release>:${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp>
)

add_custom_target(
	testConfigCommands
	DEPENDS $<$<IN_LIST:$<CONFIG>,Debug;Release>:${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp>
)

```

but this will fail with the error:  
`
OUTPUT containing a “<” is not allowed.
`

I tried escaping the semicolon and other stuff but I keep hitting various errors that I have trouble deciphering. So in my desparation I came here and ask if anybody can post a similar example that creates the stamp-file only when selecting the Release or Debug configuration when using the Visual Studio generator. If that would work without a waring when building the target for a configruation that is not Release or Debug it would be perfect.

It would be even better if the target was only available for a subset of configurations.

---

<div class="post-metadata">

**Author:** ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)\
**Post date:** [April 7, 2021, 12:28pm UTC](https://discourse.cmake.org/t/how-to-create-a-custom-target-that-only-runs-a-command-for-a-subset-of-configurations/3093/2 "2021-04-07T12:28:23Z")

</div>

First, generator expressions must be specified between quotes to avoid misinterpretation.  
Second, genex `$<CONFIG:>` can take multiple configurations as argument.

So, a simplified command:

```cmake
add_custom_command(COMMAND "$<$<CONFIG:Debug,Release>:${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp>"
OUTPUT "$<$<CONFIG:Debug,Release>:${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp>")

```

---

<div class="post-metadata">

**Author:** ![Knitschi](https://discourse.cmake.org/user_avatar/discourse.cmake.org/knitschi/32/205_2.png) [@Knitschi](https://discourse.cmake.org/u/Knitschi)\
**Post date:** [April 7, 2021, 12:32pm UTC](https://discourse.cmake.org/t/how-to-create-a-custom-target-that-only-runs-a-command-for-a-subset-of-configurations/3093/3 "2021-04-07T12:32:05Z")

</div>

Wow that was quick 😃. Thank you very much! I think my major error was to use a semicolon instead of a comma in the configuration lists.

---

<div class="post-metadata">

**Author:** ![Knitschi](https://discourse.cmake.org/user_avatar/discourse.cmake.org/knitschi/32/205_2.png) [@Knitschi](https://discourse.cmake.org/u/Knitschi)\
**Post date:** [April 7, 2021, 12:54pm UTC](https://discourse.cmake.org/t/how-to-create-a-custom-target-that-only-runs-a-command-for-a-subset-of-configurations/3093/4 "2021-04-07T12:54:10Z")

</div>

First I used:

```

add_custom_command(
	COMMAND $<$<CONFIG:Debug,Release>:${CMAKE_COMMAND}> $<$<CONFIG:Debug,Release>:-E> $<$<CONFIG:Debug,Release>:touch> $<$<CONFIG:Debug,Release>:${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp> 
	OUTPUT $<$<CONFIG:Debug,Release>:${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp>
)

```

which worked. However if I use your example I get an syntax error when the command is run. I suspect that it has something to do with the separators in the path of the stamp file. I am not sure though.

---

<div class="post-metadata">

**Author:** ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)\
**Post date:** [April 7, 2021, 3:17pm UTC](https://discourse.cmake.org/t/how-to-create-a-custom-target-that-only-runs-a-command-for-a-subset-of-configurations/3093/5 "2021-04-07T15:17:04Z")

</div>

You are right.  
Unfortunately, `add_custom_command()` command has a subtle difference, from other commands, in how arguments are interpreted. So you have to specify each element of the `COMMAND` args with its own genex:

```cmake
add_custom_command(COMMAND "$<$<CONFIG:Debug,Release>:${CMAKE_COMMAND}>" "$<$<CONFIG:Debug,Release>:-E>" "$<$<CONFIG:Debug,Release>:touch>" "$<$<CONFIG:Debug,Release>:${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp>"
OUTPUT "$<$<CONFIG:Debug,Release>:${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp>")

```

---

<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:** [April 16, 2021, 1:31am UTC](https://discourse.cmake.org/t/how-to-create-a-custom-target-that-only-runs-a-command-for-a-subset-of-configurations/3093/6 "2021-04-16T01:31:51Z")

</div>

For illustration purposes, the `COMMAND_EXPAND_LISTS` can also be relevant, depending on how you are constructing things. Here’s a refactored example to help demonstrate its use:

```cmake
cmake_minimum_required(VERSION 3.20)
project(semicolons)

set(outFile ${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp)
set(cmd ${CMAKE_COMMAND} -E touch ${outFile})
set(cmdConfigs Debug Release)
set(configEnabled "$<IN_LIST:$<CONFIG>,${cmdConfigs}>")

add_custom_command(
    OUTPUT "$<${configEnabled}:${outFile}>"
    COMMAND "$<${configEnabled}:${cmd}>"
    COMMAND_EXPAND_LISTS
)

add_custom_target(
	testConfigCommands
    DEPENDS "$<${configEnabled}:${outFile}>"
)

```

Taking account of Marc’s observation that `$<CONFIG:...>` can accept multiple configurations, that can be simplified a bit down to this:

```cmake
cmake_minimum_required(VERSION 3.20)
project(semicolons)

set(outFile ${CMAKE_BINARY_DIR}/A_Stamp_$<CONFIG>.stamp)
set(cmd ${CMAKE_COMMAND} -E touch ${outFile})
set(configEnabled "$<CONFIG:Debug,Release>") # Only part changed from previous example

add_custom_command(
    OUTPUT "$<${configEnabled}:${outFile}>"
    COMMAND "$<${configEnabled}:${cmd}>"
    COMMAND_EXPAND_LISTS
)

add_custom_target(
	testConfigCommands
    DEPENDS "$<${configEnabled}:${outFile}>"
)

```
