diff --git a/agv_calib_brain/src/agv_calib_core/CMakeLists.txt b/agv_calib_brain/src/agv_calib_core/CMakeLists.txt index 4950ca7..5d02b51 100644 --- a/agv_calib_brain/src/agv_calib_core/CMakeLists.txt +++ b/agv_calib_brain/src/agv_calib_core/CMakeLists.txt @@ -1,49 +1,78 @@ cmake_minimum_required(VERSION 3.8) project(agv_calib_core) -# 1. 寻找 ROS 2 依赖 +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# 1. 寻找 ROS 2 核心依赖 find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) -# 2. 寻找 gRPC 和 Protobuf 依赖 -find_package(Protobuf REQUIRED) -find_package(gRPC REQUIRED) +# ========================================================== +# 🚨 核心排雷修复:放弃 find_package,改用 PkgConfig 寻找 gRPC +# ========================================================== +find_package(Protobuf REQUIRED) # Protobuf 依然可以用自带的找 +find_package(PkgConfig REQUIRED) # 引入 Linux 底层 PkgConfig 工具 +# 强制让系统去底层寻找 grpc++ 库,并映射为虚拟目标 PkgConfig::GRPC +pkg_check_modules(GRPC REQUIRED IMPORTED_TARGET grpc++) +# ========================================================== -# 3. 设置 Proto 文件路径与自动生成的源码输出路径 +# 3. 设置 Proto 文件夹路径与输出路径 set(PROTO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/proto") -set(PROTO_FILE "${PROTO_DIR}/agv_calib_control.proto") +file(GLOB PROTO_FILES "${PROTO_DIR}/*.proto") + set(PROTO_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/grpc_gen") file(MAKE_DIRECTORY ${PROTO_OUT_DIR}) -# 4. 自动生成 gRPC C++ 源码 (每次 colcon build 自动执行) -find_program(GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) -add_custom_command( - OUTPUT "${PROTO_OUT_DIR}/agv_calib_control.pb.cc" - "${PROTO_OUT_DIR}/agv_calib_control.pb.h" - "${PROTO_OUT_DIR}/agv_calib_control.grpc.pb.cc" - "${PROTO_OUT_DIR}/agv_calib_control.grpc.pb.h" - COMMAND protoc - ARGS --proto_path="${PROTO_DIR}" - --cpp_out="${PROTO_OUT_DIR}" - --grpc_out="${PROTO_OUT_DIR}" - --plugin=protoc-gen-grpc="${GRPC_CPP_PLUGIN_EXECUTABLE}" - "${PROTO_FILE}" - DEPENDS "${PROTO_FILE}" +# 4. 自动生成 gRPC C++ 源码 +find_program(GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin REQUIRED) + +set(PROTO_SRCS "") +set(PROTO_HDRS "") +foreach(PROTO_FILE ${PROTO_FILES}) + get_filename_component(FIL_WE ${PROTO_FILE} NAME_WE) + list(APPEND PROTO_SRCS "${PROTO_OUT_DIR}/${FIL_WE}.pb.cc" "${PROTO_OUT_DIR}/${FIL_WE}.grpc.pb.cc") + list(APPEND PROTO_HDRS "${PROTO_OUT_DIR}/${FIL_WE}.pb.h" "${PROTO_OUT_DIR}/${FIL_WE}.grpc.pb.h") + + add_custom_command( + OUTPUT "${PROTO_OUT_DIR}/${FIL_WE}.pb.cc" + "${PROTO_OUT_DIR}/${FIL_WE}.pb.h" + "${PROTO_OUT_DIR}/${FIL_WE}.grpc.pb.cc" + "${PROTO_OUT_DIR}/${FIL_WE}.grpc.pb.h" + COMMAND protoc + # ========================================================== + # 🚨 核心修复:强行解锁 proto3 的 optional 实验性特性语法 + # ========================================================== + ARGS --experimental_allow_proto3_optional # <--- 🚨 就是加了这一行! + --proto_path="${PROTO_DIR}" + --cpp_out="${PROTO_OUT_DIR}" + --grpc_out="${PROTO_OUT_DIR}" + --plugin=protoc-gen-grpc="${GRPC_CPP_PLUGIN_EXECUTABLE}" + "${PROTO_FILE}" + DEPENDS "${PROTO_FILE}" + ) +endforeach() + +# 5. 将所有生成的网络源码统一打包成独立的 C++ 共享库 +add_library(${PROJECT_NAME}_grpc_lib SHARED ${PROTO_SRCS}) +target_include_directories(${PROJECT_NAME}_grpc_lib PUBLIC "${PROTO_OUT_DIR}") + +# 🚨 核心修复 2:这里必须改成链接 PkgConfig::GRPC +target_link_libraries(${PROJECT_NAME}_grpc_lib + PkgConfig::GRPC + protobuf::libprotobuf ) -# 5. 将生成的网络源码打包成独立的 C++ 库 -add_library(agv_grpc_proto_lib SHARED - "${PROTO_OUT_DIR}/agv_calib_control.pb.cc" - "${PROTO_OUT_DIR}/agv_calib_control.grpc.pb.cc" -) -target_include_directories(agv_grpc_proto_lib PUBLIC "${PROTO_OUT_DIR}") -target_link_libraries(agv_grpc_proto_lib gRPC::grpc++ protobuf::libprotobuf) - -# 6. 编译您的 ROS 2 节点主程序 -add_executable(brain_node src/brain_node.cpp) +# 6. 编译具体的标定业务主控节点 +add_executable(brain_node src/brain_node.cpp) ament_target_dependencies(brain_node rclcpp) -# 🚨 必须链接刚才生成的 gRPC 库 -target_link_libraries(brain_node agv_grpc_proto_lib) +# 必须链接刚才生成的协议库 +target_link_libraries(brain_node ${PROJECT_NAME}_grpc_lib) + +# 7. ROS 2 安装规则 install(TARGETS brain_node DESTINATION lib/${PROJECT_NAME}) -ament_package() +install(DIRECTORY proto/ DESTINATION share/${PROJECT_NAME}/proto) + +ament_package() \ No newline at end of file diff --git a/agv_calib_brain/src/agv_calib_core/src/master_node.cpp b/agv_calib_brain/src/agv_calib_core/src/master_node.cpp new file mode 100644 index 0000000..f637f03 --- /dev/null +++ b/agv_calib_brain/src/agv_calib_core/src/master_node.cpp @@ -0,0 +1,12 @@ +#include + +int main(int argc, char **argv) { + rclcpp::init(argc, argv); + auto node = rclcpp::Node::make_shared("master_node"); + + RCLCPP_INFO(node->get_logger(), "🚀 AGV 标定主控大脑编译成功,gRPC 契约已挂载!"); + + rclcpp::spin(node); + rclcpp::shutdown(); + return 0; +} \ No newline at end of file