在 CMAKE 中为库目标生成 protobuf 文件

问题描述 投票:0回答:1

在以下项目结构中:

root/
├─ CMakeLists.txt
├─ protocol/
│  ├─ msg.proto
│  ├─ CMakeLists.txt
├─ app/
│  ├─ main.cpp
│  ├─ CMakeLists.txt

我可以生成 protobuf 文件。但是,一旦将

app
目标添加到项目中,配置步骤就会失败,因为不再生成 protobuf 文件。

根CMakeLists.txt:

cmake_minimum_required(VERSION 3.18.4) 
project(
  root
  VERSION 0.1
  LANGUAGES CXX
)

add_subdirectory(protocol)
add_subdirectory(app) 

协议CMakeLists.txt:

add_library(protocol)
target_include_directories(protocol
  PUBLIC
  .
  ${CMAKE_CURRENT_BINARY_DIR}
  ${Protobuf_INCLUDE_DIRS}
)
find_package(Protobuf REQUIRED)
set(PROTO_SOURCES msg.proto)
protobuf_generate_cpp(LIB_SOURCES LIB_HEADERS ${PROTO_SOURCES} )
target_link_libraries(protocol ${Protobuf_LIBRARIES})
target_sources(protocol
  PUBLIC
  ${LIB_HEADERS}
  PRIVATE
  ${LIB_SOURCES}
)

应用程序CMakeLists.txt:

add_library(app)
target_link_libraries(app PUBLIC protocol)
target_include_directories(app PUBLIC .)
target_sources(app
  PRIVATE
  main.cpp
)

我理解的方式是,我必须以某种方式告诉 CMAKE 依赖关系,但据我所知

target_link_libraries
应该准确地说明这一点。

我可以采取的另一个步骤是告诉

app
目标,
protocol
库中的标头是在构建时生成的,因此可以在依赖目标编译之前生成它们。怎么办?

许多其他问题都提到了类似的问题,但我发现没有一个问题考虑到了库依赖关系。


更新:

${LIB_HEADERS}
PUBLIC
移动到
PRIVATE
后:

add_library(protocol)
target_include_directories(protocol
  PUBLIC
  .
  ${CMAKE_CURRENT_BINARY_DIR}
  ${Protobuf_INCLUDE_DIRS}
)
find_package(Protobuf REQUIRED)
set(PROTO_SOURCES msg.proto)
protobuf_generate_cpp(LIB_SOURCES LIB_HEADERS ${PROTO_SOURCES} )
target_link_libraries(protocol ${Protobuf_LIBRARIES})
target_sources(protocol
  PRIVATE
  ${LIB_HEADERS}
  ${LIB_SOURCES}
)

配置步骤成功,msg.pb.h文件生成到

protocol
中的
build
子文件夹中;但 make 失败并出现以下错误:

main.cpp:29:10: fatal error: protocol/msg.pb.h: No such file or directory
   29 | #include "protocol/msg.pb.h"
      |   

那么在此设置中如何从目标

protocol
提供标头?

c++ cmake protocol-buffers
1个回答
1
投票

基于@Tsyvarev 的帮助: 将

${LIB_HEADERS}
PUBLIC
移动到
PRIVATE
后,现在会生成 protobuf 文件。

使它们可以通过库进行包含

#include "protocol/msg.pb.h"

${CMAKE_BINARY_DIR}
需要改为
${CMAKE_CURRENT_BINARY_DIR}
中的
target_include_directories

在情况 I 中,代码直接包含 protobuf 标头:

#include "msg.pb.h"

${CMAKE_CURRENT_BINARY_DIR}
需要在那里。


因为:

  • ${CMAKE_CURRENT_BINARY_DIR}
    表示子模块二进制目录(
    protocol
    项目
  • ${CMAKE_CURRENT_BINARY_DIR}
    表示项目二进制目录(
    protocol
    project
© www.soinside.com 2019 - 2024. All rights reserved.