Skip to main content

RFrame Build Guide

Documentation entry point: Getting Started with RFrame.

1. Scope​

For C++ and Python users of an installed RFrame SDK, this guide explains:

  • How C++ projects consume RFrame through CMake.
  • Which components to declare and targets to link.
  • How to keep Python wheels consistent with native RFrame.
  • How to manage build-time, Python binding, and runtime environment variables.
  • Which RFrameExample files to reference.

Building the framework source and producing SDK packages are outside this guide's scope. See the RFrame Deployment Guide for package installation and runtime configuration, and the RFrame Development Guide for Channel APIs.

Reference project: the robby-r-frame-example deb package, installed at /opt/robby/RFrameExample/.

2. C++ integration​

2.1. Build prerequisites​

  • CMake 3.10 or later.
  • A compiler supporting C++17.
  • A matching r-frame SDK installed.
  • ROS 2 Humble installed and sourced when using ROS 2 message types.
  • The corresponding message workspace installed and sourced when using custom message types.
cmake --version
c++ --version
dpkg-query -W r-frame

For ROS 2 types, run this before CMake configuration:

source /opt/ros/humble/setup.bash
source /path/to/message_workspace/install/setup.bash # For custom types

Do not manually set AMENT_PREFIX_PATH or multiple ROS-related CMake paths; source the corresponding setup.bash instead.

The standard deb layout is shown below. RFrame libraries and underlying dependencies are installed under /usr/local/lib:

ContentsInstallation path
RFrame libraries libr_frame_*.so/usr/local/lib/
Bundled underlying libraries, such as libecdr.so/usr/local/lib/
C++ headers/usr/local/include/r, /usr/local/include/r_c
CMake package/usr/local/lib/cmake/r-frame/
Channel/Runtime plugin .so files (r-frame-plugin deb)/usr/local/lib/<plugin-name>/
Default plugin catalog/opt/robby/r-frame/config/plugins.json
Bundled third-party dependencies (fastcdr, rosidl typesupport, etc.)/opt/robby/r-frame/lib/third_party/
Python wheel/usr/local/lib/rframe/

find_package(r-frame) finds the configuration in /usr/local/lib/cmake/r-frame by default. The system dynamic linker resolves libraries in /usr/local/lib, so setting LD_LIBRARY_PATH is normally unnecessary.

Declare only the RFrame components directly used by your code, and link their namespaced targets:

cmake_minimum_required(VERSION 3.10)
project(my_rframe_app LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(r-frame REQUIRED COMPONENTS channel app log)

add_executable(my_rframe_app main.cpp)
target_link_libraries(my_rframe_app
PRIVATE
r::channel
r::app
r::log
)

Configure and build:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j4

The RFrame CMake package loads transitive dependencies of requested components. Do not repeat find_package calls or hardcode SDK-internal dependencies such as Boost, Protobuf, or jsoncpp in application projects.

2.3. Select components and targets​

Directly used in application codefind_package componentLink target
AppCoreappr::app
Logging APIlogr::log
ChannelManager、Hybrid Topic/RPCchannelr::channel

Target rules:

  • r::<component>: recommended.
  • r::frame: aggregate target; use only when directly using many modules.
  • r_frame_<component>: compatibility syntax for older projects, not preferred for new projects.

2.4. RFrameExample reference paths​

Example sources are delivered in the deb package. Paths below are relative to /opt/robby/RFrameExample/:

RequirementReference file
Minimal find_package and target usagesrc/find_package_usage/CMakeLists.txt
Logging dependency declarationsrc/log/CMakeLists.txt
AppCore/core dependency declarationsrc/core/CMakeLists.txt
Channel demo targetsrc/channel/CMakeLists.txt
Basic ChannelManager examplesrc/channel/quickstart/channel_manager_example.cpp
JSON configuration checkersrc/channel/config/channel_config_json_example.cpp
typed Hybrid Topicsrc/channel/typed/typed_channel_example.cpp
typed Hybrid RPCsrc/channel/typed/typed_rpc_example.cpp

To validate SDK integration, install the example deb and independently build the minimal Channel examples. They are standalone units; cloning the repository is unnecessary:

sudo apt install robby-r-frame-example
source /opt/ros/humble/setup.bash

cmake -S /opt/robby/RFrameExample/src/channel -B build/channel -DCMAKE_BUILD_TYPE=Release
cmake --build build/channel -j4 --target \
channel_manager_example channel_config_json_example \
typed_channel_example typed_rpc_example

typed_rpc_example depends on example_interfaces (sudo apt install ros-${ROS_DISTRO}-example-interfaces). If unavailable, this target is skipped automatically without affecting other examples.

2.5. Nonstandard installation paths​

For an SDK outside standard installation paths, specify it with CMAKE_PREFIX_PATH:

cmake -S . -B build \
-DCMAKE_PREFIX_PATH=/path/to/rframe/install \
-DCMAKE_BUILD_TYPE=Release
cmake --build build -j4

Separate multiple prefixes with semicolons:

cmake -S . -B build \
'-DCMAKE_PREFIX_PATH=/path/to/rframe/install;/usr/local'

Do not replace find_package with link_directories() or manually specified .so paths.

3. Python wheel compatibility​

3.1. Delivered components​

The r-frame deb includes:

  • native RFrame library;
  • System Python binding: /usr/lib/python3/dist-packages/rframe.
  • A wheel from the same build: /usr/local/lib/rframe/rframe-*.whl.

The wheel version comes from the same build tag as the deb. It supplies only Python bindings and cannot be used without the native r-frame from the same build.

3.2. System Python​

System Python directly uses the binding installed by the deb; no additional pip installation is required:

/usr/bin/python3 -c \
'import rframe; print(rframe.__file__, rframe.__version__, rframe.__build_tag__)'

3.3. Virtual environments or custom Python​

Install the wheel bundled with the deb into the virtual environment:

python3 -m venv --system-site-packages .venv
source .venv/bin/activate

ls /usr/local/lib/rframe/rframe-*.whl
python -m pip install --no-deps /usr/local/lib/rframe/rframe-*.whl
python -c \
'import rframe; print(rframe.__file__, rframe.__version__, rframe.__build_tag__)'

Keep --system-site-packages when using ROS 2 Python messages, allowing access to system-installed ROS 2 modules. It can be omitted for SHM-only use without system message packages.

Do not use these combinations:

  • Copying only the wheel without installing native r-frame.
  • Using a wheel from another release build.
  • Mixing site-packages between system Python, virtual environments, and Conda.
  • Pointing PYTHONPATH at RFrame source instead of using the official wheel.

3.4. Check version consistency​

dpkg-query -W -f='${Version}\n' r-frame
python -c \
'import rframe; print(rframe.__version__, rframe.__build_tag__)'

__build_tag__ should match the installed deb's build. PEP 440 wheel versions and Debian versions may differ in punctuation; compare the main version, rc/dev number, and build timestamp.

3.5. Python example references​

Paths below are relative to /opt/robby/RFrameExample/ in the deb installation:

RequirementFile
Loggingpython/log_example.py
typed Hybrid Topicpython/typed_channel_interop.py
Hybrid RPC, JSON mapping, C++ interoperabilitypython/rpc_interop.py

See the RFrame Development Guide for running these examples.

4. Environment variables and paths​

4.1. Variable categories​

Variable or environmentStageIntended usage
CMAKE_PREFIX_PATHC++ configureSet only for nonstandard SDK installation paths
ROS 2 setup.bashC++ configure / Python runtimeSource when using ROS 2 types or backends
Message workspace setup.bashC++ configure / Python runtimeSource when using custom messages or services
RFRAME_C_API_LIBPython native bindingNonstandard native library paths or diagnosis only
LD_LIBRARY_PATHRuntime diagnosisUnset for standard deb installations; temporary nonstandard SDK validation only
PYTHONPATHPython importUnset for production installation; use deb or wheel bindings
RFRAME_CONFIG_PATHApplication runtimeSelect global rframe.json; see the deployment guide
RFRAME_LOG_LEVELApplication runtimeOverride the global log level; see the deployment guide

4.2. RFRAME_C_API_LIB​

Python bindings use the native C API library. With a standard deb installation, the dynamic linker should find it automatically; no variable is needed.

Specify it explicitly only when validating a nonstandard SDK:

export RFRAME_C_API_LIB=/path/to/libr_frame_c_api.so
python -c 'import rframe; print(rframe.__file__)'

The variable must point to a library from the same build as the wheel. Unset it afterwards:

unset RFRAME_C_API_LIB

4.3. LD_LIBRARY_PATH​

Standard deb installations place RFrame and its underlying libraries in /usr/local/lib (see §2.1). System dynamic-linker configuration resolves them automatically; application code should not require LD_LIBRARY_PATH. Set it temporarily only for nonstandard SDK validation:

export LD_LIBRARY_PATH=/path/to/rframe/install/lib:${LD_LIBRARY_PATH:-}
ldd build/my_rframe_app

Do not add this variable to production startup scripts to conceal mixed SDK installations.

4.4. Runtime variables​

RFRAME_CONFIG_PATH and RFRAME_LOG_LEVEL do not affect CMake or wheel installation. They apply only at application runtime; see the RFrame Deployment Guide.

5. Validate an application project​

5.1. C++​

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j4
ldd build/my_rframe_app

Confirm:

  • CMake finds r-frame in the intended SDK.
  • Compilation and linking succeed.
  • ldd resolves RFrame and dependencies from the same installation.
  • ROS 2 type support comes from the intended sourced workspace.

5.2. Python​

python -c \
'import rframe; print(rframe.__file__, rframe.__version__, rframe.__build_tag__)'

Confirm:

  • The import path belongs to the intended system Python or virtual environment.
  • The wheel build tag matches the native deb.
  • The standard installation does not depend on source-code PYTHONPATH.
  • RFRAME_C_API_LIB does not accidentally point to another SDK.

6. Troubleshooting​

6.1. CMake cannot find r-frame​

Check that the SDK is installed and that CMAKE_PREFIX_PATH points to the installation prefix containing lib/cmake/r-frame.

6.2. ROS 2 or custom types cannot be found​

Source ROS 2 and the message workspace again, remove the old application CMake cache, and reconfigure.

Inspect actual libraries with ldd. Clear incorrect CMAKE_PREFIX_PATH, LD_LIBRARY_PATH, and old build caches. Do not patch the problem with link_directories().

6.4. Python import or native library loading fails​

Check in order:

  1. The current Python interpreter.
  2. rframe.__file__;
  3. Whether the wheel comes from /usr/local/lib/rframe/.
  4. Whether native r-frame is installed with a matching version.
  5. Whether RFRAME_C_API_LIB incorrectly overrides the library path.