Skip to content

CMake: cross-platform Webots controller build (macOS prebuilt vs Linux source) - #1046

Open
idesign0 wants to merge 8 commits into
cyberbotics:masterfrom
idesign0:master
Open

idesign0 wants to merge 8 commits into
cyberbotics:masterfrom
idesign0:master

Conversation

@idesign0

Copy link
Copy Markdown

Summary

This PR improves the CMake build of webots_ros2_driver to support both Linux and macOS environments:

  • Detect prebuilt /Applications/Webots.app on macOS and link against its libraries.
  • Add support for source builds on macOS (similar to Linux).
  • Use file(GLOB …) for Webots libraries instead of hardcoded list.
  • Refactor Python version detection (humble/iron → 3.10, others → 3.12).
  • Switch from yaml-cpp to yaml_cpp_vendor for consistency with ROS 2.
  • Install Python packages only if directories exist.
  • Conditional add_dependencies only when not using prebuilt Webots.
  • webots-controller script installation now uses ${WEBOTS_CONTROLLER_EXEC}.

Motivation

These changes allow webots_ros2_driver to build on:

  • Linux with Webots source build
  • macOS with prebuilt Webots.app

Notes

@traversaro — I would greatly appreciate your guidance and feedback here. :)

Testing

  • ✅ macOS (Apple Clang) with Webots.app 2025a (prebuilt)
  • ✅ Ubuntu 22.04 with source Webots

Comment thread webots_ros2_driver/CMakeLists.txt Outdated
idesign0 and others added 7 commits September 18, 2025 13:54
…ead of building in-tree

On macOS the in-tree webots/ copy has no proper .app layout, so building the controller /
vehicle / generic_robot_window libraries from source there is fragile (universal lipo build,
missing Contents/ dirs, java/python sub-builds). The official Webots macOS release already
ships all of them prebuilt and UNIVERSAL (x86_64+arm64) inside Webots.app/Contents/lib/controller.

Change the APPLE branch to resolve a prebuilt Webots.app into WEBOTS_HOME from, in order:
  1. $WEBOTS_HOME (a Webots you already have),
  2. /Applications/Webots.app,
  3. otherwise auto-download+cache the official webots-<ver>.dmg (cmake/fetch_webots_macos.sh:
     curl the release, hdiutil-mount, copy Webots.app to $HOME/.cache/webots/<ver> -- idempotent,
     override the cache dir with $WEBOTS_CACHE_DIR).
Pinned to R2025a. The Linux from-source path is unchanged. This gives a complete macOS solution
(the driver links the prebuilt controller/vehicle/window libs) and a runnable simulator.

Tested on macOS 15 (Apple clang): fetch_webots_macos.sh downloads+extracts idempotently; the
CMake resolve picks /Applications when present and the cache otherwise, and all of
libController/libCppController/libcar/libdriver/libgeneric_robot_window + include/webots/robot.h
resolve under the chosen WEBOTS_HOME.
…(macOS) path

When a prebuilt Webots is used (WEBOTS_HOME set -- the macOS path), the
include_directories() only added the Webots controller headers and Python, not
the package's own include/ dir. So Driver.cpp's #include
<webots_ros2_driver/PluginInterface.hpp> failed ('file not found'). The non-
prebuilt else() branch already lists include/; add it to the prebuilt branch too.

Compile-test: macOS arm64 (prebuilt Webots), Apple clang / Xcode 26.6, in the
idesign0/ros2_macOS layered CI (folded in from investigating run 34835664100).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
findVariance() tested `a < rawValue < b` (and the `>` mirror), which parses
as `(a < rawValue) < b` — comparing a bool (0/1) against b, not a range
check. Older compilers accepted it with a warning; clang 21 (Xcode 26)
rejects chained comparisons as an error:
  error: chained comparison 'X < Y < Z' does not behave the same as a
  mathematical expression [-Wparentheses]
Rewrite as proper bounds checks (a < rawValue && rawValue < b), preserving
the ascending/descending intent, so the lookup-table interpolation selects
the correct bracket.

Compile-tested on macOS (Apple clang 21, arm64): the corrected expression
compiles clean under -Wall -Wextra -Werror in isolation. Full colcon build
of webots_ros2_driver is blocked locally by the ros2 typesupport env.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…e `yaml-cpp`

target_link_libraries(driver ... yaml-cpp) passes the bare token `yaml-cpp`,
which CMake forwards to the linker as `-lyaml-cpp`. yaml_cpp_vendor builds
yaml-cpp 0.8.0, whose exported target is the namespaced `yaml-cpp::yaml-cpp`
(carrying IMPORTED_LOCATION); there is no plain `libyaml-cpp` on the default
macOS link path, so the link fails with `ld: library 'yaml-cpp' not found`.
Link the namespaced target instead (both the WEBOTS_LIB branch and the else
branch). Same fix already applied to autoware_map_loader in the workspace.

Compile-tested: macOS 15 / Apple clang 17, ROS 2 kilted workspace with
yaml_cpp_vendor building yaml-cpp 0.8.0 (exports yaml-cpp::yaml-cpp, verified
in the vendored lib/cmake/yaml-cpp config). Old behavior: `ld: library
'yaml-cpp' not found` at the webots_ros2_driver link step; with the namespaced
target the driver links clean. On humble (yaml-cpp 0.7.0, unnamespaced only)
the workspace's ci-yamlcpp-ns-alias patch fabricates yaml-cpp::yaml-cpp, so
this stays correct across distros.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…_robot_* symbols)

Ros2Control.cpp / Ros2ControlSystem.cpp call libController C symbols
(wb_robot_get_basic_time_step, wb_robot_get_time, ...). On the non-humble/jazzy
path the targets link only hardware_interface/controller_manager/rclcpp — not
webots_ros2_driver nor libController — and macOS does not chain DT_NEEDED, so the
symbols the driver links are not visible here -> "Undefined symbols for
architecture arm64: _wb_robot_get_*". Locate the Webots install
webots_ros2_driver already resolved (WEBOTS_HOME env, /Applications, or the
driver's ~/.cache/webots/<ver> download) and link its *CppController/*Controller
dylibs into both plugin libraries. APPLE-only; humble/jazzy use
ament_target_dependencies(webots_ros2_driver) and are untouched.

Compile-tested: macOS 15 / Apple clang; mirrors how webots_ros2_driver (which
builds cleanly) links ${WEBOTS_LIB}. The symbols resolve from the same
CppController dylib. Depends on webots_ros2_driver having populated WEBOTS_HOME
(it runs first).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants