Chapter 5 Configure-time and Build-time Operations
There are three important periods during the whole process of building with CMake:
- configure time: processing the
CMakeLists.txt
- generation time: generating files for the native build tool
- build time: invoking the native build tool to create the targets (executables and libraries)
5.1 Using platform-independent file operations
When we need to execute some commands during the build, we can use
add_custom_target
to bundle those commands as a target and then useadd_dependencies
to make it a dependency of our application target:cmake1
2
3
4
5
6
7
8
9
10
11
12
13add_custom_target(unpack-eigen
ALL
COMMAND
${CMAKE_COMMAND} -E tar xzf ${CMAKE_CURRENT_SOURCE_DIR}/eigen-eigen-5a0156e40feb.tar.gz
COMMAND
${CMAKE_COMMAND} -E rename eigen-eigen-5a0156e40feb eigen-3.3.4
WORKING_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}
COMMENT
"Unpacking Eigen3 in ${CMAKE_CURRENT_BINARY_DIR}/eigen-3.3.4"
)
add_dependencies(linear-algebra unpack-eigen)Note the argument following
COMMAND
here:cmake1
${CMAKE_COMMAND} -E rename eigen-eigen-5a0156e40feb eigen-3.3.4
Actually
-E
indicates the command mode of CMake, which is followed by the platform-independent command applied in CMake.Use
cmake -E
to list all those platform-independent commands.
5.2 Running a custom command at configure time
- Note that when using
execute_process
, we can specify many commands to execute, and the output of the last command will be passed as the input of the next one, which means only the last output can be picked out. - Remember commands in
execute_process
are executed in configure time.
5.3 Running a custom command at build time: I. Using add_custom_command
If we use
add_custom_command
withOUTPUT
as the first argument, it will generate some files when any target in the sameCMakeLists.txt
or which uses any file generated by the custom command is built:cmake1
2
3
4
5
6
7
8
9
10
11
12
13
14
15add_custom_command(
OUTPUT
${wrap_BLAS_LAPACK_sources}
COMMAND
${CMAKE_COMMAND} -E tar xzf ${CMAKE_CURRENT_SOURCE_DIR}/wrap_BLAS_LAPACK.tar.gz
COMMAND
${CMAKE_COMMAND} -E touch ${wrap_BLAS_LAPACK_sources}
WORKING_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/wrap_BLAS_LAPACK.tar.gz
COMMENT
"Unpacking C++ wrappers for BLAS/LAPACK"
VERBATIM
)
5.4 Running a custom command at build time: I. Using add_custom_target
To circumvent the limitation that only targets in the same
CMakeLists.txt
with theadd_custom_command
could trigger it, we can combine bothadd_custom_command
andadd_custom_target
:cmake1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22add_custom_target(BLAS_LAPACK_wrappers
WORKING_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS
${MATH_SRCS}
COMMENT
"Intermediate BLAS_LAPACK_wrappers target"
VERBATIM
)
add_custom_command(
OUTPUT
${MATH_SRCS}
COMMAND
${CMAKE_COMMAND} -E tar xzf ${CMAKE_CURRENT_SOURCE_DIR}/wrap_BLAS_LAPACK.tar.gz
WORKING_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/wrap_BLAS_LAPACK.tar.gz
COMMENT
"Unpacking C++ wrappers for BLAS/LAPACK"
)so that the custom commands will always be executed.
5.5 Running custom commands for specific targets at build time
If we use
add_custom_command
withTARGET
as the first argument, it will register some, like, hooks to a target:cmake1
2
3
4
5
6
7
8
9
10
11
12add_custom_command(
TARGET
example
POST_BUILD
COMMAND
${PYTHON_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/static-size.py
$<TARGET_FILE:example>
COMMENT
"static size of executable:"
VERBATIM
)We can register the hook to two times:
PRE_LINK
(for Linux,PRE_BUILD
has the same effect withPRE_LINK
) andPOST_BUILD
, whose names are self-explanatory.