CMake笔记:add_custom_command不执行

0x00. 前言

在网上看别人做一些手工教程视频,经常能看到这样的评论:

脑子:我感觉我会了。
手:你行你来。

之前一直通过编译脚本去寻找代码入口,感觉我已经懂得CMake的语法了,直到今天寄己要写一个脚本去编译一个工程才发现,事情并不简单:脚本并没有按照我期望的去执行。

此工程需要用到Protocol Buffer,因此当代码构建的时候需要使用使用Protocol Buffer编译器去编译.proto文件获得对应的生成文件。理论上,想要达到这个目的,我们只需要在CMakeLists.txt中使用add_custom_command命令就可以可以生成对应的构建规则。但出人意料的是,这条命令并没有被执行,也就是说,并没有编译.proto文件的规则生成,因此当最终使用Make去构建工程的时候,没能通过.proto文件得到对应的源代码。

0x01. 踩雷

整个命令的使用如下面的代码所示,作用就是将位${REPO_ROOT}/protobuf/onnx-operators-ml.proto以及${REPO_ROOT}/protobuf/onnx-ml.proto这两个文件编译成C++头文件以及源文件,并存放到{REPO_ROOT}/src目录下,其中${REPO_ROOT}是项目的根目录,例如在我的例子中为/home/sunny/workspace/model-tool/

set(PROTOBUF_PROTOC_EXECUTABLE ${REPO_ROOT}/build/third_party/protobuf/cmake/protoc)

list(APPEND PROTO_FILES 
     "${REPO_ROOT}/protobuf/onnx-operators-ml.proto"
     "${REPO_ROOT}/protobuf/onnx-ml.proto")

set(output_dir ${REPO_ROOT}/include)
set(protoc_include ${REPO_ROOT}/protobuf)

foreach(fil ${PROTO_FILES})
    get_filename_component(abs_fil ${fil} ABSOLUTE)
    get_filename_component(fil_we ${fil} NAME_WE)

    list(APPEND ${srcs_var} "${output_dir}/${fil_we}.pb.cc")
    list(APPEND ${hdrs_var} "${output_dir}/${fil_we}.pb.h")

    add_custom_command(
        OUTPUT "${output_dir}/${fil_we}.pb.cc"
                "${output_dir}/${fil_we}.pb.h"
        COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --cpp_out    ${output_dir} -I${protoc_include} ${abs_fil}
        DEPENDS ${abs_file}
        COMMENT "Running C++ protocol buffer compiler on ${fil}" VERBATIM )
endforeach()

官方文档中该命令的签名有两个形式,在开源的项目中经常看到的是下面这个形式:

add_custom_command(OUTPUT output1 [output2 ...]
                   COMMAND command1 [ARGS] [args1...]
                   [COMMAND command2 [ARGS] 

你可能感兴趣的:(工具,C/C++,解决方案,cmake,c++)