add_custom_command用法
环境:
Linux平台:CentOS Linux relase 7.2.1511、GCC_4.8.5-4、cmake version 2.8.11
开始:
一、add_custom_command
将自定义构建规则添加到生成的构建系统,有两种用法。
1.1)第一种用法:将自定义命令添加到目标,如库或可执行文件
add_custom_command(TARGET target PRE_BUILD | PRE_LINK | POST_BUILD COMMAND command1 [ARGS] [args1...] [COMMAND command2 [ARGS] [args2...] ...] [WORKING_DIRECTORY dir] [COMMENT comment] [VERBATIM])
当目标target构建时,会在你指定的阶段PRE_BUILD | PRE_LINK | POST_BUILD执行命令。
例如下面的命令,当目标my_project构建完成后,执行命令将my_project生成的文件拷贝到tmp目录
add_custom_command(TARGET my_project POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:my_project> ./tmp)
1.2)第二种用法:添加自定义命令以生成输出
add_custom_command(OUTPUT output1 [output2 ...] COMMAND command1 [ARGS] [args1...] [COMMAND command2 [ARGS] [args2...] ...] [MAIN_DEPENDENCY depend] [DEPENDS [depends...]] [IMPLICIT_DEPENDS <lang1> depend1 ...] [WORKING_DIRECTORY dir] [COMMENT comment] [VERBATIM] [APPEND])
当指定的output1被其他目标依赖时,可能会执行命令;我们假设依赖output1的目标为test,下面具体分析:
1)如果执行的命令并没有输出文件,则目标test生成时,改命令每次都会执行。
2)如果执行的命令输出文件,但是output1文件不存在,则目标test生成时,该命令会执行。
3)如果执行的命令输出文件,且output1文件存在,但是该命令的依赖(通过DEPENDS指定)被修改了,则目标test生成时,该命令会执行。
二、demo示例
2.1)静态库libtest_1.a
test_1.cpp
#include <stdio.h> __attribute__((visibility("default"))) void test_1() { printf("test_1\n"); }
2.2)动态库libtest_2.so
test_2.cpp
#include <stdio.h> __attribute__((visibility("default"))) void test_2() { printf("test_2\n"); }
2.3)可执行程序test_3
test_3.cpp
int main() { return 0; }
2.4)CMakeLists.txt
project(demo)
cmake_minimum_required(VERSION 2.6)
set(PRJ_VER "0.0.0")
set(ROOT ${PROJECT_SOURCE_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROOT}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ROOT}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${ROOT}/lib)
set(CMAKE_VERBOSE_MAKEFILE ON)
#####include_directories#####
include_directories(${ROOT})
#####link_directories#####
link_directories(${ROOT}/lib)
#CMAKE_CXX_FLAGS
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11")
message("CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS})
add_library(test_1 STATIC ${ROOT}/test_1.cpp)
set_target_properties(test_1 PROPERTIES COMPILE_FLAGS "-fPIC")
add_library(test_2 SHARED ${ROOT}/test_2.cpp)
target_link_libraries(test_2 LINK_PRIVATE test_1)
add_custom_command(TARGET test_1 POST_BUILD COMMENT "test_1 POST_BUILD")
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/test.cpp
COMMAND echo -e \"int test() { return 0\; }\" > ${CMAKE_BINARY_DIR}/test.cpp
DEPENDS test_1
COMMENT "build test.cpp")
add_executable(test_3 test_3.cpp ${CMAKE_BINARY_DIR}/test.cpp)
add_custom_target(test_4 ALL DEPENDS ${CMAKE_BINARY_DIR}/test.cpp)
2.4.1)add_custom_command第一种用法
运行make test_1
当目标test_1构建完成后,执行命令输出"test_1 POST_BUILD"
add_custom_command(TARGET test_1 POST_BUILD COMMENT "test_1 POST_BUILD")
2.4.2)add_custom_command第二种用法
添加一个自定义输出文件
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/test.cpp
COMMAND echo -e \"int test() { return 0\; }\" > ${CMAKE_BINARY_DIR}/test.cpp
DEPENDS test_1
COMMENT "build test.cpp")
添加依赖,有两种依赖方式
add_executable(test_3 test_3.cpp ${CMAKE_BINARY_DIR}/test.cpp)
add_custom_target(test_4 ALL DEPENDS ${CMAKE_BINARY_DIR}/test.cpp)
运行make test_3
或make test_4
如果“${CMAKE_BINARY_DIR}/test.cpp”文件不存在,执行命令生成文件test.cpp。
如果“${CMAKE_BINARY_DIR}/test.cpp”文件存在,但是依赖目标test_1变动,执行命令重新生成文件test.cpp。
参考资料
CMake 2.8.8 Documentation https://cmake.org/cmake/help/v2.8.8/cmake.html