# add\_custom\_command with CMake commands

**URL:** https://discourse.cmake.org/t/add-custom-command-with-cmake-commands/12790
**Category:** Code
**Created:** [October 16, 2024, 7:27pm UTC](https://discourse.cmake.org/t/add-custom-command-with-cmake-commands/12790 "2024-10-16T19:27:34Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![ibaned](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ibaned/32/5024_2.png) [@ibaned](https://discourse.cmake.org/u/ibaned)
#### Post date: [October 16, 2024, 7:27pm UTC](https://discourse.cmake.org/t/add-custom-command-with-cmake-commands/12790/1 "2024-10-16T19:27:34Z")

</div>

Hello,

I’m trying to mimic the functionality of C23’s `#embed` by having CMake generate a source file containing a C++11 raw string:

```cmake
function(embed data_file symbol)
  file(READ ${data_file} the_content)
  configure_file(CONFIGURE
       OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${symbol}.cpp
       @ONLY
       CONTENT
"#include <@symbol@.h>

const char* @symbol@ = R\"cmake_embed(@the_content@)cmake_embed\";
")

```

My problem now is that CMake doesn’t know that `${symbol}.cpp` depends on `${data_file}`. I assume `add_custom_command` could solve this, but since the script that generates my file is itself CMake commands (`file(READ` etc), how do I pass these in as the `COMMANDS` argument to `add_custom_command`? Am I going about this the wrong way? I just want to copy the contents of the input file in that spot in the template, generate the output file, and have CMake know that it needs to be re-generated when the input file changes.

Thank you!

---

<div class="post-metadata">

### Author: ![Lecris](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lecris/32/3193_2.png) [@Lecris](https://discourse.cmake.org/u/Lecris)
#### Post date: [October 17, 2024, 1:14pm UTC](https://discourse.cmake.org/t/add-custom-command-with-cmake-commands/12790/2 "2024-10-17T13:14:50Z")

</div>

Could you write it within a single `run_me.cmake` file such that you run it as `cmake -Dsymbol=something -Ddata_file=some_file -P run_me.cmake`? Then you should have close to full access of the CMake commands in there. But you might still need to design the dependency outside of that.

---

<div class="post-metadata">

### Author: ![ibaned](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ibaned/32/5024_2.png) [@ibaned](https://discourse.cmake.org/u/ibaned)
#### Post date: [October 17, 2024, 6:24pm UTC](https://discourse.cmake.org/t/add-custom-command-with-cmake-commands/12790/3 "2024-10-17T18:24:00Z")

</div>

Thank you @Lecris ! I’ll try that and report back

---

<div class="post-metadata">

### Author: ![ibaned](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ibaned/32/5024_2.png) [@ibaned](https://discourse.cmake.org/u/ibaned)
#### Post date: [October 17, 2024, 7:58pm UTC](https://discourse.cmake.org/t/add-custom-command-with-cmake-commands/12790/4 "2024-10-17T19:58:12Z")

</div>

That worked! Here is a snippet if it helps:

```cmake
function(embed data_file symbol)
  # If data_file is relative, it is meant to be relative to
  # CMAKE_CURRENT_SOURCE_DIR.
  # This function makes it an absolute path based on CMAKE_CURRENT_SOURCE_DIR
  cmake_path(ABSOLUTE_PATH data_file)
  add_custom_command(
      # Make sure CMake knows this is how ${symbol}.h and ${symbol}.cpp are generated
      OUTPUT
      "${CMAKE_CURRENT_BINARY_DIR}/${symbol}.h"
      "${CMAKE_CURRENT_BINARY_DIR}/${symbol}.cpp"
      # Call embed_script.cmake to actually generate the files
      # Make sure CMake knows that ${symbol}.h and ${symbol}.cpp depend on ${data_file}
      # so that if someone modifies ${data_file} then a rebuild will re-generate the
      # embedded source files
      DEPENDS
      "${data_file}"
      COMMAND
      "${CMAKE_COMMAND}"
      -D "data_file=${data_file}"
      -D symbol=${symbol}
      -P "${embed_list_dir}/embed_script.cmake"
      # Run the above command in CMAKE_CURRENT_BINARY_DIR, so that is where the C++ files end up
      WORKING_DIRECTORY
      "${CMAKE_CURRENT_BINARY_DIR}")
endfunction()

```
