3. Building

RTI nano-client can be easily compiled for most target platforms using CMake.

The most notable exception is the Arduino SDK, which is supported via the Arduino IDE, and the PlatformIO build system.

When building with CMake, it is recommended to use build target install to trigger the generation of all build artifacts, and then copy them into single, better organized, directory (by default: <build-dir>/install).

This makes it easier to pick up the library from other projects, by consolidating all header files and libraries into a single location.

Additionally, the build process will generate CMake Config files which trivialize the inclusion of the library in any CMake build using CMake’s find_package() function.

3.1. Building the C API with CMake

The C API can be compiled by building the repository’s root directory. For example:

# Create a build directory and enter it
mkdir build && cd build

# Run cmake to configure build
cmake /path/to/nano-client

# Call native build tool
cmake --build . --target install

3.2. Building the C++ API with CMake

The C++ API can be compiled by building directory extras/nano-client-cpp. The C API will also be automatically built.

E.g.:

# Create a build directory and enter it
mkdir build && cd build

# Run cmake to configure build
cmake /path/to/nano-client/extras/nano-client-cpp

# Call native build tool
cmake --build . --target install

3.3. Building with the Arduino IDE

After generating and installing the Arduino Package (see Arduino Package), you can enable RTI nano-client in your sketch by including header file Nano.h:

#include <nano_client_arduino.h>

3.4. Building with PlatformIO

After installing the Arduino Package as described in PlatformIO Installation, you can enable RTI nano-client by including its main header file in your application:

#include <nano_client_arduino.h>

This #include should allow PlatformIO’s library manager to detect the library and include it in the build.

You can also explicitly enable RTI nano-client in your platformio.ini file by adding it to your environment’s lib_deps entry:

[env:MyEnv]
lib_deps = nano-client-arduino

3.5. Cross-compilation with CMake

3.5.1. Raspberry Pi

#
# This toolchain file can be used to cross-compile RTI nano-client for
# Raspberry Pi.
#
# Make sure that the following variables are set in your shell's
# environment:
#
#   - RPI_TOOLS_DIR : clone of https://github.com/raspberrypi/tools
#
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)

# This toolchain can be used for both RPi2 and RPi3.
# Might need a different toolchain for RPi4/64bit
set(RPI_TOOLCHAIN_DIR
    $ENV{RPI_TOOLS_DIR}/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian)

set(CMAKE_C_COMPILER   ${RPI_TOOLCHAIN_DIR}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${RPI_TOOLCHAIN_DIR}/bin/arm-linux-gnueabihf-g++)

list(APPEND CMAKE_FIND_ROOT_PATH      ${RPI_TOOLCHAIN_DIR})

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

# Explicitly link rt library to nanocore library
set(NANO_CORE_EXTRA_LIBS            rt)

Save the previous block in a file named rpi_toolchain.cmake and build RTI nano-client with the following snippet:

# Clone RPi build tools and export their location as RPI_TOOLS_DIR
git clone https://github.com/raspberrypi/tools
export RPI_TOOLS_DIR=$(pwd)/tools

# Create a build directory and enter it
mkdir build-rpi && cd build-rpi

# Configure build using the custom toolchain. Optional: build examples.
cmake /path/to/nano-client -DCMAKE_TOOLCHAIN_FILE=rpi_toolchain.cmake \
                           -DENABLE_EXAMPLES=ON

# Compile and copy to install location (./install)
cmake --build . --target install -- -j8

# Copy install tree to RPi home directory, e.g. with rsync:
rsync -ra ./install/nano pi@my-rpi:~/

3.6. CMake Build Options

This section provides information of variables that can be used to control the behavior of RTI nano-client’s CMake build script.

3.6.1. BUILD_EXECUTABLES

Description:

Build included executables (e.g. examples).

Accepted Values:

ON, OFF

Default Value:

ON

3.6.2. BUILD_LIBRARIES

Description:

Build included libraries.

Accepted Values:

ON, OFF

Default Value:

ON

3.6.3. BUILD_SHARED_LIBS

Description:

Standard CMake option which controls whether libraries and executables will be linked statically or dynamically.

Accepted Values:

ON, OFF

Default Value:

OFF

3.6.4. CMAKE_BUILD_TYPE

Description:

Standard CMake option which controls the type of libraries and executables to build.

Accepted Values:

"Release", "Debug", "RelWithDebInfo", "MinSizeRel"

Default Value:

Release

3.6.5. CMAKE_INSTALL_PREFIX

Description:

Standard CMake option which controls the type of libraries and executables to build.

Accepted Values:

A valid path in CMake syntax (i.e. using forward-slashes / only).

Default Value:

${CMAKE_CURRENT_BUILD_DIR}/install

3.6.6. ENABLE_ARDUINO

Description:

Include additional code required to support the Arduino SDK.

Accepted Values:

ON, OFF

Default Value:

OFF

3.6.7. ENABLE_EXAMPLES

Description:

Include examples (copy to install directory, and optionally build them if BUILD_EXECUTABLES is also enabled).

Accepted Values:

ON, OFF

Default Value:

OFF

3.6.8. ENABLE_TRANSPORT_ALL

Description:

Include all available transport plugins.

Accepted Values:

ON, OFF

Default Value:

ON

3.6.9. ENABLE_TRANSPORT_SERIAL

Description:

Include Serial transport plugins.

Accepted Values:

ON, OFF

Default Value:

ON

3.6.10. ENABLE_TRANSPORT_UDPV4

Description:

Include UDPv4 transport plugins.

Accepted Values:

ON, OFF

Default Value:

ON

3.6.11. INSTALL_SOURCE

Description:

Export source files to install location.

Accepted Values:

ON, OFF

Default Value:

OFF

3.7. Generated Libraries

The following table summarizes the libraries that will be generated by the build process. Each library is associated with a CMake target (scoped within the nano:: namespace) which is configured so that the library can be easily linked using target_link_libraries(<my-tgt> [PRIVATE|PUBLIC|INTERFACE] <lib-tgt>) (if an application or library is also built using CMake).

The names of the generated library files are generated from the base target names (without the namespace prefix) plus an optional suffix, which depends on whether the library is a static one (z), and whether it was built using the "Debug" configuration (d).

For example, target nano::nanoclient will generate libnanoclientz.a (or libnanoclientz.lib on Windows) when built into a static library using "Release" configuration, and libnanoclientzd.a (libnanoclientzd.lib on Windows) when built with "Debug".

Similarly, the generated file will be named libnanoclient.so (or libnanoclient.dll on Windwos) when built into a dynamic library in "Release" configuration, and libnanoclientd.so (or libnanoclientd.dll on Windows) with "Debug".

3.7.1. nano::nanoclient

Description:

RTI nano-client C API

Dependencies:

nano::nanocore

3.7.2. nano::nanoclientudpv4

Description:

Wrapper library which links both the C API and the UDPv4 transport plugin.

Dependencies:

nano::nanoclient, nano::nanotransportudpv4

3.7.3. nano::nanoclientserial

Description:

Wrapper library which links both the C API and the Serial transport plugin.

Dependencies:

nano::nanoclient, nano::nanotransportserial

3.7.4. nano::nanocore

Description:

Core XRCE functionality shared with RTI nano-agent.

Dependencies:

None

3.7.5. nano::nanotransportserial

Description:

Serial transport plugin.

Dependencies:

nano::nanocore

3.7.6. nano::nanotransportudpv4

Description:

UDPv4 transport plugin.

Dependencies:

nano::nanocore

3.7.7. nano::nanoarduinoc

Description:

C wrapper for some of the C++ Arduino SDK functionalities. Built only if ENABLE_ARDUINO is enabled.

Dependencies:

Arduino SDK

3.7.8. nano::nanocppclient

Description:

RTI nano-client C++ API.

Dependencies:

nano::nanocppclient

3.7.9. nano::nanocpptransportserial

Description:

C++ wrapper for the Serial transport plugin.

Dependencies:

nano::nanocppclient nano::nanotransportserial

3.7.10. nano::nanocpptransportudpv4

Description:

C++ wrapper for the UDPV4 transport plugin.

Dependencies:

nano::nanocppclient nano::nanotransportudpv4

3.8. Alternative build systems

RTI nano-client can be easily embedded into any existing C/C++ project by including the library’s source files in the project’s compilation unit.

This can be useful when CMake is not used to build the project.

3.8.1. Exporting Source with CMake

The CMake build script can also be used to copy RTI nano-client’s source files into a single location, without compiling them.

Use variables BUILD_LIBRARIES, and INSTALL_SOURCE to control this behavior. For example, to export both the C and C++ APIs:

mkdir build && cd build
cmake /path/to/nano-client/extras/nano-client-cpp \
        -DBUILD_LIBRARIES=OFF \
        -DINSTALL_SOURCE=ON \
        -DCMAKE_INSTALL_PREFIX=/install/location
cmake --build . --target install
# source code copied to /install/location/src
# List out exported files (if make is available)
make -C /install/location/src

The installation location will contain a makefile which can be used to load variables that can be used to include RTI nano-client in a make-based build.

For every library included in RTI nano-client, the makefile contains the following variables (scoped by a prefix associated with the library):

  • $(LIBRARY)_DIR

  • $(LIBRARY)_SRC

  • $(LIBRARY)_INC

  • $(LIBRARY)_INC_PUB

  • $(LIBRARY)_DEFINES

  • $(LIBRARY)_LIBS

  • $(LIBRARY)_SRC_FILES

  • $(LIBRARY)_INC_FILES

  • $(LIBRARY)_INC_PUB_FILES

  • $(LIBRARY)_INC_DIRS

  • $(LIBRARY)_SOURCE_FILES

Libraries are identified by the following prefixes:

Library

Variable Prefix

nano::nanocore

NANO_CORE

nano::nanotransportserial

NANO_TRANSPORT_SERIAL

nano::nanotransportudpv4

NANO_TRANSPORT_UDPV4

nano::nanoarduinoc

NANO_ARDUINO_C

nano::nanoclient

NANO_CLIENT

nano::nanoclientserial

NANO_CLIENT_SERIAL

nano::nanoclientudpv4

NANO_CLIENT_UDPV4

nano::nanocppclient

NANO_CLIENT_CPP

nano::nanocpptransportudpv4

NANO_CLIENT_CPP_UDPV4

nano::nanocpptransportserial

NANO_CLIENT_CPP_SERIAL

3.8.2. Building exported source with Make

The following makefile could be used to build RTI nano-client and the UDPv4 transport plugin along with a simple C application:

# Base location where nano-client's source code was exported
# (i.e. CMAKE_INSTALL_PREFIX)
NANO_INSTALL_DIR    ?= /path/to/install/directory

include $(NANO_INSTALL_DIR)/src/makefile

MYAPP_SRC_FILES := MyApplication.c \
                $(NANO_CLIENT_SRC_FILES) \
                $(NANO_CORE_SRC_FILES) \
                $(NANO_TRANSPORT_UDPV4_SRC_FILES)

MYAPP_INC_FILES := MyApplication.h \
                $(NANO_CLIENT_INC_FILES) \
                $(NANO_CLIENT_INC_PUB_FILES) \
                $(NANO_CORE_INC_FILES) \
                $(NANO_CORE_INC_PUB_FILES) \
                $(NANO_TRANSPORT_UDPV4_INC_FILES) \
                $(NANO_TRANSPORT_UDPV4_INC_PUB_FILES)

MYAPP_INC_DIRS  := $(shell pwd) \
                $(NANO_CLIENT_INC_DIRS) \
                $(NANO_CORE_INC_DIRS) \
                $(NANO_TRANSPORT_UDPV4_INC_DIRS)

MYAPP_BUILD_DIR ?= $(shell pwd)/build

MYAPP_OBJ_FILES := $(MYAPP_SRC_FILES:%.c=$(MYAPP_BUILD_DIR)/%.o)

MYAPP_EXEC      ?= myapp

CC              ?= gcc

.PHONY : $(MYAPP_EXEC)

$(MYAPP_EXEC): $(MYAPP_BUILD_DIR)/$(MYAPP_EXEC)
    echo "Built executable: $<"

$(MYAPP_BUILD_DIR)/$(MYAPP_EXEC): $(MYAPP_OBJ_FILES)
    $(CC) -o $@ $<

$(MYAPP_BUILD_DIR)/%.o : %.c
    mkdir -p $$(dirname $@)
    $(CC) -o $@ -c $< -I $(MYAPP_INC_DIRS)

3.8.3. C API Manual Build

The C API and C transport plugins can be built by passing the following source files and include paths to your C compiler of choice:

  • Source Files:
    • src/**/*.c

    • core/src/**/*.c

  • Include Paths:
    • include

    • core/include

3.8.4. C++ API Manual Build

If building the C++ API, the following source files and paths should be included:

  • Source Files:
    • src/**/*.c

    • core/src/**/*.c

    • extras/nano-client-cpp/src/**/*.cpp

  • Include Paths:
    • include

    • core/include

    • extras/nano-client-cpp/include

3.8.5. Arduino-compatible API Manual Build

If building for the Arduino-compatible API, the following source files and paths should be included:

  • Source Files:
    • src/**/*.c

    • core/src/**/*.c

    • extras/nano-client-cpp/src/**/*.cpp

    • extras/arduino-c/src/*.cpp

  • Include Paths:
    • include

    • core/include

    • extras/nano-client-cpp/include

    • extras/arduino-c/include