I originally asked this question on CMake mailing list: How to configure target or command to preprocess C file?
I’m porting build configuration based on GNU Autotools to CMake and I have to deal with C preprocessing to generate a file.
The input for preprocessor is SQL file with C preprocessor directives used, like #include "another.sql", etc.
Currently, Makefile uses the following rule to generate plain SQL file as output:
myfile.sql: myfile.sql.in.c
cpp -I../common $< | grep -v '^#' > $@
So, the myfile.sql is meant to be one of products of the build process, similar to share libraries or executables.
What CMake tools should I use to achieve the same effect?
It’s unclear to me if I should use add_custom_command, add_custom_target or combine both.
Obviously, I’m looking for a portable solution that would work at least with GNU GCC and Visual Studio toolsets. I presume I will have to define platform-specific custom commands, one for cpp preprocessor, one for cl.exe /P.
Or, does CMake provide any kind of abstraction for C preprocessor?
I scanned the archives, but I only found preprocessing of fortran files or solutions based on make capabilities: make myfile.i
So, it’s not quite what I’m looking for.
UPDATE: Added answer based on solution received from Petr Kmoch on CMake mailing list.
To take advantage of CMake’
make myfile.ifeature, you can do this:Now running
make myfile.sql.in.c.iwill produce preprocessed source for you, using definedCMAKE_C_FLAGS. It might be possible to change output name and dir for preprocessed file.At any rate, you’d need to wrap these
makeinvocations intoadd_custom_target(ALL ...)to make CMake run them during build.Use
CMAKE_MAKE_PROGRAMvariable in targets definitions.If you want to abstract from build tool, you can call cmake itself to build a target for you. Use
${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target targetnamewhen defining custom target.Alternatively, you can just
add_custom_command()which runs specified compiler to preprocess files and put them at the appropriate place. But this seems to be less flexible, IMO.