Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6095a79
Map the cli11 rosdep key to conda-forge cli11
Tobias-Fischer Oct 19, 2026
2f9a084
mrpt_common, mrpt_gui: add missing host dependencies
Tobias-Fischer Oct 19, 2026
d7a7a6f
mrpt_gui: find the bundled nanogui fonts outside the find root
Tobias-Fischer Oct 19, 2026
9d15651
mrpt_imgui_vendor: link CMAKE_DL_LIBS
Tobias-Fischer Oct 19, 2026
932ad74
mola_launcher: find modules in conda environments
Tobias-Fischer Oct 19, 2026
f115922
Select mola on Linux [skip ci]
Tobias-Fischer Oct 19, 2026
53ceab8
mrpt_maps: fix Bonxai Grid move assignment for clang
Tobias-Fischer Oct 19, 2026
11b8475
mrpt_gui: build the bundled nanogui on macOS too
Tobias-Fischer Oct 19, 2026
f072808
mp2p_icp_core: build and load plugins on macOS
Tobias-Fischer Oct 19, 2026
d1c9c53
mp2p_icp_viz: link CoreServices on macOS
Tobias-Fischer Oct 19, 2026
e5e3d5f
mola_launcher: load modules on macOS
Tobias-Fischer Oct 19, 2026
8ef8e58
Select mola on macOS too [skip ci]
Tobias-Fischer Oct 19, 2026
c233120
jazzy, humble: let mrpt_gui pick a wxwidgets compatible with qt-main …
Tobias-Fischer Oct 19, 2026
8af9ccd
mrpt_gui: don't include the wx headers in error_box.cpp when Qt 5 is …
Tobias-Fischer Oct 19, 2026
00a5373
mola: recipe test that mola-cli finds the modules and their classes […
Tobias-Fischer Oct 19, 2026
51cbdb4
Merge remote-tracking branch 'origin/main' into ports/mola
Tobias-Fischer Oct 24, 2026
c119e16
mola: try Windows too
Tobias-Fischer Oct 24, 2026
9e12a87
mola_launcher: mola-cli without unistd.h/sigaction on Windows
Tobias-Fischer Oct 24, 2026
c7d169e
mrpt_math: eigen as run dependency on Windows
Tobias-Fischer Oct 24, 2026
794ddfc
mola_launcher: load modules with LoadLibraryA on Windows
Tobias-Fischer Oct 24, 2026
a23576f
mola_launcher, mp2p_icp_core: Windows fixes
Tobias-Fischer Oct 24, 2026
3e04dcd
mrpt_libros_bridge: export all symbols on Windows
Tobias-Fischer Oct 24, 2026
2709f8d
mola_kernel: undefine windows.h's ERROR before DiagnosticLevel
Tobias-Fischer Oct 24, 2026
be7166d
mola_yaml: variadic macros for MSVC's traditional preprocessor
Tobias-Fischer Oct 24, 2026
644cce2
mola_bridge_ros2: /bigobj on MSVC
Tobias-Fischer Oct 24, 2026
c260493
Merge remote-tracking branch 'origin/main' into HEAD
Tobias-Fischer Oct 25, 2026
f41f14a
mrpt_opengl on Windows: conda-forge's GLEW
Tobias-Fischer Oct 25, 2026
4db7ddd
mrpt_opengl on Windows: link GLEW privately
Tobias-Fischer Oct 25, 2026
f5a21f2
ci.yaml: evict mrpt_opengl for real (the previous commit put it in th…
Tobias-Fischer Oct 25, 2026
4a3967a
mrpt_gui on Windows: nanogui includes commdlg.h
Tobias-Fischer Oct 25, 2026
7edf264
mrpt_gui on Windows: nanogui's common.cpp without NOGDI
Tobias-Fischer Oct 25, 2026
149f3bd
mrpt_gui on Windows: undefine NOGDI for the whole package
Tobias-Fischer Oct 25, 2026
7a49657
mrpt_gui on Windows: install nanogui's bundled glad headers
Tobias-Fischer Oct 25, 2026
5cbbb70
mola_kernel on Windows: VizInterface's backend names as inline variables
Tobias-Fischer Oct 25, 2026
92637f7
mrpt_imgui on Windows: link conda-forge's GLEW
Tobias-Fischer Oct 25, 2026
9a70772
mrpt_imgui: GLEW for its users too; mola_metric_maps: static constexp…
Tobias-Fischer Oct 25, 2026
7771910
mola_metric_maps on Windows: without its tests
Tobias-Fischer Oct 25, 2026
836ed4e
mrpt_common: SIMD-specific sources without the precompiled header
Tobias-Fischer Oct 25, 2026
ade3494
ci.yaml: reset the mrpt_common eviction (rebuilt)
Tobias-Fischer Oct 25, 2026
8ba8c09
mrpt_gui: conda-forge's glad on Windows; mrpt_math: eigen run depende…
Tobias-Fischer Oct 25, 2026
3961c4e
ci.yaml: reset the evictions (rebuilt)
Tobias-Fischer Oct 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions distros/humble/patch/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ mimick_vendor:
add_build: ["vcstool"]
moveit_visual_tools:
add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}"]
mrpt_gui:
# Overrides shared/: this distribution maps Qt to qt-main 5.15, whose builds need
# gstreamer <1.27, while the pinned wxwidgets (3.3.3) needs gstreamer 1.28. A version
# spec bypasses that pin, so the solver picks a wxwidgets that coexists with qt-main.
add_host: ["wxwidgets >=3.2", "${{ 'glad' if win }}"] # glad: as in shared/
nav2_constrained_smoother:
add_host: ["${{ 'openblas' if win }}"]
nav2_util:
Expand Down
5 changes: 5 additions & 0 deletions distros/jazzy/patch/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ mimick_vendor:
add_host: ["setuptools <81"]
moveit_visual_tools:
add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}"]
mrpt_gui:
# Overrides shared/: this distribution maps Qt to qt-main 5.15, whose builds need
# gstreamer <1.27, while the pinned wxwidgets (3.3.3) needs gstreamer 1.28. A version
# spec bypasses that pin, so the solver picks a wxwidgets that coexists with qt-main.
add_host: ["wxwidgets >=3.2", "${{ 'glad' if win }}"] # glad: as in shared/
nav2_constrained_smoother:
add_host: ["${{ 'openblas' if win }}"]
nav2_mppi_controller:
Expand Down
23 changes: 23 additions & 0 deletions shared/patch/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,29 @@ moveit_setup_framework:
add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}"]
moveit_setup_srdf_plugins:
add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}"]
mrpt_common:
# CMakeLists.txt calls find_package(ament_cmake) when ROS_VERSION=2 (set by ros_environment),
# but package.xml (build_type cmake) does not declare it
add_host: ["ros2-ament-cmake"]
mrpt_gui:
# links libwx_*; the wxwidgets/wx-common keys map to wxpython, so wxwidgets is only a
# transitive host dep and its (weak) run_exports never reach the run requirements
# Windows: nanogui links conda-forge's glad instead of its bundled copy (ros2-mrpt-gui.win.patch)
add_host: ["wxwidgets", "${{ 'glad' if win }}"]
mrpt_imgui:
# Windows: links conda-forge's GLEW like mrpt_opengl, also for its users (ros2-mrpt-imgui.win.patch)
add_host: ["${{ 'glew' if win }}"]
add_run: ["${{ 'glew' if win }}"]
mrpt_math:
# its public headers include Eigen, and its exported CMake targets (and mrpt_poses') carry
# the eigen3 include directory: users need the headers (eigen-abi-devel's run_exports only
# add eigen-abi), or dependents without their own eigen dependency fail to configure
add_run: ["eigen"]
mrpt_opengl:
# Windows: the release source has no bundled GLEW (ros2-mrpt-opengl.win.patch); users of
# opengl_api.h need GL/glew.h too
add_host: ["${{ 'glew' if win }}"]
add_run: ["${{ 'glew' if win }}"]
mujoco_ros2_control_plugins:
add_host:
- if: linux
Expand Down
15 changes: 15 additions & 0 deletions shared/patch/ros2-mola-bridge-ros2.win.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1002ccf..fc37b9a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -85,6 +85,10 @@ mola_add_library(
# Same for mrpt_libros_bridge
mola_version_to_hexadecimal(mrpt_libros_bridge_VERSION_HEX ${mrpt_libros_bridge_VERSION})
target_compile_definitions(${PROJECT_NAME} PRIVATE MRPT_ROS2_BRIDGE_VERSION=${mrpt_libros_bridge_VERSION_HEX})
+if(MSVC)
+ # error C1128: number of sections exceeded object file format limit
+ target_compile_options(${PROJECT_NAME} PRIVATE /bigobj)
+endif()
message(STATUS "Found: mrpt_libros_bridge_VERSION: ${mrpt_libros_bridge_VERSION} (${mrpt_libros_bridge_VERSION_HEX})")

if (gps_msgs_FOUND)
49 changes: 49 additions & 0 deletions shared/patch/ros2-mola-kernel.win.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
diff --git a/include/mola_kernel/interfaces/DiagnosticsProvider.h b/include/mola_kernel/interfaces/DiagnosticsProvider.h
index 9ee9be8..fb7423d 100644
--- a/include/mola_kernel/interfaces/DiagnosticsProvider.h
+++ b/include/mola_kernel/interfaces/DiagnosticsProvider.h
@@ -22,6 +22,12 @@
#include <string>
#include <vector>

+// windows.h (wingdi.h) defines ERROR, which breaks DiagnosticLevel::ERROR below
+// (the generated diagnostic_msgs headers do the same)
+#if defined(_WIN32) && defined(ERROR)
+#undef ERROR
+#endif
+
namespace mola
{
/** \addtogroup mola_kernel_interfaces_grp
diff --git a/include/mola_kernel/interfaces/VizInterface.h b/include/mola_kernel/interfaces/VizInterface.h
index e86f489..1d67359 100644
--- a/include/mola_kernel/interfaces/VizInterface.h
+++ b/include/mola_kernel/interfaces/VizInterface.h
@@ -147,10 +147,12 @@ class VizInterface
[[nodiscard]] virtual const std::string& gui_backend() const noexcept = 0;

/// Canonical backend name returned by MolaViz (nanogui).
- static const std::string BACKEND_NANOGUI; // defined in VizInterface.cpp as "nanogui"
+ // RoboStack: inline, so Windows DLLs using it need no exported data symbol
+ static inline const std::string BACKEND_NANOGUI = "nanogui";

/// Canonical backend name returned by MolaVizImGui (Dear ImGui).
- static const std::string BACKEND_IMGUI; // defined in VizInterface.cpp as "imgui"
+ // RoboStack: inline, so Windows DLLs using it need no exported data symbol
+ static inline const std::string BACKEND_IMGUI = "imgui";

/**
* \brief Installs or replaces the menu bar of a parent window.
diff --git a/src/interfaces/VizInterface.cpp b/src/interfaces/VizInterface.cpp
index 8b207c8..1caa66f 100644
--- a/src/interfaces/VizInterface.cpp
+++ b/src/interfaces/VizInterface.cpp
@@ -24,7 +24,5 @@ namespace mola

VizInterface::~VizInterface() = default;

-const std::string VizInterface::BACKEND_NANOGUI = "nanogui";
-const std::string VizInterface::BACKEND_IMGUI = "imgui";

} // namespace mola
\ No newline at end of file
70 changes: 70 additions & 0 deletions shared/patch/ros2-mola-launcher.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
diff --git a/src/MolaDLL_Loader.cpp b/src/MolaDLL_Loader.cpp
--- a/src/MolaDLL_Loader.cpp
+++ b/src/MolaDLL_Loader.cpp
@@ -24,7 +24,7 @@

#include <map>

-#if defined(__unix__)
+#if defined(__unix__) || defined(__APPLE__)
#include <dlfcn.h>
#endif

@@ -39,7 +39,9 @@
{
MRPT_TRY_START

-#if defined(__unix__)
+#if defined(__APPLE__)
+#define DLL_EXT "dylib"
+#elif defined(__unix__)
#define DLL_EXT "so"
#else
#define DLL_EXT "dll"
@@ -59,11 +61,14 @@
for (const auto& lib : lst)
{
if (lib.name.find("mola") == std::string::npos) continue; // skip
+ // ROS interface libraries (e.g. mola_msgs) are never MOLA modules, and the
+ // Python ones cannot be dlopen()ed from a non-Python process:
+ if (lib.name.find("__rosidl_") != std::string::npos) continue; // skip

// Already loaded?
if (loaded_lib_handled.count(lib.name) != 0) continue; // skip

-#if defined(__unix__)
+#if defined(__unix__) || defined(__APPLE__)
// Check if already loaded?
{
void* handle = dlopen(lib.wholePath.c_str(), RTLD_NOLOAD);
@@ -109,7 +114,7 @@
{
// printf("[mola-launcher] Unloading: %s\n",
// lib.second.lib_path.c_str());
-#if defined(__unix__)
+#if defined(__unix__) || defined(__APPLE__)
dlclose(lib.second.handle);
#else
FreeLibrary(lib.second.handle);
diff --git a/src/MolaLauncherApp.cpp b/src/MolaLauncherApp.cpp
--- a/src/MolaLauncherApp.cpp
+++ b/src/MolaLauncherApp.cpp
@@ -119,6 +119,18 @@
// do not filter these ones by *directory* name, since *filenames* will be
// filtered later on:
from_env_var_to_list("LD_LIBRARY_PATH", lib_search_paths_);
+
+ // conda/RoboStack environments do not set LD_LIBRARY_PATH: also search
+ // <prefix>/lib (<prefix>/bin for Windows DLLs) for every prefix in AMENT_PREFIX_PATH.
+ {
+ std::vector<std::string> prefixes;
+ from_env_var_to_list("AMENT_PREFIX_PATH", prefixes);
+#if defined(_WIN32)
+ for (const auto& prefix : prefixes) safe_add_to_list(prefix + "/bin", lib_search_paths_);
+#else
+ for (const auto& prefix : prefixes) safe_add_to_list(prefix + "/lib", lib_search_paths_);
+#endif
+ }
}

MolaLauncherApp::~MolaLauncherApp()
105 changes: 105 additions & 0 deletions shared/patch/ros2-mola-launcher.win.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
diff --git a/apps/mola-cli.cpp b/apps/mola-cli.cpp
index 2bd97ff..d77ceda 100644
--- a/apps/mola-cli.cpp
+++ b/apps/mola-cli.cpp
@@ -23,7 +23,11 @@
#include <mrpt/core/exceptions.h>
#include <mrpt/rtti/CObject.h>
#include <mrpt/system/filesystem.h>
+#if defined(_WIN32)
+#include <io.h> // _write()
+#else
#include <unistd.h> // write()
+#endif

#include <CLI/CLI.hpp>
#include <atomic>
@@ -48,7 +52,11 @@ void mola_signal_handler([[maybe_unused]] int s)
// raw write() to stderr. The actual shutdown (which logs, sleeps and joins
// threads) is done by the main thread as soon as spin() returns.
static const char msg[] = "\nTermination signal caught. Shutting down...\n";
+#if defined(_WIN32)
+ [[maybe_unused]] const auto n = ::_write(2, msg, sizeof(msg) - 1);
+#else
[[maybe_unused]] const auto n = ::write(STDERR_FILENO, msg, sizeof(msg) - 1);
+#endif

if (auto* app = theApp.load())
{
@@ -58,6 +66,11 @@ void mola_signal_handler([[maybe_unused]] int s)

void mola_install_signal_handler()
{
+#if defined(_WIN32)
+ // No sigaction() on Windows:
+ std::signal(SIGINT, &mola_signal_handler);
+ std::signal(SIGTERM, &mola_signal_handler);
+#else
struct sigaction sigIntHandler;

sigIntHandler.sa_handler = &mola_signal_handler;
@@ -71,6 +84,7 @@ void mola_install_signal_handler()
// the main MOLA loop keeps running, so the process never exits and lingers
// with its ROS 2 endpoints still advertised but no longer served.
sigaction(SIGTERM, &sigIntHandler, nullptr);
+#endif
}

// Default task for mola-cli: launching a SLAM system
diff --git a/src/MolaDLL_Loader.cpp b/src/MolaDLL_Loader.cpp
index ec376eb..6dcee68 100644
--- a/src/MolaDLL_Loader.cpp
+++ b/src/MolaDLL_Loader.cpp
@@ -26,6 +26,11 @@

#if defined(__unix__) || defined(__APPLE__)
#include <dlfcn.h>
+#elif defined(_WIN32)
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#include <windows.h> // LoadLibraryA(), FreeLibrary()
#endif

/** From internal_load_lib_modules() */
@@ -81,11 +86,17 @@ void internal_load_lib_modules(

void* handle = dlopen(lib.wholePath.c_str(), RTLD_LAZY);
#else
- HMODULE handle = LoadLibrary(lib.wholePath.c_str());
+ void* handle = LoadLibraryA(lib.wholePath.c_str());
#endif
if (handle == nullptr)
{
+#if defined(_WIN32)
+ const std::string err_str =
+ mrpt::format("LoadLibrary() error code %lu", static_cast<unsigned long>(GetLastError()));
+ const char* err = err_str.c_str();
+#else
const char* err = dlerror();
+#endif
if (!err) err = "(error calling dlerror())";
THROW_EXCEPTION(mrpt::format(
"Error loading module: `%s`\ndlerror(): `%s`", lib.wholePath.c_str(), err));
@@ -117,7 +128,7 @@ void internal_unload_lib_modules()
#if defined(__unix__) || defined(__APPLE__)
dlclose(lib.second.handle);
#else
- FreeLibrary(lib.second.handle);
+ FreeLibrary(static_cast<HMODULE>(lib.second.handle));
#endif
}
loaded_lib_handled.clear();
diff --git a/src/MolaLauncherApp.cpp b/src/MolaLauncherApp.cpp
index d939bfe..37be9fc 100644
--- a/src/MolaLauncherApp.cpp
+++ b/src/MolaLauncherApp.cpp
@@ -99,7 +99,7 @@ std::string relative_to_abs_path(
if (f.is_relative())
{
f = fs::path(*basePath) / f;
- return f;
+ return f.string(); // no implicit conversion on Windows (wchar_t paths)
}
else
return path;
28 changes: 28 additions & 0 deletions shared/patch/ros2-mola-metric-maps.win.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 775a066..073a5f8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -187,7 +187,8 @@ add_subdirectory(apps)
# -----------------------
# define tests:
enable_testing()
-add_subdirectory(tests)
+# RoboStack: not on Windows, the tests use POSIX setenv()/unsetenv()
+# add_subdirectory(tests)

# -----------------------------------------------------------------------------
# ROS2
diff --git a/src/KeyframePointCloudMap.cpp b/src/KeyframePointCloudMap.cpp
index 74b2701..1a38249 100644
--- a/src/KeyframePointCloudMap.cpp
+++ b/src/KeyframePointCloudMap.cpp
@@ -1864,7 +1864,8 @@ namespace
/// axis with a large centering offset, covering ~ +/-1e6 voxels per axis.
inline int64_t voxelKey(float x, float y, float z, double inv_voxel)
{
- constexpr int64_t kOffset = 1 << 20; // center the range around 0
+ // RoboStack: static, so the lambda below needn't capture it (MSVC requires that, C3493)
+ static constexpr int64_t kOffset = 1 << 20; // center the range around 0
const auto q = [inv_voxel](float c)
{ return static_cast<int64_t>(std::floor(static_cast<double>(c) * inv_voxel)) + kOffset; };
const int64_t ix = q(x);
22 changes: 22 additions & 0 deletions shared/patch/ros2-mola-yaml.win.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
diff --git a/include/mola_yaml/macro_helpers.h b/include/mola_yaml/macro_helpers.h
index 0f76953..cb7c4a4 100644
--- a/include/mola_yaml/macro_helpers.h
+++ b/include/mola_yaml/macro_helpers.h
@@ -48,7 +48,10 @@
// which corresponds to the actual argument count (up to 10 args supported).
// ---------------------------------------------------------------------------
#define MOLA_NARG(...) MOLA_NARG_I_(__VA_ARGS__, MOLA_RSEQ_N())
-#define MOLA_NARG_I_(...) MOLA_ARG_N(__VA_ARGS__)
+// MSVC's traditional preprocessor passes __VA_ARGS__ on as one argument unless
+// it is rescanned through another macro:
+#define MOLA_EXPAND_(x) x
+#define MOLA_NARG_I_(...) MOLA_EXPAND_(MOLA_ARG_N(__VA_ARGS__))

/** Picks the 11th argument - used internally by MOLA_NARG. */
#define MOLA_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
@@ -80,4 +83,4 @@
* @param func Base name of the macro family (without trailing digit).
* @param ... Arguments forwarded verbatim to the selected overload.
*/
-#define VFUNC(func, ...) MOLA_VFUNC(func, MOLA_NARG(__VA_ARGS__))(__VA_ARGS__)
+#define VFUNC(func, ...) MOLA_EXPAND_(MOLA_VFUNC(func, MOLA_NARG(__VA_ARGS__))(__VA_ARGS__))
Loading
Loading