Similar to the previous recipe, we need to configure a template file, but this time, we will emulate the configure_file() function with a Python script. We keep the CMakeLists.txt largely unchanged, but we replace configure_file(print_info.c.in print_info.c @ONLY) with a set of commands, which we will introduce step by step:
- First, we construct a variable, _config_script, which will hold a Python script that we will execute a moment later:
set(_config_script
"
from pathlib import Path
source_dir = Path('${CMAKE_CURRENT_SOURCE_DIR}')
binary_dir = Path('${CMAKE_CURRENT_BINARY_DIR}')
input_file = source_dir / 'print_info.c.in'
output_file = binary_dir / 'print_info.c'
import sys
sys.path.insert(0, str(source_dir))
from configurator import configure_file
vars_dict = {
'_user_name': '${_user_name}',
'_host_name': '${_host_name}',
'_fqdn': '${_fqdn}',
'_processor_name': '${_processor_name}',
'_processor_description': '${_processor_description}',
'_os_name': '${_os_name}',
'_os_release': '${_os_release}',
'_os_version': '${_os_version}',
'_os_platform': '${_os_platform}',
'_configuration_time': '${_configuration_time}',
'CMAKE_VERSION': '${CMAKE_VERSION}',
'CMAKE_GENERATOR': '${CMAKE_GENERATOR}',
'CMAKE_Fortran_COMPILER': '${CMAKE_Fortran_COMPILER}',
'CMAKE_C_COMPILER': '${CMAKE_C_COMPILER}',
}
configure_file(input_file, output_file, vars_dict)
")
- We then use find_package to ensure that the Python interpreter is available for CMake to use:
find_package(PythonInterp QUIET REQUIRED)
- If the Python interpreter was found, we can execute _config_script from within CMake, to generate the print_info.c file:
execute_process(
COMMAND
${PYTHON_EXECUTABLE} "-c" ${_config_script}
)
- After that, we define the executable target and dependencies, but this is unchanged from the previous recipe. Also, the obtained output is unchanged.