Skip to content

Add MOLA on MRPT 3 - #117

Merged
Tobias-Fischer merged 41 commits into
mainfrom
ports/mola
Oct 25, 2026
Merged

Tobias-Fischer merged 41 commits into
mainfrom
ports/mola

Conversation

@Tobias-Fischer

@Tobias-Fischer Tobias-Fischer commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #106, porting RoboStack/ros-lyrical#30 by @wolfv: adds mola to the shared selection, on all platforms. MOLA 3.x now builds on MRPT 3 (mrpt3-release: mrpt_core, mrpt_math, …) and mp2p_icp 3.0 is split into mp2p_icp_core/mp2p_icp_viz, so the old PR's MRPT 2 workarounds aren't used. Everything is released in the rosdistros (MOLA 3.3.x and MRPT 3 for humble, jazzy, lyrical and rolling), so no additional recipes.

One commit per fix:

  • cli11 rosdep key → conda-forge cli11 (was unmapped: mola_launcher, mp2p_icp_core/_viz, mola_metric_maps couldn't find CLI11). Side effect: gz_utils_vendor and ros_gz_sim also get cli11 in their recipes, so they rebuild.
  • mrpt_common: host-depends on ament_cmake (its CMakeLists uses it with ROS_VERSION=2, its package.xml doesn't declare it); mrpt_gui: host-depends on wxwidgets (the wxwidgets/wx-common keys map to wxpython only, so libmrpt_gui.so lacked libwx_baseu-3.3.so at runtime).
  • mrpt_gui: NO_CMAKE_FIND_ROOT_PATH for the bundled nanogui fonts (conda's find-root settings hid them).
  • mrpt_imgui_vendor: links ${CMAKE_DL_LIBS} publicly (dlopen is in libdl on the glibc 2.28 sysroot).
  • mola_launcher: also looks for modules in <prefix>/lib of each AMENT_PREFIX_PATH entry (a conda environment sets neither MOLA_MODULES_LIB_PATH nor LD_LIBRARY_PATH, so it found 0 modules), and skips *__rosidl_* libraries, which are never modules (loading the Python type support one crashed). The only patch that changes upstream behaviour.
  • The mola metapackage doesn't pull in mola_lidar_odometry/mola_state_estimation*; they can be added if wanted.

macOS (osx-arm64 trial):

  • mrpt_maps: the bundled Bonxai Grid move assignment re-constructs its Mask (const members): clang instantiates it and rejects the implicitly deleted assignment, GCC never instantiates it.
  • mrpt_gui: also builds the bundled nanogui on macOS (upstream defaults it off on Apple, which removes CDisplayWindowGUI that mola_viz needs).
  • mp2p_icp_core: dlopen and lib<name>.dylib on __APPLE__ (macOS took the Windows LoadLibrary branch, as Apple clang doesn't define __unix__), plugin search in each AMENT_PREFIX_PATH's lib like mola_launcher, and size_t values serialized as uint64_t (MRPT's CArchive only takes fixed-width integers; size_t is unsigned long but uint64_t is unsigned long long on macOS; the same type on Linux).
  • mp2p_icp_viz: links CoreServices on Apple (libcfgpath uses FSFindFolder).
  • mola_launcher: dlopen/.dylib modules on __APPLE__, as mp2p_icp_core.

Windows:

  • GLEW: the MRPT 3 release sources have no bundled GLEW (3rdparty/), so mrpt_opengl and mrpt_imgui link conda-forge's glew (a DLL: no GLEW_STATIC); mrpt_imgui's header calls GL extension functions inline, so its users get GLEW too (glew32.lib by path in the installed targets).
  • mrpt_gui: re-enables GDI (/UNOGDI: the ROS build scripts set NOGDI for every package, but wxWidgets' and nanogui's GUI code need it), <commdlg.h> for nanogui's file dialog, and installs nanogui's bundled glad headers (its opengl.h includes them on Windows, upstream only installs the GLFW and nanovg headers).
  • mrpt_math: run-depends on eigen on Windows (its exported targets carry the Eigen include path). mrpt_libros_bridge exports all symbols.
  • mola_kernel: #undef ERROR (wingdi.h) before DiagnosticLevel::ERROR; VizInterface's backend names as inline variables (static data members aren't exported by export-all, so mola_viz failed to link).
  • mola_launcher and mp2p_icp_core: modules and plugins load with LoadLibrary (<name>.dll, searched in each prefix's bin); mola-cli uses signal() and _write().
  • mola_yaml: an extra macro expansion for MSVC's traditional preprocessor (__VA_ARGS__); mola_bridge_ros2: /bigobj; mola_metric_maps: static constexpr for a lambda (C3493), and its tests aren't built (POSIX setenv()).

Qt 5 distributions (jazzy, humble):

  • mrpt_gui: add_host: wxwidgets >=3.2 in distros/{jazzy,humble}/patch/dependencies.yaml, overriding the shared wxwidgets. These distributions map Qt to qt-main 5.15, whose builds need gstreamer <1.27 on Linux, while the pinned wxwidgets 3.3.3 needs gstreamer 1.28, so the host environment couldn't be solved. With a version spec the pin doesn't apply, and on linux-64 the solver takes wxwidgets 3.2.8.1 (gstreamer 1.26); its run_exports still reach the run requirements.
  • mrpt_gui: error_box.cpp includes the wx headers only without Qt (its wx code is only used then). With Qt 5 on macOS, the wx and Qt headers clash (typedef 'NSData' cannot be referenced with the 'struct' specifier). No change on Linux or with Qt 6.

Recipe test on the mola metapackage: mola-cli --rtti-list-all lists MolaViz, BridgeROS2, Rosbag2Dataset and KeyframePointCloudMap, i.e. the launcher finds the module libraries without any environment variable (shared/tests/ros2-mola.yaml).

Built locally

  • lyrical, linux-64: all 231 recipes of the mola closure (ROS core, 31 mrpt_*, 17 mola_*, mp2p_icp*), with their recipe tests. Smoke test in a fresh environment: mola-cli --help, icp-run --help, mm-info --help, mola-yaml-parser --help work; ldd finds every library; mola-cli --list-modules loads 12 modules (BridgeROS2, MolaViz, Rosbag2Dataset, KeyframePointCloudMap, …) without any environment variable set; import mrpt_msgs.msg, from mrpt import poses, import mola_msgs.srv work. That was before the macOS commits; those change Linux only by the extra AMENT_PREFIX_PATH plugin search in mp2p_icp_core (the __APPLE__ branches and size_t→uint64_t are the same code there), and a Linux rebuild with them is still to do.
  • lyrical, osx-arm64: the same 231-recipe closure with recipe tests. mola-cli --list-modules loads the module libraries (bridge_ros2, the input_* modules, metric_maps, relocalization, viz; mola_kernel/launcher/yaml are linked directly), --rtti-list-all shows the same 13 mola:: classes as on Linux, the Python imports work, and otool -L shows only @rpath/system libraries. Not run: opening a window (nanogui on macOS isn't tested upstream), SLAM on a dataset.
  • jazzy, osx-arm64: the same 231-recipe closure (MRPT 3.4.0, mp2p_icp 3.0.0, MOLA 3.3.1) with recipe tests. mola-cli --list-modules loads 9 module libraries as on lyrical, --rtti-list-all shows the 13 mola:: classes, libmrpt_gui.dylib links libwx_baseu-3.3 and libQt5Widgets, and mrpt_msgs, mola_msgs.srv and mrpt.gui import.
  • jazzy, linux-64: the mola closure with recipe tests, on top of the jazzy sync and the other ports (a build host with a GPU and some system -dev packages, worked around locally). mrpt_gui's host environment solves as predicted (qt-main 5.15.15, gstreamer 1.26.11, wxwidgets 3.2.8.1). Smoke test in a fresh environment: mola-cli --list-modules lists the module libraries, --rtti-list-all shows the 13 mola:: classes, import mrpt_msgs.msg, mola_msgs.srv and from mrpt import poses work, and libmrpt_gui.so resolves libwx_baseu-3.2 and libQt5Widgets.
  • humble, osx-arm64: the mola closure (MOLA 3.3.1, MRPT 3.5.0) with recipe tests; smoke test as on jazzy: 9 module libraries, the 13 mola:: classes, the Python imports; libmrpt_gui links wxWidgets 3.3 and Qt 5.
  • rolling, osx-arm64: the mola closure (MOLA 3.3.2, MRPT 3.5.2) with recipe tests; the same smoke test passes (libmrpt_gui links wxWidgets 3.3, no Qt).
  • humble, linux-64: the mola closure with recipe tests; smoke test: the module libraries are found, 13 mola:: classes, Python imports; libmrpt_gui.so resolves wxWidgets 3.2 and Qt 5.
  • rolling, linux-64: the mola closure with recipe tests, incl. the new mola-cli --rtti-list-all test.

CI (run): green on humble, jazzy, lyrical and rolling, all platforms. osx-64 needed mrpt_common to compile the *.SSE2.cpp-style sources without the precompiled header (clang rejects a PCH built without -msse2; shared/patch/ros2-mrpt-common.patch). The syncs it was prepared on are merged.

🤖 Generated with Claude Code

Tobias-Fischer and others added 12 commits October 19, 2026 11:24
mola_launcher, mp2p_icp_core/viz and mola_metric_maps find_package(CLI11)
for their command-line tools; the key was unmapped, so the dependency was
dropped and configure failed. gz_utils_vendor and ros_gz_sim also declare
it and pick it up now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- mrpt_common calls find_package(ament_cmake) when ROS_VERSION=2, but its
  package.xml (build_type cmake) does not declare it.
- mrpt_gui links libwx_*; the wxwidgets/wx-common keys map to wxpython,
  so wxwidgets was only a transitive host dependency and its (weak)
  run_exports never reached the run requirements (libmrpt_gui.so and
  libmola_viz.so then failed to load).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
find_file() for the fonts in 3rdparty/nanogui/resources is re-rooted
under CMAKE_FIND_ROOT_PATH by the conda toolchain flags, so the source
tree files are never found. Search them with NO_CMAKE_FIND_ROOT_PATH.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The static vendor library's GLFW/OpenGL3 backends call dlopen()/dlsym(),
which live in libdl on the glibc 2.28 sysroot; mp2p_icp_viz's mm-viewer
failed to link.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mola-cli only searches MOLA_MODULES_LIB_PATH and LD_LIBRARY_PATH for
module libraries; neither is set in a conda/pixi environment, so no
module was ever loaded. Also search <prefix>/lib for each
AMENT_PREFIX_PATH entry, and skip *__rosidl_* libraries (mola_msgs), which
are never modules and whose Python ones cannot be dlopen()ed from a
non-Python process.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Requested in #106. On
lyrical this is MOLA 3.3.0 on MRPT 3 (mrpt3-release 3.3.1) and
mp2p_icp 3.0.0 (mp2p_icp_core/mp2p_icp_viz), all released in the
snapshot.

Co-authored-by: Wolf Vollprecht <885054+wolfv@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Grid::operator=(Grid&&) move-assigns a Bonxai::Mask, which has const
members and so no assignment operator. GCC never instantiates the
operator, clang rejects it at definition. Re-construct the mask in place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MRPT turns MRPT_WITH_NANOGUI off by default on Apple, which drops
CDisplayWindowGUI; mola_viz requires it unconditionally. nanogui builds
against GLFW and OpenGL.framework there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- load_plugin(): use dlopen() on Apple too (it only did under __unix__,
  so macOS fell into the Windows LoadLibrary() branch), map the usual
  "lib<name>.so" plugin names to .dylib there, and also search
  <prefix>/lib for each AMENT_PREFIX_PATH entry (conda environments do
  not set LD_LIBRARY_PATH).
- Serialize std::size_t values as uint64_t: MRPT's CArchive only accepts
  fixed-width integers and size_t is unsigned long, not uint64_t, on
  macOS. No change on Linux, where the two are the same type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
libcfgpath calls FSFindFolder()/FSRefMakePath() on Apple; mm-viewer and
icp-log-viewer failed to link.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MolaDLL_Loader only used dlopen() under __unix__, which Apple clang does
not define, so macOS took the Windows LoadLibrary() branch. Use dlopen()
on Apple too and look for .dylib modules there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The whole MOLA / MRPT 3 / mp2p_icp tree builds on osx-arm64 with the
previous fixes, and mola-cli loads all modules. Windows not tried yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Tobias-Fischer Tobias-Fischer changed the title Add MOLA on MRPT 3 (Linux) Add MOLA on MRPT 3 (Linux, macOS) Oct 19, 2026
Tobias-Fischer and others added 3 commits October 19, 2026 14:21
…5.15

These distributions map Qt to qt-main 5.15, whose builds need gstreamer
<1.27 on Linux, while the pinned wxwidgets 3.3.3 needs gstreamer 1.28, so
mrpt_gui's host environment (shared: add_host wxwidgets) could not be
solved. A version spec bypasses the variant pin: on linux-64 the solver
now takes wxwidgets 3.2.8.1 (with wxpython 4.2.4, which the wx rosdep
keys map to), and its run_exports still reach the run requirements.
lyrical and rolling (qt6-main) keep the shared entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…used [skip ci]

showErrorMessage() only uses wx when Qt is not available, but the file
includes WxUtils.h whenever wx is found. With Qt 5 (jazzy, humble) on
macOS, the wx and Qt headers clash: "typedef 'NSData' cannot be referenced
with the 'struct' specifier". No change on Linux or with Qt 6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…skip ci]

Turns the local checks of this PR into a recipe test, so later rebuilds keep them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Tobias-Fischer

Copy link
Copy Markdown
Collaborator Author

Human Tobi: looks good to go once the sync PRs are in

@Tobias-Fischer Tobias-Fischer added build:humble PR build: build only humble (with other build:<distro> labels: only those) build:jazzy PR build: build only jazzy (with other build:<distro> labels: only those) build:lyrical PR build: build only lyrical (with other build:<distro> labels: only those) labels Oct 24, 2026
Tobias-Fischer and others added 8 commits October 25, 2026 07:32
Select mola on every platform; mola_launcher searches <prefix>/bin (where
Windows DLLs are) of each AMENT_PREFIX_PATH entry on Windows, and the
mola-cli recipe test runs on Windows as well.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Its exported targets carry the eigen include directory there, so
mola_traj_tools (no eigen host dependency of its own) failed to configure.
Evict mrpt_math from the PR cache so it is rebuilt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Include windows.h, report GetLastError() instead of dlerror(), and cast the
stored handle back to HMODULE for FreeLibrary(). Reset evict_cache: the
mrpt_math rebuild has happened.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- mola_launcher: return fs::path::string() (no implicit conversion with
  MSVC's wchar_t paths).
- mp2p_icp_core: load plugins with LoadLibraryA (windows.h, GetLastError()),
  map "lib<name>.so" to "<name>.dll", search <prefix>/bin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without exports MSVC writes no import library and its test executable
cannot link (LNK1181).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mola_bridge_ros2 includes windows.h (via rclcpp) before mola_kernel's
DiagnosticsProvider.h, whose DiagnosticLevel::ERROR then fails to parse.
Evict mola_kernel from the PR cache so it is rebuilt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MOLA_NARG/VFUNC passed __VA_ARGS__ on as a single argument with MSVC, so
YAML_LOAD_OPT(...) in mola_bridge_ros2 did not resolve. Rescan through an
expansion macro. Evict mola_yaml from the PR cache.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tobias-Fischer and others added 3 commits October 25, 2026 09:39
BridgeROS2.cpp exceeds the object file section limit (C1128).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The release source has no 3rdparty/ with MRPT's bundled static GLEW, so
opengl_api.h failed with 'Cannot open include file: GL/glew.h' (C1083).
Use conda-forge's GLEW (a DLL, so without GLEW_STATIC) and leave out the bundled
glext.h, which glew.h covers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Tobias-Fischer Tobias-Fischer added the build:win PR build: only the win platforms (remove for a full build before merging) label Oct 25, 2026
Tobias-Fischer and others added 2 commits October 25, 2026 11:52
The exported targets (mrpt_opengl-targets.cmake) listed GLEW::GLEW, which
mrpt_gui's find_package(mrpt_opengl) didn't define. Linked privately like
MRPT's bundled GLEW; ci.yaml evicts the cached mrpt_opengl (reset before merging).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e comment)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Tobias-Fischer Tobias-Fischer added the build:rolling PR build: build only rolling (with other build:<distro> labels: only those) label Oct 25, 2026
Tobias-Fischer and others added 8 commits October 25, 2026 12:19
windows.h comes without commdlg.h here (WIN32_LEAN_AND_MEAN), so nanogui's
file dialog failed: 'OPENFILENAMEW': undeclared identifier (C2065).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The ROS build scripts set NOGDI (CL=/DNOGDI=1), which keeps GDI's types out of
windows.h; commdlg.h, for nanogui's file dialog, needs them ('lpLogFont':
unknown override specifier, C3646).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Its wxWidgets sources need GDI too (glcanvas.h's PIXELFORMATDESCRIPTOR),
not only nanogui's file dialog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nanogui/opengl.h includes glad/glad.h when NANOGUI_GLAD is set (the Windows
default), but only the GLFW and nanovg headers were installed, so mola_viz
failed with C1083. ci.yaml: evict mrpt_gui instead of the already rebuilt
packages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mola_viz links VizInterface::BACKEND_NANOGUI, a static data member that
CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS doesn't export (LNK2019). C++17 inline
variables need no exported symbol. ci.yaml: evict mola_kernel instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Like mrpt_opengl: the release source has no bundled GLEW, so CImGuiSceneView's
framebuffer calls (__glewBindFramebuffer, ...) were unresolved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r on Windows

- mrpt_imgui: CImGuiSceneView.h calls GL extension functions inline, so
  mp2p_icp_viz failed to link __glewBindFramebuffer: GLEW is now in its
  link interface (the import library by path once installed).
- mola_metric_maps: MSVC requires capturing the constexpr local used in
  voxelKey()'s lambda (C3493); static needs no capture.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The keyframe map test uses POSIX setenv()/unsetenv() (and a constexpr local
MSVC requires capturing). ci.yaml: evictions reset (rebuilt).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Tobias-Fischer Tobias-Fischer removed the build:win PR build: only the win platforms (remove for a full build before merging) label Oct 25, 2026
@Tobias-Fischer Tobias-Fischer changed the title Add MOLA on MRPT 3 (Linux, macOS) Add MOLA on MRPT 3 Oct 25, 2026
Tobias-Fischer and others added 2 commits October 25, 2026 16:05
mrpt_tfest failed on osx-64: its se2_l2.SSE2.cpp gets -msse2, and clang
rejects the target's precompiled header, built without it. GCC doesn't
check this.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

ABI check (linux-64)

About this check

Each package this pull request built, compared with its newest released build (tools/abi_check.py, libabigail):

  • compatible / additions: the package can be bumped on its own;
  • soname / incompatible: the packages that depend on it need a rebuild (build number bump) in the same pull request.

Exported symbols are compared (the released packages are stripped, so struct layouts aren't); unchanged installed headers rule out layout and inline changes, changed ones are listed for review. Dependents to rebuild are the released ones linking to a changed library. A changed pin is part of the comparison.

@Tobias-Fischer
Tobias-Fischer marked this pull request as ready for review October 25, 2026 10:36
…ncy everywhere

- nanogui (in mrpt_gui) links conda-forge's glad DLL on Windows instead of
  compiling its bundled glad; its users link glad.lib through mrpt_gui's
  interface. The install of the bundled glad headers is gone.
- mrpt_math run-depends on eigen on every platform: its public headers
  include Eigen, and eigen-abi-devel's run_exports only add eigen-abi.

ci.yaml: evict mrpt_math, mrpt_gui and the packages built against mrpt_gui's
glad (mola_viz, mp2p_icp_viz); reset before merging.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Tobias-Fischer
Tobias-Fischer enabled auto-merge (squash) October 25, 2026 11:01
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Tobias-Fischer
Tobias-Fischer enabled auto-merge (squash) October 25, 2026 11:32
@Tobias-Fischer
Tobias-Fischer merged commit ff56026 into main Oct 25, 2026
30 checks passed
@Tobias-Fischer
Tobias-Fischer deleted the ports/mola branch October 25, 2026 12:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build:humble PR build: build only humble (with other build:<distro> labels: only those) build:jazzy PR build: build only jazzy (with other build:<distro> labels: only those) build:lyrical PR build: build only lyrical (with other build:<distro> labels: only those) build:rolling PR build: build only rolling (with other build:<distro> labels: only those)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Package request: MOLA and MRPT 3

1 participant