summaryrefslogtreecommitdiff
path: root/mrpt-libbase.spec
blob: e3bf581dff5e579f4421b1c79f41516b7bd3b8f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
%define ros_distro humble
%define RosPkgName mrpt-libbase
%define src_version 2.15.20
%define mrpt_version 2.15.21
# mrpt 的 git submodule 内容(GitHub archive tarball 不含),按需手工补:
%define nanoflann_version 1.5.5
%define simpleini_version 4.22

Name:           ros-%{ros_distro}-%{RosPkgName}
Version:        2.15.20
Release:        3%{?dist}
Summary:        Mobile Robot Programming Toolkit (MRPT) libraries (core C++ libraries)
License:        BSD
URL:            https://github.com/MRPT/mrpt_ros.git
Source0:        %{RosPkgName}-%{src_version}.tar.gz
# mrpt upstream source, pre-fetched to avoid ExternalProject git clone at build time
Source1:        https://github.com/MRPT/mrpt/archive/refs/tags/%{mrpt_version}.tar.gz#/mrpt-%{mrpt_version}.tar.gz
# mrpt 的两个 submodule(COPR chroot 无外网,构建期无法下载/克隆,须随 SRPM 携带):
#   nanoflann —— mrpt 强制依赖(script_nanoflann.cmake: FATAL_ERROR if not found),
#                openEuler 无系统包,只能喂 3rdparty/nanoflann 让内层自建(头文件库)
#   simpleini —— mrpt-config 编译 CConfigFile.cpp 需要 SimpleIni.h(script_simpleini.cmake
#                回退到 3rdparty/simpleini 作为 include 目录)
Source2:        https://github.com/jlblancoc/nanoflann/archive/refs/tags/v%{nanoflann_version}.tar.gz#/nanoflann-%{nanoflann_version}.tar.gz
Source3:        https://github.com/brofield/simpleini/archive/refs/tags/v%{simpleini_version}.tar.gz#/simpleini-%{simpleini_version}.tar.gz

%global debug_package %{nil}
%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
%global __provides_exclude_from ^/opt/ros/%{ros_distro}/.*$
%global __requires_exclude_from ^/opt/ros/%{ros_distro}/.*$

BuildRequires:  assimp-devel
BuildRequires:  eigen3-devel
BuildRequires:  ffmpeg-devel
BuildRequires:  freeglut-devel
BuildRequires:  git
BuildRequires:  gtest-devel
BuildRequires:  libXrandr-devel
BuildRequires:  libXxf86vm-devel
BuildRequires:  libpcap-devel
BuildRequires:  libudev-devel
BuildRequires:  libusbx-devel
BuildRequires:  libjpeg-devel
BuildRequires:  libzstd-devel
BuildRequires:  libglvnd-devel
BuildRequires:  mesa-libGL-devel
BuildRequires:  mesa-libGLU-devel
BuildRequires:  opencv
BuildRequires:  pkgconfig
BuildRequires:  pybind11-devel
BuildRequires:  suitesparse-devel
BuildRequires:  tbb-devel
BuildRequires:  tinyxml2-devel
BuildRequires:  zlib-devel
BuildRequires:  cmake

Requires:       ros-%{ros_distro}-ros-workspace

Provides:       %{name}-devel = %{version}-%{release}
Provides:       %{name}-doc = %{version}-%{release}
Provides:       %{name}-runtime = %{version}-%{release}

%description
Mobile Robot Programming Toolkit (MRPT) libraries (core C++ libraries).
  This package contains: mrpt-io, mrpt-serialization, mrpt-random, mrpt-system, mrpt-rtti, mrpt-containers, mrpt-typemeta, mrpt-core, mrpt-random, mrpt-config, mrpt-expr

%prep
%autosetup -n %{RosPkgName}-%{src_version}
# --- 复用预置 mrpt 源码,避免 ExternalProject 在构建期 git clone -------------
# mrpt_libbase/CMakeLists.txt 用 ExternalProject_Add(mrpt ...) 拉取上游 mrpt,
# 本地复用路径写成 ${CMAKE_BINARY_DIR}/../mrpt_libbase/mrpt-build/...,那是 ROS
# 官方 buildfarm 的目录布局(build 目录 = <ws>/build/mrpt_libbase,故其 .. 即
# <ws>/build)。本 spec 的 CMAKE_BINARY_DIR = <top>/mrpt_libbase/.obj,同一表达式
# 会多出一层 mrpt_libbase(<top>/mrpt_libbase/mrpt_libbase/mrpt-build),EXISTS
# 检查必然失败而退回 git clone;COPR chroot 无外网,clone 100% 失败
# (build 112429/112431/112435/112438 连续四轮的根因,日志均为
#  "Could not resolve host: github.com")。
# 统一改写成相对 CMakeLists.txt 自身目录的 ../mrpt-build,与下面 %prep 的预置
# 目录 <top>/mrpt-build 对齐(VERSION_CACHE / EXISTS 检查 / SOURCE_DIR 三处)。
sed -i 's|\${CMAKE_BINARY_DIR}/\.\./mrpt_libbase/mrpt-build|${CMAKE_CURRENT_LIST_DIR}/../mrpt-build|g' \
    mrpt_libbase/CMakeLists.txt
# 去掉 HOME==/home/buildfarm 守卫:该条件只对 buildfarm 屏蔽本地复用,COPR 里
# HOME 非 /home/buildfarm,去掉后复用分支在任何构建环境都成立。
sed -i 's/AND (NOT "\$ENV{HOME}" STREQUAL "\/home\/buildfarm")//' \
    mrpt_libbase/CMakeLists.txt
# 给内层 mrpt 追加开关(外层 cmake 命令行传的 MRPT_WITH_xxx 落在 ROS 包装工程上,
# 而包装工程只把它们原样忽略——真正生效的是写死在 ExternalProject_Add 的
# CMAKE_ARGS,必须在此注入):
#   MRPT_HAS_LIBFYAML=OFF  openEuler 无 libfyaml,内置分支要 3rdparty/libfyaml
#                          (submodule 空目录)且会 file(READ .tarball-version) 报错;
#                          该特性只影响 mrpt::containers::yaml,关掉即可(ROS 包
#                          package.xml 里 libfyaml-dev 也被上游注释掉了)
#   MRPT_WITH_KINECT=OFF   libusb 存在时默认开启 Kinect,会去编译空的
#                          3rdparty/libfreenect(openEuler 无 libfreenect-devel)
#   MRPT_HAS_OPENNI2=OFF   无 libopenni2
#   MRPT_BUILD_OCTOMAP=OFF 无系统 octomap 时 ExternalProject 会从 GitHub 下载
#                          octomap(构建期无外网必失败);octomap 只被 maps/obs/
#                          opengl 使用,本包(libbase 粒度)全部为 OFF
sed -i 's|^\(\s*-DDISABLE_JSONCPP=ON\)$|\1\n    -DMRPT_HAS_LIBFYAML=OFF\n    -DMRPT_WITH_KINECT=OFF\n    -DMRPT_HAS_OPENNI2=OFF\n    -DMRPT_BUILD_OCTOMAP=OFF|' \
    mrpt_libbase/CMakeLists.txt
# 预置 ExternalProject 的 SOURCE_DIR:<top>/mrpt-build/src/mrpt
mkdir -p mrpt-build/src
tar -xzf %{SOURCE1} -C mrpt-build/src
mv mrpt-build/src/mrpt-%{mrpt_version} mrpt-build/src/mrpt
# 版本缓存:cmake 读取 <top>/mrpt-build/MRPT_VERSION_TO_DOWNLOAD.txt,内容必须与
# MRPT_VERSION_TO_DOWNLOAD 完全一致(无换行)才走复用分支。
echo -n "%{mrpt_version}" > mrpt-build/MRPT_VERSION_TO_DOWNLOAD.txt
# GitHub archive tarball 不含 git submodule 内容,而上游 mrpt 顶层 CMakeLists.txt
# 第 49-55 行有无条件存在性检查(3rdparty/nanogui/include、3rdparty/rplidar_sdk/
# sdk/src),缺失即 FATAL_ERROR "git submodules missing!"。补空目录绕过;两个
# 子项目在内层 CMAKE_ARGS 里已分别用 -DMRPT_BUILD_nanogui=OFF /
# -DMRPT_BUILD_rplidar_sdk=OFF 关闭,不会被真正编译。
mkdir -p mrpt-build/src/mrpt/3rdparty/nanogui/include \
         mrpt-build/src/mrpt/3rdparty/rplidar_sdk/sdk/src
# 填充 mrpt 的两个必需 submodule(见 Source2/Source3 说明):nanoflann 供内层
# CMake 自建(头文件库),simpleini 仅作为 mrpt-config 的 include 目录。
rm -rf mrpt-build/src/mrpt/3rdparty/nanoflann mrpt-build/src/mrpt/3rdparty/simpleini
mkdir -p mrpt-build/src/mrpt/3rdparty/nanoflann mrpt-build/src/mrpt/3rdparty/simpleini
tar -xzf %{SOURCE2} -C mrpt-build/src/mrpt/3rdparty/nanoflann --strip-components=1
tar -xzf %{SOURCE3} -C mrpt-build/src/mrpt/3rdparty/simpleini --strip-components=1
# Override the version cmake reads from package.xml to match the pre-fetched source
echo 'set(MRPT_VERSION_TO_DOWNLOAD "%{mrpt_version}")' > override_mrpt_version.cmake

%build
[ -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}
cd mrpt_libbase
mkdir -p .obj && cd .obj
%cmake3 \
    -DCMAKE_INSTALL_PREFIX="/opt/ros/%{ros_distro}" \
    -DAMENT_PREFIX_PATH="/opt/ros/%{ros_distro}" \
    -DCMAKE_PREFIX_PATH="/opt/ros/%{ros_distro}" \
    -UINCLUDE_INSTALL_DIR -ULIB_INSTALL_DIR -USYSCONF_INSTALL_DIR -USHARE_INSTALL_PREFIX -ULIB_SUFFIX \
    -DSETUPTOOLS_DEB_LAYOUT=OFF \
    -DBUILD_TESTING=OFF -DTESTING=OFF -DCMAKE_SUPPRESS_REGENERATION=ON \
    -DMRPT_WITH_FREENECT=OFF \
    -DMRPT_WITH_OPENNI2=OFF \
    -DMRPT_WITH_GLFW=OFF \
    -DMRPT_BUILD_wxThings=OFF \
    ..
# 闸门:cmake 生成 mrpt-gitclone.cmake 即表示未复用 %prep 预置的 mrpt 源码,
# 构建期将 git clone(COPR chroot 无外网,必然失败)。这里提前失败并给出明确
# 原因,避免又白烧一轮 COPR 构建。
if [ -e mrpt-build/tmp/mrpt-gitclone.cmake ]; then
    echo "ERROR: cmake 准备 git clone mrpt —— %prep 预置源码未被复用,请检查预置路径" >&2
    exit 1
fi
make %{?_smp_mflags}

%install
[ -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}
cd mrpt_libbase
cd .obj
make install DESTDIR=%{buildroot}

%files
/opt/ros/%{ros_distro}

%changelog
* Mon Sep 21 2026 ai-importer <ai-importer@openeuler.org> - 2.15.20-3
- 内层 mrpt 配置期剩余的 "无 submodule" 阻断逐个消除:
  * 注入 -DMRPT_HAS_LIBFYAML=OFF / -DMRPT_WITH_KINECT=OFF / -DMRPT_HAS_OPENNI2=OFF
    / -DMRPT_BUILD_OCTOMAP=OFF(外层 cmake 传的 MRPT_WITH_* 是空转,必须写进
    包装工程的 ExternalProject CMAKE_ARGS)。
  * 新增 Source2(nanoflann 1.5.5)、Source3(simpleini 4.22) 并在 %prep 填入
    3rdparty/nanoflann、3rdparty/simpleini(mrpt 强制依赖 nanoflann;mrpt-config
    需要 SimpleIni.h)。
- BuildRequires: freeglut → freeglut-devel(openEuler 的 freeglut 只有运行库,
  头文件/so 链接在 -devel;找不到系统 GLUT 时 mrpt 编内置 freeglut,会因
  -Werror=implicit-function-declaration 失败);新增 gtest-devel(避免编译内置
  googletest)。
- 本地按同一组 CMAKE_ARGS 完整验证:内层 mrpt 配置 + mrpt-config/containers/core/
  io/random/rtti/serialization/system/expr/typemeta 全部编译通过。
* Mon Sep 21 2026 ai-importer <ai-importer@openeuler.org> - 2.15.20-2
- 修复 %build 期 ExternalProject 退回 git clone 导致构建失败(COPR 无外网):
  %prep 将 CMakeLists.txt 的本地复用路径 ${CMAKE_BINARY_DIR}/../mrpt_libbase/
  mrpt-build 改写为 ${CMAKE_CURRENT_LIST_DIR}/../mrpt-build,并把预置 mrpt 源码
  放到与之对齐的 <top>/mrpt-build/(原路径多一层 mrpt_libbase,EXISTS 检查必然
  失败);保留去掉 HOME==/home/buildfarm 守卫的补丁。
- 补 3rdparty/nanogui/include 与 3rdparty/rplidar_sdk/sdk/src 空目录,绕过上游
  mrpt 顶层 CMakeLists.txt:51 的 "git submodules missing!" 致命检查(GitHub
  archive tarball 不含 submodule 内容;两者内层已 MRPT_BUILD_*=OFF)。
- 新增 BuildRequires: libglvnd-devel、mesa-libGLU-devel(mesa-libGL-devel 已有),
  满足 mrpt 对 OpenGL/GLU 的 find_package 探测。
- %build 增加闸门:若 cmake 生成 mrpt-gitclone.cmake 则立即失败并提示原因。
* Mon Sep 21 2026 ai-importer <ai-importer@openeuler.org> - 2.15.20-1
- Initial import (ROS batch)