# PRE-Ninja Bash-Command

**URL:** <https://discourse.cmake.org/t/pre-ninja-bash-command/1418>\
**Category:** Code\
**Tags:** os:linux, gen:ninja\
**Created:** [June 20, 2020, 6:05am UTC](https://discourse.cmake.org/t/pre-ninja-bash-command/1418 "2020-06-20T06:05:34Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![aphardt](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/65b543/32.png) [@aphardt](https://discourse.cmake.org/u/aphardt)\
**Post date:** [June 20, 2020, 6:05am UTC](https://discourse.cmake.org/t/pre-ninja-bash-command/1418/1 "2020-06-20T06:05:34Z")

</div>

Hi

I work on a big Cortex-M project with arm-none-eabi-gcc, cmake and ninja-build.

The current build process is a bash script which consists of 4 parts:

- Execute pre-cmake-build bash instruction (also here, some files are generated EVERY TIME like git\_version\_info.h etc)
- Execute cmake …
- Execute ninja
- Execute post-cmake-build bash instructions

Now what i want to achieve is moving part 1 and part 4 into a pre and post build bash script, and remove the other one, so i can make it work with CLion.

Im terribly failing to find a command for cmake that lets me execute a bash script:  
A.) every time a build, even if there is no change in coding  
B.) that actually PRE\_BUILD executes.

add\_custom\_command does not work, as PRE\_BUILD is equal to PRE\_LINK, therefore the build fails since header files are missing.

Can someone help me write this cmakelists file so the bash script will actually execute BEFORE cmake generates files and ninja executes the compilation?

---

<div class="post-metadata">

**Author:** ![joe198](https://discourse.cmake.org/user_avatar/discourse.cmake.org/joe198/32/1301_2.png) [@joe198](https://discourse.cmake.org/u/joe198)\
**Post date:** [June 20, 2020, 6:24am UTC](https://discourse.cmake.org/t/pre-ninja-bash-command/1418/2 "2020-06-20T06:24:24Z")

</div>

ok

---

<div class="post-metadata">

**Author:** ![aphardt](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/65b543/32.png) [@aphardt](https://discourse.cmake.org/u/aphardt)\
**Post date:** [June 20, 2020, 6:26am UTC](https://discourse.cmake.org/t/pre-ninja-bash-command/1418/3 "2020-06-20T06:26:50Z")

</div>

haha, “ok” ?? 😃

---

<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:** [June 20, 2020, 12:13pm UTC](https://discourse.cmake.org/t/pre-ninja-bash-command/1418/5 "2020-06-20T12:13:15Z")

</div>

You can make a command run “always” by listing an output that never gets created. Something like this:

```cmake
add_custom_command(
  OUTPUT
    "${CMAKE_CURRENT_BINARY_DIR}/version.h"
    "${CMAKE_CURRENT_BINARY_DIR}/version.h.noexist"
  COMMAND
    mkversion)
# "Attach" a single target to this command. Directly depending on
# version.h from multiple targets is not supported in Visual Studio.
add_custom_target(version.h
  DEPENDS
    "${CMAKE_CURRENT_BINARY_DIR}/version.h")

# For each direct consumer of the header.
add_library(foo foo.c)
add_dependencies(foo version.h)

```

---

<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:** [June 20, 2020, 5:39pm UTC](https://discourse.cmake.org/t/pre-ninja-bash-command/1418/6 "2020-06-20T17:39:10Z")

</div>

But then you can put the command in the version.h target and mark the output file as GENERATED and list the file as BYPRODUCT as well

---

<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:** [June 20, 2020, 10:43pm UTC](https://discourse.cmake.org/t/pre-ninja-bash-command/1418/7 "2020-06-20T22:43:20Z")

</div>

`BYPRODUCTS` only works with the Ninja generator.

---

<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:** [June 20, 2020, 11:08pm UTC](https://discourse.cmake.org/t/pre-ninja-bash-command/1418/8 "2020-06-20T23:08:11Z")

</div>

You trick the Ninja tool with the non-existent output. What’s the point compared to the custom target?

---

<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:** [June 21, 2020, 5:45pm UTC](https://discourse.cmake.org/t/pre-ninja-bash-command/1418/9 "2020-06-21T17:45:08Z")

</div>

You wanted it to run unconditionally. That makes that happen. Compared to a plain custom target? It’s probably similar, but it’s easier to make chains of commands with `add_custom_command`, so I just do that then “cap” it off with a user-facing custom target.

---

<div class="post-metadata">

**Author:** ![aphardt](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/65b543/32.png) [@aphardt](https://discourse.cmake.org/u/aphardt)\
**Post date:** [June 22, 2020, 11:02am UTC](https://discourse.cmake.org/t/pre-ninja-bash-command/1418/10 "2020-06-22T11:02:08Z")

</div>

Okay i got it working as follows:

CMakeLists.txt

```
cmake_minimum_required(VERSION 3.16)
project(test001)
set(CMAKE_CXX_STANDARD 20)
add_custom_command(
  OUTPUT
    "${PROJECT_SOURCE_DIR}/version.h"
    "${PROJECT_SOURCE_DIR}/version.h.noexist"
  COMMAND
    ${PROJECT_SOURCE_DIR}/version.sh)
add_custom_target(test001_prebuild
  DEPENDS
  "${PROJECT_SOURCE_DIR}/version.h")
add_executable(test001 main.cpp)
add_dependencies(test001 test001_prebuild)

```

main.cpp

```
#include <iostream>
#include "version.h"
int main() {
  #ifndef DUMMY_VERSION
    #warning no DUMMY_VERSION
    std::cout << "Hello, World! NOT DEFINED" << std::endl;
  #else
    #warning DUMMY_VERSION
    std::cout << "Hello, World! DEFINED" << std::endl;
  #endif
  return 0;
}

```

version.sh

```
#!/bin/env bash
echo ">>>>>>>>>>>>>>> VERSION.SH BEGIN"
echo "#pragma once" >> ../version.h
echo "#define DUMMY_VERSION" >> ../version.h
echo ">>>>>>>>>>>>>>> VERSION.SH END"

```

tree

```
.
├── cmake-build-debug
├── CMakeLists.txt
├── main.cpp
├── version.h
└── version.sh
```

---

<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:** [June 22, 2020, 12:51pm UTC](https://discourse.cmake.org/t/pre-ninja-bash-command/1418/11 "2020-06-22T12:51:20Z")

</div>

You should never generate files during build in the source directory!
