The execute_process command will spawn one or more child processes from within the currently executing CMake process, thus providing a powerful and convenient way of running arbitrary commands when configuring your project. It is possible to execute more than one command within one invocation of execute_process. Notice, however, that the output of each command will be piped into the next. The command accepts a number of arguments:
- WORKING_DIRECTORY lets you specify in which directory the commands should be executed.
- RESULT_VARIABLE will contain the result of running the processes. This is either an integer to signal successful execution or a string with the error condition incurred.
- OUTPUT_VARIABLE and ERROR_VARIABLE will contain the standard output and standard error of the executed commands. Keep in mind that since the outputs of commands are piped, only the standard output of the last command will be saved into OUTPUT_VARIABLE.
- INPUT_FILE, OUTPUT_FILE, and ERROR_FILE specify filenames for the standard input and standard output of the last command, and the standard error for all commands.
- By setting OUTPUT_QUIET and ERROR_QUIET, CMake will silently ignore the standard output and the standard error, respectively.
- Any trailing whitespace in the standard output and standard error for the running commands can be stripped by setting OUTPUT_STRIP_TRAILING_WHITESPACE and ERROR_STRIP_TRAILING_WHITESPACE, respectively.
With these explanations, we can return to our example:
set(_module_name "cffi")
execute_process(
COMMAND
${PYTHON_EXECUTABLE} "-c" "import ${_module_name}; print(${_module_name}.__version__)"
OUTPUT_VARIABLE _stdout
ERROR_VARIABLE _stderr
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE
)
if(_stderr MATCHES "ModuleNotFoundError")
message(STATUS "Module ${_module_name} not found")
else()
message(STATUS "Found module ${_module_name} v${_stdout}")
endif()
The command checks the output of python -c "import cffi; print(cffi.__version__)". If the module is not found, _stderr will contain ModuleNotFoundError, which we check for in the if-statement, and in this case we would print Module cffi not found. If the import is successful, the Python code will print the version of the module, which is piped into _stdout so that we can print the following:
message(STATUS "Found module ${_module_name} v${_stdout}")