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_3make 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

  https://zhuanlan.zhihu.com/p/397394950?utm_id=0

posted on 2023-05-13 16:19  dchao  阅读(863)  评论(0编辑  收藏  举报

导航