0

我正在使用Google protobuf-c-rpc编写概念验证项目。

我想使用 CMake 来构建项目。我正在使用 CMake 版本 3.19

这是我的目录结构:

├── build
│   ├── CMakeCache.txt
│   └── CMakeFiles
├── CMakeLists.txt
├── interfaces
|------ example.proto
└── src
    ├── client
    ├───── foo_client.py
    └── server
      |-- include
      |── example-server.c

我已经在本地构建并安装了 protobuf-c-rpc 及其依赖项

我想使用 CMake 构建如下:

  1. Glob 接口文件夹并编译所有*.proto文件
  2. 从 *.proto 文件生成 C 头文件和源文件,并将它们分别放在 ${PROJECT_SOURCE_DIR}/server/include 和 ${PROJECT_SOURCE_DIR}/server/ 中
  3. 从 *.proto 文件生成 python 代码并将它们放在 ${PROJECT_SOURCE_DIR}/client/core
  4. 编译生成的C文件(包括example-server.c)
  5. 将第 4 步中的目标文件与 protobuf-c 库链接(目前,我只设法为 protobuf-c* 构建静态库)

到目前为止,这是我的 CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.10)

# set the project name
project(MyProj VERSION 0.10)

file(GLOB PROTOBUF_DEFINITION_FILES "interfaces/*.proto")
set(PROTOBUF_INPUT_DIRECTORY "${PROJECT_SOURCE_DIR}")
set(PROTOBUF_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/src/")
foreach(file ${PROTOBUF_DEFINITION_FILES})
    # Generate C stubs
    set(PROTOBUF_C_ARGUMENTS "protoc-c --proto_path=\"${PROTOBUF_INPUT_DIRECTORY}\" --c_out=\"${PROTOBUF_OUTPUT_DIRECTORY}\server\" \"${file}\"")
    execute_process(COMMAND ${PROTOBUF_C_ARGUMENTS}
            WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
            RESULT_VARIABLE PROTOBUF_C_RESULT
            OUTPUT_VARIABLE PROTOBUF_C_OUTPUT_VARIABLE)

    # Generate Python bindings
    set(PROTOBUF_ARGUMENTS "protoc --proto_path=\"${PROTOBUF_INPUT_DIRECTORY}\" --python_out=\"${PROTOBUF_OUTPUT_DIRECTORY}\client\" \"${file}\"")
    execute_process(COMMAND ${PROTOBUF_ARGUMENTS}
            WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
            RESULT_VARIABLE PROTOBUF_RESULT
            OUTPUT_VARIABLE PROTOBUF_OUTPUT_VARIABLE)            
endforeach()

# Move C headers to include folder
file(GLOB GENERATED_C_HEADERS
  "${PROTOBUF_OUTPUT_DIRECTORY}/server/*.pb-c.h"
)
file(COPY ${GENERATED_C_HEADERS} DESTINATION "${PROTOBUF_OUTPUT_DIRECTORY}/server/include/")
# file(REMOVE "${GENERATED_C_HEADERS}" ) doesn't work? why can't I use variable here?
file(REMOVE "${PROTOBUF_OUTPUT_DIRECTORY}/server/*.pb-c.h")

file(GLOB PROTOBUF_MODELS_INCLUDES "src/server/*.pb-c.c" "src/server/includes/*.h")

# Need to build (compile + link) my custom C sources + generated C stubs + link to protobuf-c-* libraries
# ... ?

如何修改上面的 CMakeLists.txt,以实现我上面描述的工作流程?

[[编辑]]

如果我还可以在 CMakeLists 选项中指定 C 可执行文件的调试和发布版本,那就太好了

4

1 回答 1

0

不要在 CMake 配置阶段执行此操作。在构建阶段进行。

CMake 是一个构建系统生成器,构建系统需要依赖项。模型依赖。该文件取决于该文件和该命令。

这是一个简短的脚本,也许可以帮助您入门。我在这里写了脚本,它可能充满了错误和错别字:

# Glob the interfaces folder 
file(GLOB files interfaces/*.proto)

set(pythonouts) # list for python output files
set(srcs)  # list for c/h generated sources
foreach(file IN LISTS files)
   get_filename_component(out ${file} NAME_WE)

   # Generate C headers and source files from the *.proto files and place 
   # them in ${PROJECT_SOURCE_DIR}/server/include and 
   # ${PROJECT_SOURCE_DIR}/server/ respectively
   add_custom_command(
       COMMENT "Generate this and that from ${file} using proto-c"
       COMMAND protoc-c
             --proto_path=${PROTOBUF_INPUT_DIRECTORY}
             --c_out=${PROTOBUF_OUTPUT_DIRECTORY}/server/
             ${file}
       COMMAND ${CMAKE_COMMAND} -E copy
            ${PROTOBUF_OUTPUT_DIRECTORY}/server/${out}.pb-c.h
            ${PROTOBUF_OUTPUT_DIRECTORY}/server/include/${out}.pb-c.h
       COMMAND ${CMAKE_COMMAND} -E remove
            ${PROTOBUF_OUTPUT_DIRECTORY}/server/${out}.pb-c.h
       DEPENDS
            ${file}
       OUTPUT
            ${PROTOBUF_OUTPUT_DIRECTORY}\server\${out}.pb-c.c
            ${PROTOBUF_OUTPUT_DIRECTORY}\server\include\${out}.pb-c.h
       VERBATIM
   )
   list(APPEND srcs
      ${PROTOBUF_OUTPUT_DIRECTORY}\server\include\${out}.pb-c.h
      ${PROTOBUF_OUTPUT_DIRECTORY}\server\${out}.pb-c.c
   )

   # Generate python code from the *.proto files and place
   # them in ${PROJECT_SOURCE_DIR}/client/core
   add_custom_command(
      COMMENT "Generate python this and that from ${file} using proto"
      COMMAND proto ....
      DEPENDS ${file}
      OUTPUT
         ${PROTOBUF_OUTPUT_DIRECTORY}\server\${out}.pb.python
      VERBATIM
   )
   list(APPEND pythonouts
       ${PROTOBUF_OUTPUT_DIRECTORY}\server\${out}.pb.python
   )

endfor()

add_custom_command(gen-python-files ALL)
depends(gen-python-files ${pythonouts})

# Compile the C files generated (including example-server.c)
add_executable(someexe example-server.c ${srcs})

# Link the object files from step 4 with the protobuff-c libs (currently, I have only managed to build the static libs for protobuf-c*)
# https://cmake.org/cmake/help/latest/module/FindProtobuf.html
find_package(Protobuf REQUIRED)
target_link_libraries(someexe PUHBLIC ${Protobuf_LIBRARIES})

如果您打算自己动手,您可能会想从cmake findprotobuf中汲取灵感。

于 2021-10-07T21:55:58.427 回答