We will collect functions that generate these files in src/autogenerate.cmake, include this module, and call these functions in src/CMakeLists.txt before defining the executable target:
# generate config.h, pathdef.c, and osdef.h
include(autogenerate.cmake)
generate_config_h()
generate_pathdef_c()
generate_osdef_h()
add_executable(vim
main.c
)
# ...
The included src/autogenerate.cmake contains other includes for functionality that we will require to probe header files, functions, and libraries, as well as the three functions:
include(CheckTypeSize)
include(CheckFunctionExists)
include(CheckIncludeFiles)
include(CheckLibraryExists)
include(CheckCSourceCompiles)
function(generate_config_h)
# ... to be written
endfunction()
function(generate_pathdef_c)
# ... to be written
endfunction()
function(generate_osdef_h)
# ... to be written
endfunction()
We choose to generate files with functions rather than in macros or "naked" CMake code. As we discussed in previous chapters, this sidesteps many pitfalls:
- It lets us avoid files being generated multiple times, in case we accidentally include the module multiple times. As noted in Recipe 5, Redefining functions and macros, in Chapter 7, Structuring Projects, we could employ an include guard to protect against accidentally running code multiple times.
- It guarantees full control over the scope of variables defined within the functions. This avoids that these definitions spill out and pollute the main scope.