# configure-step dependencies

**URL:** https://discourse.cmake.org/t/configure-step-dependencies/7020
**Category:** Usage
**Created:** [December 6, 2022, 5:57pm UTC](https://discourse.cmake.org/t/configure-step-dependencies/7020 "2022-12-06T17:57:15Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Barry\_Revzin](https://discourse.cmake.org/user_avatar/discourse.cmake.org/barry_revzin/32/1283_2.png) [@Barry\_Revzin](https://discourse.cmake.org/u/Barry_Revzin)
#### Post date: [December 6, 2022, 5:57pm UTC](https://discourse.cmake.org/t/configure-step-dependencies/7020/1 "2022-12-06T17:57:15Z")

</div>

Here is a reduced example:

```auto
$ tree
.
├── cmake
│ └── foo.cmake
├── CMakeLists.txt
├── meow.py
└── woof.py

```

with the main CMakeLists.txt

```cmake
cmake_minimum_required(VERSION 3.21)
project(execute)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/target/bin)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)
include(foo)

add_program(meow meow.py)
add_program(woof woof.py)

```

and `cmake/foo.cmake` definined that `add_program` function:

```cmake
function(add_program target file)
    set(directory ${CMAKE_CURRENT_BINARY_DIR}/${target}/generated)
    file(MAKE_DIRECTORY ${directory})

    execute_process(
        COMMAND python ${file}
        OUTPUT_FILE ${directory}/out.cxx
        WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})

    set_property(
        DIRECTORY
        APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
        ${file})

    add_executable(${target} ${directory}/out.cxx)
endfunction()

```

where the two python files are just very silly, `meow.py` looks like this and `woof.py` just prints `woof` instead:

```python
print("""
#include <iostream>

int main() {
    std::cout << "meow\\n";
}
""")

```

This works:

```auto
$ mkdir build && cd build
$ cmake ..
$ make -j30
$ ./target/bin/meow
meow
$ ./target/bin/woof
woof

```

So far so good. Now, when I change `meow.py`, and I recompile, that _does_ recompile `meow`. But it _also_ recompiles `woof`:

```auto
$ touch ../meow.py
$ make -j30
-- Configuring done
-- Generating done
-- Build files have been written to: /home/brevzin/sandbox/execute_process/build
Consolidate compiler generated dependencies of target woof
Consolidate compiler generated dependencies of target meow
[25%] Building CXX object CMakeFiles/woof.dir/woof/generated/out.cxx.o
[50%] Building CXX object CMakeFiles/meow.dir/meow/generated/out.cxx.o
[75%] Linking CXX executable target/bin/woof
[100%] Linking CXX executable target/bin/meow
[100%] Built target woof
[100%] Built target meow

```

How do I make this _only_ recompile `meow`?

---

<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: [December 6, 2022, 6:07pm UTC](https://discourse.cmake.org/t/configure-step-dependencies/7020/2 "2022-12-06T18:07:44Z")

</div>

> [@Barry\_Revzin](#):
>
> ```auto
> execute_process(
> COMMAND python ${file}
> OUTPUT_FILE ${directory}/out.cxx
> WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
> 
> ```

This unconditionally overwrites the file. You want to instead do one of:

## Generate during the build

My preferred solution. Use `add_custom_command` to generate the file during the build. This command would `DEPENDS` on the Python script.

## Copy-if-different

Instead of writing directly to the source file during the configure, write to a “temp” place, then `file(COPY_IF_DIFFERENT)` to the actual source location.

---

<div class="post-metadata">

### Author: ![Barry\_Revzin](https://discourse.cmake.org/user_avatar/discourse.cmake.org/barry_revzin/32/1283_2.png) [@Barry\_Revzin](https://discourse.cmake.org/u/Barry_Revzin)
#### Post date: [December 6, 2022, 7:27pm UTC](https://discourse.cmake.org/t/configure-step-dependencies/7020/3 "2022-12-06T19:27:30Z")

</div>

Yeah changing:

```cmake
execute_process(... OUTPUT_FILE out ...)

```

to

```cmake
execute_process(... OUTPUT_FILE out-tmp ...)
file(COPY_FILE out-tmp out ONLY_IF_DIFFERENT)

```

does the trick.

This does still run _all_ the `execute_process` commands though. Is there a way to only run the necessary one(s)?

(Note that I have over-reduced this example - the `add_custom_command` approach is not viable because in reality I’m generating a `CMakeLists.txt` that needs to be included as part of the build, which CMake does not allow me to do during the build phase).

---

<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: [December 6, 2022, 7:58pm UTC](https://discourse.cmake.org/t/configure-step-dependencies/7020/4 "2022-12-06T19:58:20Z")

</div>

> [@Barry\_Revzin](#):
>
> Is there a way to only run the necessary one(s)?

If you have some way of knowing that the output is consistent with the input, sure. `if (path1 IS_NEWER_THAN path2)` exists if that helps.

---

<div class="post-metadata">

### Author: ![Barry\_Revzin](https://discourse.cmake.org/user_avatar/discourse.cmake.org/barry_revzin/32/1283_2.png) [@Barry\_Revzin](https://discourse.cmake.org/u/Barry_Revzin)
#### Post date: [December 6, 2022, 9:00pm UTC](https://discourse.cmake.org/t/configure-step-dependencies/7020/5 "2022-12-06T21:00:16Z")

</div>

Okay yep, between the two that’ll do it! 👍

So I have a combination of:

```cmake
if(${command_file} IS_NEWER_THAN ${output_file})
    execute_process(... OUTPUT_FILE ${output_file}.tmp ...)
    file(COPY_FILE ${output_file}.tmp ${output_file} ONLY_IF_DIFFERENT)
endif()

```

That seems to both (a) only execute the process if necessary and also then (b) only rebuild if necessary (so that `touch meow.py` does call `meow.py` again but won’t rebuild `meow` since its `out.cxx` hasn’t changed).

Seems like at least the only-re-execute-if-changed part should be a parameter on `execute_process`, something like:

```cmake
execute_process(... DEPENDS ${command_file})

```

In the same way that this works for `add_custom_command`

---

<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: [December 6, 2022, 9:38pm UTC](https://discourse.cmake.org/t/configure-step-dependencies/7020/6 "2022-12-06T21:38:40Z")

</div>

`execute_process` is used to just run a command to query something and stuff it into a cache variable. It usually isn’t involved in the build graph at all. Other things to consider that aren’t handled:

- the output file doesn’t exist yet
- the output is a `-o out` flag, not a `stdout` capture

It seems to me that `add_custom_command(IMMEDIATE)` is probably a better foundation to build something like that from (but still seems very niche to me). I don’t know how many are generating configure code in such a complicated way.

---

<div class="post-metadata">

### Author: ![Barry\_Revzin](https://discourse.cmake.org/user_avatar/discourse.cmake.org/barry_revzin/32/1283_2.png) [@Barry\_Revzin](https://discourse.cmake.org/u/Barry_Revzin)
#### Post date: [December 7, 2022, 12:27am UTC](https://discourse.cmake.org/t/configure-step-dependencies/7020/7 "2022-12-07T00:27:11Z")

</div>

> [@ben.boeckel](#):
>
> It seems to me that `add_custom_command(IMMEDIATE)` is probably a better foundation to build something like that from (but still seems very niche to me). I don’t know how many are generating configure code in such a complicated way.

Sure, I totally agree that `add_custom_command` would be a better solution for this (though probably like `CONFIGURATION_TIME` rather than `IMMEDIATE`).

The real problem I have is that I need to generate part of my build outside of cmake. Because cmake can only include other cmake files during configuration, this generation needs to happen during configuration. If cmake let me do that during build, then I would happily use `add_custom_command` but that’s not an option, so I’m left trying to… effectively implement a configuration-time `add_custom_command`.

I’m not sure how niche this is. Ultimately I’m asking cmake to handle dependencies properly during configuration time as well as during build time. In trying to figure out how to do this, I’ve run into quite a few other half-solutions to this problem that each have their own limitations (e.g. running `ExternalProject_Add` to emit that other cmake build then building that one appears to be a common solution, but then you can’t bring in cmake library dependences from the rest of the project).

---

<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: [December 7, 2022, 12:48am UTC](https://discourse.cmake.org/t/configure-step-dependencies/7020/8 "2022-12-07T00:48:14Z")

</div>

Well, CMake isn’t a build tool and really just knows how to construct DAGs, not execute them. Getting it Just Right™ will be tedious, but I suspect that this might be one time where committing generated files is better. The pattern there is usually to commit some version of the generated file(s), have `add_custom_command`s that generate new files into the build tree, another `add_custom_command` that _detects_ whether the files are different, and an `add_custom_target` (to be run manually) that copies them back to the source tree.
