# add\_custom\_command() does not work in each cases but there is no error!

**URL:** https://discourse.cmake.org/t/add-custom-command-does-not-work-in-each-cases-but-there-is-no-error/4338
**Category:** Code
**Tags:** os:windows, gen:ninja
**Created:** [October 25, 2021, 1:03pm UTC](https://discourse.cmake.org/t/add-custom-command-does-not-work-in-each-cases-but-there-is-no-error/4338 "2021-10-25T13:03:41Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [October 25, 2021, 1:03pm UTC](https://discourse.cmake.org/t/add-custom-command-does-not-work-in-each-cases-but-there-is-no-error/4338/1 "2021-10-25T13:03:41Z")

</div>

I have a CMake Project with following code snipped

```cmake
find_program(DOT dot REQUIRED)

find_program(
  IDL_COMPILER
  NAMES idl2cpp idl2cpp.sh idl2cpp.cmd
  HINTS $ENV{OE_HOME}/host/$ENV{OE_HOST_PLATFORM}/bin REQUIRED
)

# create a long text
set(TEXT 0123456789ABCDEF)
foreach(I RANGE 7)
  list(APPEND TEXT ${TEXT})
endforeach()

add_custom_command(
  OUTPUT generate
  COMMAND ${CMAKE_COMMAND} --graphviz=${GENERATED_DIR}/${CMAKE_PROJECT_NAME}.dot ${CMAKE_CURRENT_BINARY_DIR}
  COMMAND ${DOT} -Tsvg ${GENERATED_DIR}/${CMAKE_PROJECT_NAME}.dot -o ${GENERATED_DIR}/${CMAKE_PROJECT_NAME}.svg
  COMMAND ${CMAKE_COMMAND} -E echo ${TEXT} > generate
  COMMAND ${IDL_COMPILER} -help || echo ignored
  COMMAND ${CMAKE_COMMAND} -E echo OK
  COMMENT "generates generate"
)

add_custom_target(gen DEPENDS generate)

```

If the command are longer than an unknown limit (about 8k) a batch file is generated from `CMake`.  
But the `IDL_COMPILER` program may be a **program** , a **bat** , or a **shell** wrapper depending on the build host.

following happens on windows:

```bash
$ ninja generate -v
[1/1] CMakeFiles\generate-24cacf5.bat 769e14510ca1803e
-- Configuring done
-- Generating done
Generate graphviz: C:/Users/klein_cl/Workspace/CmakeCustomTargetExamples/build/ppcIntegrity178BOrbExpressD/.generated/MyProj.dot
Reading GraphViz options file: C:/Users/klein_cl/Workspace/CmakeCustomTargetExamples/CMakeGraphVizOptions.cmake
-- Build files have been written to: C:/Users/klein_cl/Workspace/CmakeCustomTargetExamples/build/ppcIntegrity178BOrbExpressD
Usage is: idl2cpp [-help | options] input-file

  -a Generate typecodes & type Any support for user-defined IDL types [default=false]
  -bm Generate MSVC++ V6 and prior bug-compatible code (not for V7 and later) [default=false]
  -bo Generate g++ 2.7 bug-compatible code [default=false]
  -d<sym> Define pre-processor symbol <sym>
  -ea Generate servant to require only impls with _env arg [default=true]
  -ee Generate servant to allow impls both with and without _env arg [default=false]
  -ex Generate servant to require only impls without _env arg [default=false]
  -fi<n> Set formatting indent to <n> spaces [default=4]
  -fm<n> Set formatting margin to column <n> [default=80]
  -fc<sfx> Set client file suffix to <sfx> [default=]
  -fs<sfx> Set server file suffix to <sfx> [default=_s]
  -fh<ext> Set C++ header file extension to <ext> [default=h]
  -fx<ext> Set C++ source file extension to <ext> [default=cxx]
  -i<dir> Search <dir> for #included files
  -m Map IDL modules to C++ namespaces [default=false]
  -n Generate code for #included files [default=false]
  -pl Use POA policies on local invocations [default=false]
  -q Don't generate model _impl files [default=false]
  -r Generate client code only, implies -q [default=false]
  -s Syntax and semantic check only [default=false]
  -ts<size> Allocate temporaries larger than size on heap instead of stack [default=1000000]
  -u<sym> Undefine pre-processor symbol <sym>
  -od<dir> Specify the output directory
  -v Print version number and license info
  -help Print this message

ignored

```

### NO OK? This is an error in the generated batch file because call to cmd file is not used!

Q: Any idea how this can be solved a portable way?  
Q: What is the **MAX** command length, after that, a batch file is generated?  
Q: Is this a `windows` specifically problem or a general `ninja generator` problem?

---

<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: [October 26, 2021, 8:54pm UTC](https://discourse.cmake.org/t/add-custom-command-does-not-work-in-each-cases-but-there-is-no-error/4338/2 "2021-10-26T20:54:41Z")

</div>

> [@ClausKlein](#):
>
> Any idea how this can be solved a portable way?

Write a CMake script that does `execute_process` on its own (configured with the paths you need passed in as `-D` or via `configure_file`) and then call it with `cmake -P …`.

> [@ClausKlein](#):
>
> What is the **MAX** command length, after that, a batch file is generated?

Platform dependent.

> [@ClausKlein](#):
>
> Is this a `windows` specifically problem or a general `ninja generator` problem?

How each generator deals with over-long command lines is probably unique. `make` generators have a line per command while `ninja` will do `cmd1 && cmd2` (or other ways of concatenating them, I don’t remember off hand), so `make` won’t hit the limit so easily.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [October 26, 2021, 9:26pm UTC](https://discourse.cmake.org/t/add-custom-command-does-not-work-in-each-cases-but-there-is-no-error/4338/3 "2021-10-26T21:26:40Z")

</div>

I can use

> [@ClausKlein](#):
>
> `call ${IDL_COMPILER} -Ipath1 -I... -IpathN ...`

on **windows** , than it works. But this is **NOT** portable!

My problem was the changed behaviour as I needed to add more include path arguments.  
The next commend was not longer executed and I saw not why?

---

<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: [October 26, 2021, 10:26pm UTC](https://discourse.cmake.org/t/add-custom-command-does-not-work-in-each-cases-but-there-is-no-error/4338/4 "2021-10-26T22:26:18Z")

</div>

Why do you need `call`? What does the compiler do that is modifying the parent process environment? If it is a `bat` script itself, the command should itself be `cmd;path/to/idlc.bat`, no (just like a Python script would be `${Python_EXECUTABLE};path/to/idlc.py`)? Sure, non-Windows support shebang lines for such things, but Windows has mechanisms for that too AFAIK.

> [@ClausKlein](#):
>
> My problem was the changed behaviour as I needed to add more include path arguments.  
> The next commend was not longer executed and I saw not why?

What changed behavior? CMake? If so, what version worked and what version is not working anymore? If there are any versions in between, knowing which version started to break things would be useful in tracking down this change. Additionally, can you provide a small self-contained example that demonstrates the problem so that we can test it and fix it?

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [October 27, 2021, 4:59am UTC](https://discourse.cmake.org/t/add-custom-command-does-not-work-in-each-cases-but-there-is-no-error/4338/5 "2021-10-27T04:59:19Z")

</div>

> [@ben.boeckel](#):
>
> Why do you need `call`?

The ninja rule is something like this:

```batch
cmd /c path/to/cmake/generated.bat

```

But the batch file need to use:

`call idl2cpp.cmd && do some post processing`

> [@ben.boeckel](#):
>
> What changed behavior?

It is not changed with `CMake version`. It was changed by me!

My project in development and on **Windows** , you needs much more `path` entries and `include_directories` then on other build host OS environments. 🥴

> [@ben.boeckel](#):
>
> Additionally, can you provide a small self-contained example that demonstrates the problem so that we can test it and fix it?

sure, see

> <https://github.com/ClausKlein/CmakeCustomTargetExamples/blob/develop/CMakeLists.txt>

---

<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: [October 27, 2021, 2:40pm UTC](https://discourse.cmake.org/t/add-custom-command-does-not-work-in-each-cases-but-there-is-no-error/4338/6 "2021-10-27T14:40:05Z")

</div>

> [@ClausKlein](#):
>
> The ninja rule is something like this:
> 
> ```auto
> cmd /c path/to/cmake/generated.bat
> 
> ```
> 
> But the batch file need to use:
> 
> `call idl2cpp.cmd && do some post processing`

I would just write my own batch script and have CMake use `cmd /c` on that. CMake has no idea that your tool uses `cmd` and requires `call` (and there’s no way to tell it to do so because there’s no guarantee that `cmd` is even used by the build tool; `nmake` just calls `CreateProcess` AFAIK).

> [@ClausKlein](#):
>
> My project in development and on **Windows** , you needs much more `path` entries and `include_directories` then on other build host OS environments.

Ah, yep 🙂 . Welcome to cross platform development 🙂 .
