We are using CMake for a larger Fortran-based project in which we are also employing the Fypp preprocessor.
To implement this I added a function ADD_FYPP_SOURCES
which takes the files, defines a custom command and returns the output files which are then added to the library:
function (ADD_FYPP_SOURCES OUTVAR)
set(outfiles)
foreach (f ${ARGN})
# first we might need to make the input file absolute
get_filename_component(f "${f}" ABSOLUTE)
get_filename_component(ext "${f}" EXT)
# get the relative path of the file to the current source dir
file(RELATIVE_PATH rf "${CMAKE_CURRENT_SOURCE_DIR}" "${f}")
# set the output filename of fypped sources
set(of "${CMAKE_CURRENT_BINARY_DIR}/${rf}")
# create the output directory if it doesn't exist
get_filename_component(d "${of}" PATH)
if (NOT IS_DIRECTORY "${d}")
file(MAKE_DIRECTORY "${d}")
endif ()
if ("${f}" MATCHES ".F$")
# append the output file to the list of outputs
list(APPEND outfiles "${of}")
# now add the custom command to generate the output file
add_custom_command(
OUTPUT "${of}"
COMMAND ${Python_EXECUTABLE} ${FYPP_EXECUTABLE} ARGS ${fypp_flags}
"${f}" "${of}"
MAIN_DEPENDENCY "${f}"
VERBATIM)
elseif ("${f}" MATCHES ".h$")
# append the output file to the list of outputs
list(APPEND outfiles "${of}")
# now add the custom command to generate the output file
add_custom_command(
OUTPUT "${of}"
COMMAND ${Python_EXECUTABLE} ${FYPP_EXECUTABLE} ARGS "-F" "${f}" "${of}"
DEPENDS "${f}")
else ()
configure_file("${f}" "${of}" COPYONLY)
endif ()
endforeach ()
# build a custom target to fypp seperately (required for example by the doc
# target)
add_custom_target("fypp_${OUTVAR}" DEPENDS ${outfiles})
add_dependencies(fypp "fypp_${OUTVAR}")
# set the output list in the calling scope
set(${OUTVAR}
${outfiles}
PARENT_SCOPE)
endfunction ()
Since we are running everything through the preprocessor, is there a way to simply register it as a pre-build step without having to use such a wrapper function?
Furthermore the preprocessor language allows for includes which are not tracked by CMake (e.g. when the included file is changed, there is no rebuild), how can we tell CMake (and then make & ninja) about such a dependency?