Establish dependency on header files generated by configure_file

My script generates a configure .h file from a template file by calling command configure_file:

configure_file(config.h.in   efc_fw_config.h)

But my source files do not directly #include “efc_fw_config.h”. Instead, we used compiler option -include to include the generated file efc_fw_config.h. The ‘-include’ option includes the source code of the specified file at the beginning of the compilation as if it were included at the first line of the compilation unit. The problem is, it seems that CMake cannot figure out all of my source files depend on this generated file. When I make a change in the template config.h.in, then run “cmake --build .”, CMake is smart enough to regenerate efc_fw_config.h, but it does not recompile my source files at all.

Is there any elegant way to tell CMake that the generated file efc_fw_config.h is a dependency of all source files?

Have a look at source property OBJECT_DEPENDS.

Do I have to set OBJECT_DEPENDS property for each source files?

@marc.chevrier, I tend to think this is a CMake bug. Given -include option, “armclang -M” can generate a correct dependency list.
For example, here is my simple main.c:

#include "mylib.h"

int add(int a, int b)
{
    return a+b;
}

int main()
{
    return add(NUM_OF_A, NUM_OF_B);
}

With this command:

armclang --target=arm-arm-none-eabi -march=armv8-a -include config.h -M main.c >deps.d

The content of deps.d:
main.o: main.c config.h mylib.h

Does CMake take into compiler options when generating dependency list?

OBJECT_DEPENDS is a source property, so… Yes.

Dependencies are computed differently depending on CMake version as well as generator.

What are your CMake version and generator?

I’m using CMake 3.20.0. And the generator is Unix Makefile.

In this environment, CMake is able to use the compiler to generate dependencies.

But I am not sure if this feature is activated for this specific compiler. Can you check, in your top-level CMakeLists.txt, what are the values of the following variables:

  • CMAKE_DEPFILE_FLAGS_C
  • CMAKE_C_DEPENDS_USE_COMPILER

CMAKE_DEPFILE_FLAGS_C is -MD -MT <DEP_TARGET> -MF <DEP_FILE>
CMAKE_C_DEPENDS_USE_COMPILER is not defined.

So, as I suspected, compiler generated dependencies are not activated for this compiler.

Can you add the following code in macro __compiler_armclang (file Modules/Compiler/ARMCLang.cmake). For example, at the end of the macro:

if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
    AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
    AND CMAKE_DEPFILE_FLAGS_${lang})
  # dependencies are computed by the compiler itself
  set(CMAKE_${lang}_DEPFILE_FORMAT gcc)
  set(CMAKE_${lang}_DEPENDS_USE_COMPILER TRUE)
endif()

And relaunch a generation from scratch. If all is OK, during compilation, flags defined in CMAKE_DEPFILE_FLAGS_C variable should be part of the compilation. And, of course, your dependency should be taken into account.

@marc.chevrier , with your suggested code change, the “-include” option is taken into account when the dependency list is generated. The behavior is as expected. Would you plan to include this fix in next release?

An interesting observation: if I simply “touch config.h.in” followed by “cmake --build”, the build system is reconfigured, but no recompilation. Recompilation happens only after I make a real content change in config.h.in. Does CMake watch the content change in addition to the file timestamp?

Thank you, Marc.

configure_file regenerate the if, and only if, contents has changed.

I will evaluate the possibility to integrate this evolution in next release: see MR.