gpt4 book ai didi

c++ - 传递性 add_custom_command 依赖关系未结转

转载 作者:行者123 更新时间:2023-11-28 04:54:14 24 4
gpt4 key购买 nike

我有一些 protobuf 文件,它们位于我的 cmake 项目之外的目录中(它们位于 旁边 ${CMAKE_SOURCE_DIR} 的根目录中,我们的主要 CMakeLists .txt 文件是)。

root/
+--- src/
| +--- CMakeLists.txt # main CMakeLists
| +--- messages/
| +--- CMakeLists.txt # protocol generation CMakeLists
| +--- base/
| +--- header.pb.cc
| +--- header.pb.h
+--- protocols/
+--- base/
| +--- header.proto # protocol definitions
. .

我的目标是创建一个 custom_command,它将生成 .pb.cc.pb.h 文件并将它们链接到一个库中以供我的项目使用。

因此在上面的示例中,root/src/messages/base/header.pb.cc 是从 root/protocols/base/header.proto 创建的。

Protobuf 生成:

我创建了一个函数 (protoc),它循环遍历 protobuf .proto 源文件列表,并调用 add_custom_command在每个文件上调用 protobuf 编译器。

function(protoc SRCS_OUT HDRS_OUT)

set(options)
set(values CPP_OUT CWD)
set(lists PROTO)
cmake_parse_arguments(ARG "${options}" "${values}" "${lists}" "${ARGN}")

set(GENERATED_SRCS)
set(GENERATED_HDRS)

foreach(FILE ${ARG_PROTO})

# find the absolute path to the .proto file
get_filename_component(ABS_FILE ${FILE} ABSOLUTE)

# replace source-dir with dest-dir and generate the path where the
# .pb.cc and .pb.h files will be created
string(REPLACE ${ARG_CWD} ${ARG_CPP_OUT} PROTO_DEST ${ABS_FILE})

get_filename_component(FILE_WE ${PROTO_DEST} NAME_WE)
get_filename_component(DEST_DIR ${PROTO_DEST} DIRECTORY)

set(GENERATED_SRC "${DEST_DIR}/${FILE_WE}.pb.cc")
set(GENERATED_HDR "${DEST_DIR}/${FILE_WE}.pb.h")

# run the protoc compiler on the .proto file, specifying the generated
# .pb.cc and .pb.h files as OUTPUT, and the .proto file as the
# MAIN_DEPENDENCY
add_custom_command(
OUTPUT
${GENERATED_SRC}
${GENERATED_HDR}

COMMAND
protoc

ARGS
--cpp_out ${ARG_CPP_OUT} ${ABS_FILE}

WORKING_DIRECTORY
${ARG_CWD}

MAIN_DEPENDENCY
${ABS_FILE}

COMMENT
"Running C++ protocol buffer compiler on ${FILE}"

VERBATIM
)

set_source_files_properties(${GENERATED_SRC} ${GENERATED_HDR}
PROPERTIES GENERATED TRUE)

list(APPEND GENERATED_SRCS ${GENERATED_SRC})
list(APPEND GENERATED_HDRS ${GENERATED_HDR})

endforeach()

set(${SRCS_OUT} ${GENERATED_SRCS} PARENT_SCOPE)
set(${HDRS_OUT} ${GENERATED_HDRS} PARENT_SCOPE)

endfunction()

请注意,我已经指定了 .pb.cc.pb.h 文件与 .proto 文件之间的依赖关系:

  • OUTPUT:我指定生成的.pb.cc.pb.h 文件的完整路径
  • MAIN_DEPENDENCY:我指定了 .proto 文件的完整路径

然后我使用上面的 protoc 函数创建一个由生成的 .pb.cc 文件组成的库:

root/src/messages/CMakeLists.txt:

get_filename_component(PROTOCOLS_DIR "${CMAKE_SOURCE_DIR}/../protocols" ABSOLUTE)

protoc(
PROTO_SRCS
PROTO_HDRS

PROTO
${PROTOCOLS_DIR}/base/header.proto

CWD
${PROTOCOLS_DIR}

CPP_OUT
${CMAKE_CURRENT_SOURCE_DIR}
)

add_library(
msg_base
STATIC
${PROTO_SRCS} ${PROTO_HDRS}
)

因此,protoc 的命令将作为其 PROTO 参数

  • /home/steve/root/protocols/messages/base/header.proto

msg_base 将作为其来源

  • /home/steve/root/src/messages/base/header.pb.cc
  • /home/steve/root/src/messages/base/header.pb.h

我的期望是,现在任何链接msg_base 的目标都将传递 依赖于.proto 文件

target -> msg_base -> header.pb.cc -> header.proto

例如:

add_executable(foo ${FOO_SRCS})
target_link_libraries(foo msg_base) # transitive dependency on header.proto

问题:

有时 header.proto 会过时,但 foo 会链接到旧版本的 msg_base

msg_base 不会在 foo 链接之前用新的 header.pb.cc 文件重建(带有过时的 msg_base).

问题:

  • 我使用的文件路径是否与 CMakeLists.txt(.proto 文件和 .pb)在同一目录中。 cc 等文件)允许吗?

我问这个是因为 add_custom_command 的帮助确实引用了在同一目录中创建的目标,我想知道这是否违反了这一点?

  • 另请注意,我们正在使用并行构建

最佳答案

研究使我在 cmake wiki 上找到了一篇名为“How can I add a dependency to a source file which is generated in a subdirectory?”的帖子

事实证明,cmake 目前不知道如何将生成的文件作为依赖项链接到不同目录 中的目标。

这听起来很像是这个问题的根本原因。

有一个开放的bug report / feature request为此,但在撰写本文时它仍然是开放的。

“修复”是将包含生成的 protobuf 文件的每个库的创建移动到生成这些文件的子目录中。

即把msg_base的创建从root/src/messages/CMakeLists.txt移到root/src/messages/base/CMakeLists.txt

生成的树将如下所示:

root/
+--- src/
| +--- CMakeLists.txt # main CMakeLists
| +--- messages/
| +--- base/
| +--- CMakeLists.txt # protocol generation CMakeLists
| +--- header.pb.cc
| +--- header.pb.h
+--- protocols/
+--- base/
| +--- header.proto # protocol definitions
. .

关于c++ - 传递性 add_custom_command 依赖关系未结转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47536633/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com