Build ROS2 stack for iOS software development.
This valuable experience allows us to build and run ROS2 on Mac including graphical tools such as RVIZ as well (see below).
For the impatient: Instead of building ROS2 from source (see below), you can download our prebuilt libs and extract it.
Then make a symlink ros2
pointing to the extracted ros2_$PLATFORM
where we can find the ROS2 lib
and include
headers
ln -s PATH_TO_EXTRACTED_ros2_$PLATFORM ros2
You should of course change the symlink target when switching between building for real iPhone, simulator and Mac Catalyst. Now we can run the demo application which ports the official example: Run the app on two simulator instances, click on Start publishing on one and Start listening on the other.
Note: To run Mac Catalyst app on your macOS machine, you need to sign the app with your development signing certificate.
Main guides:
We are going to need
- CMake 3.23 until this issue is sorted out
- Python 3.11
- Xcode + Command Line tools
installed.
If you have other environment management such as Anaconda, remember to DEACTIVATE them. Then create and activate a Python virtual environment for ease of package installation
python3 -m venv ros2PythonEnv
source ros2PythonEnv/bin/activate
python3 -m pip install -r requirements.txt
To build for iOS simulator on Intel Macs, use the script build_ros2.sh
.
You might need to change some variable in the script to match your system.
Activate your Python environment then execute
# change iOS to iOS_Simulator if you want to test ROS2 on the iPhone simulator
source build_ros2.sh iOS
buildRos2Base
at the root of this repo (the script must be source
d there so you should clone this repo where you want to put your ROS2 installation).
The key command in the script is
colcon build --merge-install \
--cmake-force-configure \
--cmake-args \
-DCMAKE_TOOLCHAIN_FILE=$REPO_ROOT/cmake/iOS.cmake \
-DBUILD_TESTING=NO \
-DTHIRDPARTY=FORCE \
-DCOMPILE_TOOLS=NO \
-DBUILD_MEMORY_TOOLS=OFF \
-DRCL_LOGGING_IMPLEMENTATION=rcl_logging_noop
After my tons of failures, here is what went going on behind the above command:
-
The classical method to CMake for iOS simulator in my other projects such as LibGit2 is to set the appropriate
CMAKE_OSX_SYSROOT
andCMAKE_OSX_ARCHITECTURES
.Note: The right way to get
clang
to compile for iOS simulator is to set toCMAKE_C_FLAGS
andCMAKE_CXX_FLAGS
, namely-target x86_64-apple-ios-simulator -mios-version-min=14.0
together with-isysroot
to find the standard headers.However, that is not going to work here. The reason is because of the
***_vendor
packages which are proxy packages for 3rd party libraries such aslibyaml
: their CMake files fetch the library and passing to their CMake with the "right" options. Checking for examplelibyaml_vendor/CMakeLists.txt
reveals that it does NOT pass along all ourCMAKE_***
options except forCMAKE_C_FLAGS
and even forceBUILD_SHARED_LIBS=ON
. We need to pass along all desired options in-DCMAKE_TOOLCHAIN_FILE
and in that file, we set up all the desired CMake variables.Note: Even this is not going to be enough for some package such as
mimick_vendor
as it sets its internal variable_ARCH
BEFORE considering the toolchain file! -
BUILD_TESTING=NO
to disable all test packages, without this, we are going to need a ton of third party packages such asament/google_benchmark_vendor
,ament/uncrustify_vendor
,ament/googletest
,osrf/osrf_testing_tools_cpp
,ros2/performance_test_fixture
andros2/mimick_vendor
and account for a ton of CMake issues -
THIRDPARTY=FORCE
is to ask eProsima Fast-DDS to build and use its own dependencies (asio
, ...) so that we do not have to install it to the system with Homebrew -
COMPILE_TOOLS=NO
forFast-DDS
to NOT compile the fast discovery server executable. -
BUILD_MEMORY_TOOLS=OFF
is forfoonathan_memory
to disable buildingnodesize_db
program -
RCL_LOGGING_IMPLEMENTATION=rcl_logging_noop
is to select the logging backend forrcl_logging
. Here, I am usingnoop
one to avoid one more dependencyspdlog_vendor
. -
ROS2 depends significantly on dynamic linking. Do NOT add
BUILD_SHARED_LIBS=NO
, contrary to my other project LLVM where building static libs is needed!
While there is an option, namely RoboStack, to install ROS2 for macOS without having to build it from source, their prebuilt graphical tools such as rviz2
and gazebo
do not work.
So I find a way to build ROS2 from source to use on macOS (Intel only) as well. There is no need to disable SIP like the official instruction suggested. I also build pretty much all dependencies so Homebrew isn't needed either.
Unlike iOS, you first need to build the dependencies using build_deps.sh
and install XQuartz if you want to build MoveIt2.
Then similar to iOS,
source build_ros2.sh macOS
buildRos2Base
buildRviz2 # Run if you need Rviz2 (depends on base)
buildMoveIt2 # Run if you need MoveIt2 (depends on Rviz2)
See build_ros2.sh
for more details.
If you want to save yourself one full working day, you can use our release built using GitHub Action.
Note: We did not manage to build native ROS2 for ARM64 Mac but you can still use the Intel version thank to Rosetta 2.
In that case, you will need to install x86_64
version of Python.
- If you download the file from a browser, it will be put in quarantine so you need to
xattr -d com.apple.quarantine DOWNLOADED_FILE
before extraction. - To avoid that, you could open the terminal and do
instead.
baseUrl=https://github.com/light-tech/ROS2-On-iOS/releases/download/humble-1.4 curl -OL $baseUrl/deps_macOS.tar.xz \ -O $baseUrl/base_macOS.tar.xz \ -O $baseUrl/rviz2_macOS.tar.xz \ -O $baseUrl/moveit2_macOS.tar.xz \ -O $baseUrl/tutorials_macOS.tar.xz
After extracting the archives with tar xzf
and move the resulting ros2_macOS
to where you want (I usually rename it to ros2
and move it inside ~/usr
in my home folder along with the other Linux-based software), you need to fix hardcoded paths to match YOUR system as colcon
(or maybe CMake) unfortunately hardcoded a lot of paths (mostly concerning Python-based stuffs) in generated files such as CMake and package config files.
- To do that, run our script
fix_hardcoded_paths.sh
and you will be prompted with the relevant information. - The script is not exhaustive so you will need to manually fix the path such as the path to
python3
inbin/ros2
so you can runros2
command line such asros2 launch
andros2 topic list
.
Next, add this to your .zshrc
(appropriate modification required)
activateROS2() {
# So that ros2 can find the Python framework that you installed yourself.
# Change the path /Library/Frameworks appropriately to fit your system.
export DYLD_FRAMEWORK_PATH=/Library/Frameworks:$DYLD_FRAMEWORK_PATH
source PATH_TO_PYTHON_ENV/bin/activate
source PATH_TO_EXTRACTED_ROS2/moveit2/setup.zsh
# Add the location for ROS2 to find prebuilt dependencies
# Do this AFTER source setup.zsh because of https://github.com/colcon/colcon-zsh/issues/12
export DYLD_LIBRARY_PATH=PATH_TO_EXTRACTED_ROS2/deps/lib:$DYLD_LIBRARY_PATH
}
so that anytime you need ROS2, you can simply execute activateROS2
in the terminal.
Now you can start using ROS2 as usual.
- Try following the various tutorials such as the image transport tutorial and the URDF tutorial.
Define functions buildCMake
and buildColcon
in your .zshrc
such as
buildCMake() {
mkdir _build && cd _build
cmake -DCMAKE_INSTALL_PREFIX=$HOME/usr/ros2/deps -DCMAKE_PREFIX_PATH="$HOME/usr/ros2/deps" "$@" ..
cmake --build . --config Release --target install
}
buildColcon() {
colcon build --symlink-install --cmake-args -DCMAKE_PREFIX_PATH=$PATH_TO_EXTRACTED_ROS2/deps -DBUILD_TESTING=NO
}
to avoid typing (copying and pasting) long chains of shell commands in the terminal.