- CMake Cookbook
- Radovan Bast Roberto Di Remigio
- 412字
- 2025-04-04 16:17:18
How it works
There are three new CMake commands in this recipe: execute_process and add_custom_command, which are always available, and find_package_handle_standard_args, which requires include(FindPackageHandleStandardArgs).
The execute_process command will execute one or more commands as child processes to the currently issued CMake command. The return value for the last child process will be saved into the variable passed as an argument to RESULT_VARIABLE, while the contents of the standard output and standard error pipes will be saved into the variables passed as arguments to OUTPUT_VARIABLE and ERROR_VARIABLE. execute_process allows us to execute arbitrary commands and use their results to infer the configuration of our system. In our case, we first use it to make sure that NumPy is available and then to obtain the version of the module.
The find_package_handle_standard_args command provides the standard tool for handling common operations related to finding programs and libraries installed on a given system. The version-related options, REQUIRED and EXACT, are all correctly handled without further CMake code when referring to this command. The additional options QUIET and COMPONENTS, which we will meet shortly, are also handled under the hood by this CMake command. In this recipe, we have used the following:
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(NumPy
FOUND_VAR NumPy_FOUND
REQUIRED_VARS NumPy
VERSION_VAR _numpy_version
)
The command will set the variable to signal that the module was found (NumPy_FOUND) when all required variables are set to valid file paths (NumPy). It will also set the version to the passed version variable ( _numpy_version) and print out status messages for the user:
-- Found NumPy: /usr/lib/python3.6/site-packages/numpy (found version "1.14.3")
In the present recipe, we have not used these variables further. What we could have done is to stop the configuration if NumPy_FOUND was returned as FALSE.
Finally, we should comment on the section of the code that copies use_numpy.py to the build directory:
add_custom_command(
OUTPUT
${CMAKE_CURRENT_BINARY_DIR}/use_numpy.py
COMMAND
${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/use_numpy.py
${CMAKE_CURRENT_BINARY_DIR}/use_numpy.py
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/use_numpy.py
)
target_sources(pure-embedding
PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/use_numpy.py
)
We could have achieved the copying with a file(COPY ...) command. Here, we opted to use add_custom_command to make sure that the file gets copied every time it changes, not only the first time we run the configuration. We will return to add_custom_command in more detail in Chapter 5, Configure-time and Build-time Operations. Note also the target_sources command, which adds the dependency to ${CMAKE_CURRENT_BINARY_DIR}/use_numpy.py; this was done to make sure that building the pure-embedding target triggers the preceding custom command.