如何在Conan包中封装Proto文件并供CMake依赖项目共享?
共享Protobuf基础定义的成熟方案
核心结论
共享.proto文件给依赖项目是完全合理的做法——这是多仓库/微服务场景下保证基础消息类型一致性、支持基于基础定义扩展的标准模式。下面是解决Conan+CMake配合问题的具体步骤:
一、Conan包端配置(打包基础proto和静态库)
CMake中正确安装proto文件
将.proto文件安装到包的include目录下的专属子目录,方便依赖项目定位:# 假设你的proto文件都在当前源码的proto/目录下 install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/proto/ DESTINATION include/your_package/proto FILES_MATCHING PATTERN "*.proto") # 同时配置静态库的安装和接口包含路径 add_library(your_static_lib STATIC ${GENERATED_PROTO_SRCS} ${GENERATED_PROTO_HDRS}) target_include_directories(your_static_lib PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> # 编译时生成的C++头文件路径 $<INSTALL_INTERFACE:include> # 安装后,依赖项目能找到proto和生成的头文件 ) install(TARGETS your_static_lib EXPORT your_package-targets DESTINATION lib) install(EXPORT your_package-targets FILE your_package-targets.cmake NAMESPACE your_package:: DESTINATION lib/cmake/your_package)Conan Recipe中配置路径传递
不要用resdirs,改用cpp_info.includedirs传递proto文件的父目录,避免构建类型后缀问题:from conans import ConanFile, CMake import os class YourPackageConan(ConanFile): name = "your_package" # ...其他配置(版本、依赖等) def package_info(self): # 添加proto文件所在的父目录到包含路径(依赖项目通过这个路径查找proto) self.cpp_info.includedirs.append(os.path.join("include", "your_package")) # 声明静态库 self.cpp_info.libs = ["your_static_lib"]
二、依赖项目端配置(使用共享的proto文件)
依赖项目通过Conan引入包后,直接利用CMake目标的接口属性获取proto路径,传递给protobuf_generate:
find_package(Protobuf REQUIRED) find_package(your_package REQUIRED) # 获取基础proto文件的根路径 get_target_property(YOUR_PACKAGE_PROTO_ROOT your_package::your_static_lib INTERFACE_INCLUDE_DIRECTORIES) # 生成自身的proto代码时,把基础proto路径传给protoc protobuf_generate( TARGET your_project_proto_target PROTOS your_project_extension.proto # 你的扩展proto文件,依赖基础定义 PROTO_PATH ${YOUR_PACKAGE_PROTO_ROOT} OUT_VAR GENERATED_SRCS OUT_HDRS GENERATED_HDRS )
三、解决路径重复问题
之前出现的路径重复(如/root/...//root/...)通常是因为:
- 手动重复添加了包含路径
- Conan包的
includedirs和CMake的INSTALL_INTERFACE路径不匹配
按照上面的步骤配置后,Conan的CMakeDeps生成器会自动管理路径,避免重复拼接问题。
内容的提问来源于stack exchange,提问作者Matt Soucy
相关产品推荐
相关产品推荐

