# ROS spec:nebula_continental(ament_cmake 形态,monorepo 多包内嵌构建) # 上游:https://github.com/tier4/nebula(branch main) # 构建类型:ament_cmake,使用 autoware_cmake 宏 + out-of-source CMake # 依赖模型:标准 ROS 消息包 + autoware/nebula 内部包 + yaml-cpp 系统库 # # 多包内嵌构建说明:tier4/nebula 是 monorepo,nebula_continental 编译时 # 链接同仓 sibling 包(nebula_continental_common/decoders/hw_interfaces、 # nebula_core_ros、nebula_core_hw_interfaces)。这些包在 EUR(additional_repos) # 中使用下划线命名(ros-humble-nebula_continental_common 而非连字符), # 依赖预检按连字符名查询无 provider;COPR 批量构建的同名包亦全部失败 # (build 113348/113349/113350 均 failed)。改用同源内嵌构建:在 %build 中 # 按依赖拓扑序逐个 cmake && make install DESTDIR,后续包通过 CMAKE_PREFIX_PATH # 含 buildroot 前缀发现已装 sibling。Provides 声明虚拟别名满足下游。 %define ros_distro humble %define RosPkgName nebula-continental Name: ros-%{ros_distro}-%{RosPkgName} Version: 1.2.0 Release: 1%{?dist} Summary: Nebula Continental ROS Wrapper License: Apache-2.0 URL: https://github.com/tier4/nebula # GitHub branch main 归档;URL 后缀 #/ 强制 rpm 内部文件名,与 autosetup -n 统一目录名 Source0: https://github.com/tier4/nebula/archive/refs/heads/main.tar.gz#/nebula-continental-%{version}.tar.gz # debug 子包无意义(/opt 前缀,strip/debugedit 路径非常规),SIG 模板统一关闭 %global debug_package %{nil} # /opt 下 python 字节码编译会写标准 sitelib 路径,摘掉 brp-python-bytecompile %global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g') # ROS 包不做自动依赖扫描(.so 全在 /opt/ros 下,由 ament 间接依赖模型替代) %global __provides_exclude_from ^/opt/ros/%{ros_distro}/.*$ %global __requires_exclude_from ^/opt/ros/%{ros_distro}/.*$ # ===== BuildRequires ===== # 系统构建工具与库 BuildRequires: cmake BuildRequires: gcc-c++ BuildRequires: boost-devel BuildRequires: yaml-cpp-devel # 构建基座(ament_cmake 形态强制) BuildRequires: ros-%{ros_distro}-ament-cmake # buildtool_depend(package.xml) BuildRequires: ros-%{ros_distro}-autoware-cmake BuildRequires: ros-%{ros_distro}-ros-environment BuildRequires: ros-%{ros_distro}-ros-testing # depend(package.xml,条件依赖 agnocast_components 默认不启用故省略) # 内嵌构建的 sibling 包不写 BuildRequires(同源 %build 编译安装): # nebula_continental_common / nebula_continental_decoders / # nebula_continental_hw_interfaces / nebula_core_ros / # nebula_core_hw_interfaces(nebula_continental_hw_interfaces 的传递依赖) BuildRequires: ros-%{ros_distro}-autoware-sensing-msgs BuildRequires: ros-%{ros_distro}-continental-msgs BuildRequires: ros-%{ros_distro}-continental-srvs BuildRequires: ros-%{ros_distro}-diagnostic-msgs BuildRequires: ros-%{ros_distro}-diagnostic-updater BuildRequires: ros-%{ros_distro}-geometry-msgs BuildRequires: ros-%{ros_distro}-message-filters BuildRequires: ros-%{ros_distro}-nebula-core-common BuildRequires: ros-%{ros_distro}-nebula-msgs BuildRequires: ros-%{ros_distro}-radar-msgs BuildRequires: ros-%{ros_distro}-rclcpp BuildRequires: ros-%{ros_distro}-rclcpp-components BuildRequires: ros-%{ros_distro}-rosbag2-storage BuildRequires: ros-%{ros_distro}-sensor-msgs BuildRequires: ros-%{ros_distro}-sync-tooling-msgs BuildRequires: ros-%{ros_distro}-tf2-ros BuildRequires: ros-%{ros_distro}-visualization-msgs # ===== Requires(运行时;/opt/ros 被 autodeps 豁免,必须手写)===== # 强制基座(§6 运行时 Requires 三件套) Requires: ros-%{ros_distro}-ros-workspace Requires: ros-%{ros_distro}-ament-cmake # package.xml 的运行时部分(exec 依赖) # 内嵌构建的 sibling 包不写 Requires(文件已在本包 %files 中) Requires: ros-%{ros_distro}-autoware-sensing-msgs Requires: ros-%{ros_distro}-continental-msgs Requires: ros-%{ros_distro}-continental-srvs Requires: ros-%{ros_distro}-diagnostic-msgs Requires: ros-%{ros_distro}-diagnostic-updater Requires: ros-%{ros_distro}-geometry-msgs Requires: ros-%{ros_distro}-message-filters Requires: ros-%{ros_distro}-nebula-core-common Requires: ros-%{ros_distro}-nebula-msgs Requires: ros-%{ros_distro}-radar-msgs Requires: ros-%{ros_distro}-rclcpp Requires: ros-%{ros_distro}-rclcpp-components Requires: ros-%{ros_distro}-sensor-msgs Requires: ros-%{ros_distro}-sync-tooling-msgs Requires: ros-%{ros_distro}-tf2-ros Requires: ros-%{ros_distro}-visualization-msgs Requires: yaml-cpp # 单包策略:虚拟别名兼容依赖方,禁止拆实体子包(路径重叠致安装事务冲突) Provides: %{name}-devel = %{version}-%{release} Provides: %{name}-doc = %{version}-%{release} Provides: %{name}-runtime = %{version}-%{release} # 内嵌构建的 sibling 包虚拟别名(满足下游 Requires 与 CI 可安装性检查) Provides: ros-%{ros_distro}-nebula-continental-common = %{version}-%{release} Provides: ros-%{ros_distro}-nebula-continental-decoders = %{version}-%{release} Provides: ros-%{ros_distro}-nebula-continental-hw-interfaces = %{version}-%{release} Provides: ros-%{ros_distro}-nebula-core-ros = %{version}-%{release} Provides: ros-%{ros_distro}-nebula-core-hw-interfaces = %{version}-%{release} %description Nebula Continental ROS Wrapper — Continental ARS548 / SRR520 雷达 ROS 封装, 提供解码器封装、硬件接口封装与 ROS 节点组件。属于 TIER IV Nebula 多雷达驱动框架的 Continental 分支,构建进 /opt/ros/humble 前缀。 本包内嵌构建同仓 sibling 包(nebula_continental_common/decoders/hw_interfaces、 nebula_core_ros、nebula_core_hw_interfaces),因 EUR 命名约定(下划线) 与 COPR 批量构建均不可用,改由同源 monorepo 编译安装。 %prep %autosetup -n nebula-continental-%{version} -p1 %build # ROS 基座环境(chroot 已配置 ROS SIG repo;无 ROS 依赖的包 buildroot 里 # 可能没有 setup.sh,必须用 [ -f ] 守卫——直接 source 不存在的文件在 # 严格 sh 下会中止整个 %build 脚本,|| true 挡不住) [ -f /opt/ros/%{ros_distro}/setup.sh ] && source /opt/ros/%{ros_distro}/setup.sh || true export PYTHONPATH=/opt/ros/%{ros_distro}/lib/python%{python3_version}/site-packages${PYTHONPATH:+:$PYTHONPATH} export PKG_CONFIG_PATH=/opt/ros/%{ros_distro}/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH} # staged install prefix:sibling 包 make install DESTDIR=%{buildroot} 后, # 后续包通过 CMAKE_PREFIX_PATH / AMENT_PREFIX_PATH 含 %{buildroot}/opt/ros 发现 _STAGED="%{buildroot}/opt/ros/%{ros_distro}" export AMENT_PREFIX_PATH="${_STAGED}:/opt/ros/%{ros_distro}${AMENT_PREFIX_PATH:+:$AMENT_PREFIX_PATH}" export PKG_CONFIG_PATH="${_STAGED}/lib/pkgconfig:${PKG_CONFIG_PATH}" # monorepo 多包内嵌构建:按依赖拓扑序逐个 cmake + build + install # 拓扑序:common → hw_interfaces → decoders → hw_interfaces(continental) → core_ros → continental # 1. nebula_continental_common(header-only INTERFACE,依赖 nebula_core_common) mkdir -p src/nebula_continental/nebula_continental_common/.obj cd src/nebula_continental/nebula_continental_common/.obj %cmake3 .. \ -DCMAKE_INSTALL_PREFIX="/opt/ros/%{ros_distro}" \ -DAMENT_PREFIX_PATH="/opt/ros/%{ros_distro};${_STAGED}" \ -DCMAKE_PREFIX_PATH="/opt/ros/%{ros_distro};${_STAGED}" \ -UINCLUDE_INSTALL_DIR -ULIB_INSTALL_DIR -USYSCONF_INSTALL_DIR -USHARE_INSTALL_PREFIX -ULIB_SUFFIX \ -DSETUPTOOLS_DEB_LAYOUT=OFF \ -DBUILD_TESTING=OFF %cmake_build make install DESTDIR=%{buildroot} cd - >/dev/null # 2. nebula_core_hw_interfaces(header-only INTERFACE,依赖 nebula_core_common) mkdir -p src/nebula_core/nebula_core_hw_interfaces/.obj cd src/nebula_core/nebula_core_hw_interfaces/.obj %cmake3 .. \ -DCMAKE_INSTALL_PREFIX="/opt/ros/%{ros_distro}" \ -DAMENT_PREFIX_PATH="/opt/ros/%{ros_distro};${_STAGED}" \ -DCMAKE_PREFIX_PATH="/opt/ros/%{ros_distro};${_STAGED}" \ -UINCLUDE_INSTALL_DIR -ULIB_INSTALL_DIR -USYSCONF_INSTALL_DIR -USHARE_INSTALL_PREFIX -ULIB_SUFFIX \ -DSETUPTOOLS_DEB_LAYOUT=OFF \ -DBUILD_TESTING=OFF %cmake_build make install DESTDIR=%{buildroot} cd - >/dev/null # 3. nebula_continental_decoders(SHARED lib,依赖 #1 nebula_continental_common) mkdir -p src/nebula_continental/nebula_continental_decoders/.obj cd src/nebula_continental/nebula_continental_decoders/.obj %cmake3 .. \ -DCMAKE_INSTALL_PREFIX="/opt/ros/%{ros_distro}" \ -DAMENT_PREFIX_PATH="/opt/ros/%{ros_distro};${_STAGED}" \ -DCMAKE_PREFIX_PATH="/opt/ros/%{ros_distro};${_STAGED}" \ -UINCLUDE_INSTALL_DIR -ULIB_INSTALL_DIR -USYSCONF_INSTALL_DIR -USHARE_INSTALL_PREFIX -ULIB_SUFFIX \ -DSETUPTOOLS_DEB_LAYOUT=OFF \ -DBUILD_TESTING=OFF %cmake_build make install DESTDIR=%{buildroot} cd - >/dev/null # 4. nebula_continental_hw_interfaces(SHARED lib,依赖 #1 + #2) mkdir -p src/nebula_continental/nebula_continental_hw_interfaces/.obj cd src/nebula_continental/nebula_continental_hw_interfaces/.obj %cmake3 .. \ -DCMAKE_INSTALL_PREFIX="/opt/ros/%{ros_distro}" \ -DAMENT_PREFIX_PATH="/opt/ros/%{ros_distro};${_STAGED}" \ -DCMAKE_PREFIX_PATH="/opt/ros/%{ros_distro};${_STAGED}" \ -UINCLUDE_INSTALL_DIR -ULIB_INSTALL_DIR -USYSCONF_INSTALL_DIR -USHARE_INSTALL_PREFIX -ULIB_SUFFIX \ -DSETUPTOOLS_DEB_LAYOUT=OFF \ -DBUILD_TESTING=OFF %cmake_build make install DESTDIR=%{buildroot} cd - >/dev/null # 5. nebula_core_ros(SHARED lib,依赖 nebula_core_common + rosbag2_storage) mkdir -p src/nebula_core/nebula_core_ros/.obj cd src/nebula_core/nebula_core_ros/.obj %cmake3 .. \ -DCMAKE_INSTALL_PREFIX="/opt/ros/%{ros_distro}" \ -DAMENT_PREFIX_PATH="/opt/ros/%{ros_distro};${_STAGED}" \ -DCMAKE_PREFIX_PATH="/opt/ros/%{ros_distro};${_STAGED}" \ -UINCLUDE_INSTALL_DIR -ULIB_INSTALL_DIR -USYSCONF_INSTALL_DIR -USHARE_INSTALL_PREFIX -ULIB_SUFFIX \ -DSETUPTOOLS_DEB_LAYOUT=OFF \ -DBUILD_TESTING=OFF %cmake_build make install DESTDIR=%{buildroot} cd - >/dev/null # 6. nebula_continental(主包,依赖 #1 #3 #4 #5 + 外部 ROS 包) mkdir -p src/nebula_continental/nebula_continental/.obj cd src/nebula_continental/nebula_continental/.obj %cmake3 .. \ -DCMAKE_INSTALL_PREFIX="/opt/ros/%{ros_distro}" \ -DAMENT_PREFIX_PATH="/opt/ros/%{ros_distro};${_STAGED}" \ -DCMAKE_PREFIX_PATH="/opt/ros/%{ros_distro};${_STAGED}" \ -UINCLUDE_INSTALL_DIR -ULIB_INSTALL_DIR -USYSCONF_INSTALL_DIR -USHARE_INSTALL_PREFIX -ULIB_SUFFIX \ -DSETUPTOOLS_DEB_LAYOUT=OFF \ -DBUILD_TESTING=OFF %cmake_build %install # 所有 sibling 包在 %build 阶段已 make install DESTDIR=%{buildroot}, # 仅需安装主包(nebula_continental)的最终产物 cd src/nebula_continental/nebula_continental/.obj make install DESTDIR=%{buildroot} %files %license LICENSE # 整树拥有(SIG 模板标准做法,对"装了没打包"类错误免疫) /opt/ros/%{ros_distro} %changelog * Thu Oct 08 2026 ROS SIG - 1.2.0-1 - 初始引入 ros-humble-nebula-continental 1.2.0 - 内嵌构建同仓 sibling 包(EUR 下划线命名不匹配 + COPR 构建失败)