一 概述
add_custom_command
是 CMake 中用于定义自定义构建规则的指令。这个命令允许你指定一个或多个依赖项,一个或多个输出文件,以及当依赖项改变时需要执行的命令。当依赖项比输出文件新,或者输出文件不存在时,指定的命令就会执行。
add_custom_command
的基本语法如下:
cmake复制代码
add_custom_command(OUTPUT output1 [output2 ...] | |
COMMAND command1 [ARGS] [args1...] | |
[COMMAND command2 [ARGS] [args2...] ...] | |
[MAIN_DEPENDENCY depend] | |
[DEPENDS [depends...]] | |
[IMPLICIT_DEPENDS <lang> depend1 ...] | |
[WORKING_DIRECTORY dir] | |
[COMMENT comment] | |
[VERBATIM] | |
[APPEND] | |
[AT_BUILD] | |
[BYPRODUCTS [products...]] | |
[CACHEABLE] | |
[USES_TERMINAL] | |
[COMMAND_EXPAND_LISTS]) |
OUTPUT
指定了命令执行后应该生成的文件。COMMAND
指定了要执行的命令及其参数。可以有多个COMMAND
,它们会按照指定的顺序执行。MAIN_DEPENDENCY
指定了主要依赖项,通常是源文件或主要输入文件。DEPENDS
列出了此命令依赖的其他文件。只有当这些文件更改时,命令才会重新执行。IMPLICIT_DEPENDS
用于自动检测源文件中的依赖关系,通常用于编译器自动生成的依赖。WORKING_DIRECTORY
设置命令执行时的工作目录。COMMENT
为构建过程中显示的注释或消息。VERBATIM
指示 CMake 不要修改命令行的任何字符。APPEND
将此命令追加到为相同输出文件指定的现有自定义命令之后。AT_BUILD
指示该命令将在构建时(而不是安装时)运行。BYPRODUCTS
指定命令生成的其他非主要输出文件。CACHEABLE
指示输出是否可以被缓存。USES_TERMINAL
指示命令是否需要在终端中运行(对于某些生成器)。COMMAND_EXPAND_LISTS
允许在COMMAND
中使用分号分隔的参数列表。
二 实例
假设你有一个简单的 C++ 项目,其中包含一个源文件 main.cpp
,并且你想在编译之前自动生成一个包含构建时间戳的头文件 build_timestamp.h
。你可以使用 add_custom_command
来实现这一点:
cmake复制代码
cmake_minimum_required(VERSION 3.10) | |
project(CustomCommandExample) | |
# 设置输出文件名和路径 | |
set(TIMESTAMP_HEADER "build_timestamp.h") | |
# 添加自定义命令来生成 build_timestamp.h | |
add_custom_command( | |
OUTPUT ${TIMESTAMP_HEADER} | |
COMMAND ${CMAKE_COMMAND} -D TIMESTAMP_FILE=${TIMESTAMP_HEADER} -P timestamp.cmake | |
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/timestamp.cmake | |
COMMENT "Generating build timestamp header" | |
VERBATIM | |
) | |
# 添加一个目标来构建 timestamp 头文件 | |
add_custom_target(generate_timestamp ALL DEPENDS ${TIMESTAMP_HEADER}) | |
# 将源文件添加到可执行文件中,并设置依赖关系以确保在构建可执行文件之前生成 timestamp 头文件 | |
add_executable(my_program main.cpp) | |
add_dependencies(my_program generate_timestamp) |
在这个例子中,add_custom_command
使用了一个 CMake 脚本 timestamp.cmake
来生成 build_timestamp.h
文件。timestamp.cmake
可能包含一些像这样的代码来生成时间戳:
cmake复制代码
# timestamp.cmake | |
file(WRITE ${TIMESTAMP_FILE} "#define BUILD_TIMESTAMP \"${CMAKE_CURRENT_TIME}\"\n") |
这个 add_custom_command
会在 timestamp.cmake
脚本更改时重新生成 build_timestamp.h
。通过 add_dependencies
,我们确保了在构建 my_program
之前先执行自定义命令。