add_custom_command with CMake commands

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:

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!

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.

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

That worked! Here is a snippet if it helps:

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()