Build and Package RobustOS SDK Application Projects

Build and package RobustOS SDK applications

Use the RobustOS SDK package Makefile to prepare source, cross-compile it for your device and install the runtime files into an RPK. This article also explains how to select a sample package and include the libraries your application needs.

Applies to: Applications built with the matching RobustOS SDK and device target. Package, helper and library availability depend on the SDK release. Confirm the target for the exact device; see the RobustOS SDK starting page.

Before sizing your package, review hardware platforms and SDK resources. Compare the installed application and dependencies with SDK Flash, and peak application memory with SDK RAM; total device capacity is not the application allocation.

Know which files the build system owns

Run SDK build commands in the SDK container, from /root/ROS-SDK. The following directories have different roles:

Directory or file Purpose
package/ Package Makefiles, package source or preparation instructions, and patches
tarball/ Compressed source archives used by packages
build_dir/target-<platform>/ Working build directories for packages being cross-compiled
bin/ Generated RPK output; discover the actual target subdirectory and filename after the build. In SDK 5.0.3, an r1510 target build can produce an r1520-prefixed file whose internal Platform field is r1510.
include/ Common Makefiles and scripts for configuring, building, and packaging
rules/ Platform-specific build rules
staging_dir/host/ Host tools required by the cross-build
staging_dir/target-<platform>/ Target-side cross-build files, including tools, binaries, libraries, and headers used during builds
Makefile and rules.mk SDK build entry point and shared rules

The include/ reference set includes check_uci.py, host-build.mk, python-package-2.7.mk, platform.mk, cmake.mk, image.mk, configure.mk, package.mk, quilt.mk, rpkg-build.sh, rstrip.sh, unpack.mk, and web_language_js_gen. Inspect the files shipped with your SDK when a package needs to customize a build stage. Their presence in one release is not a promise that every release contains the same helper set.

Keep maintained changes in the package/source location. Treat build_dir as the build working area, and retain the source changes needed to reproduce its contents. A target directory name describes a build target, not every model in a marketed product series.

Keep the two Makefile roles separate

The application's own Makefile knows how to compile its source. The SDK package Makefile supplies metadata, preparation steps, target configuration, and installation instructions for the RPK.

The Hello World package illustrates the include and evaluation order:

include $(TOPDIR)/rules.mk

PKG_NAME:=helloworld
PKG_VERSION:=1.0
PKG_DESC:=helloworld example

PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_UNPACK:=cp -rf src/* $(PKG_BUILD_DIR)
PKG_BUILD_PARALLEL:=1
PKG_BUILD_DEPENDS:=

include $(INCLUDE_DIR)/package.mk

define Package/Install
	$(INSTALL_DIR) $(1)/usr/bin/
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/usr/bin/
	$(INSTALL_DIR) $(1)/etc/sdk/
	$(INSTALL_BIN) files/sdk.sh $(1)/etc/sdk/$(PKG_NAME)
endef

$(eval $(call BuildPackage))

Keep lifecycle scripts in LF format; a CRLF script can package successfully but fail on the device. Keep actual tab characters at the beginning of recipe lines. $(1) in Package/Install is the package's destination tree. It is not a host filesystem root. In this example the executable will be installed as /usr/bin/helloworld and the lifecycle script as /etc/sdk/helloworld on the device.

The matching source Makefile uses the compiler passed by the build system:

helloworld:
	$(CC) helloworld.c -o helloworld

Use the SDK's package target from the SDK root to supply the target configuration:

make package/helloworld/install

The complete example and device execution check are in Environment preparation and the first application.

Select the package variables you need

Identify and prepare source

Variable Meaning
PKG_NAME For an application package, use a name without hyphens and shorter than 18 characters. SDK library packages can use different naming conventions; for example, azure-iot-sdk-c.
PKG_DESC Package description; shown in the device application list.
PKG_VERSION Package version
PKG_SOURCE Source archive filename stored in tarball/
PKG_BUILD_DIR Directory in which the package is compiled
PKG_UNPACK Optional replacement for the normal unpack command; use it when preparing local source instead of an archive

For a local-source package, the Hello World PKG_UNPACK copies src/* into $(PKG_BUILD_DIR). For an archive-based package, use the preparation pattern of a matching package in the installed SDK. Do not add a local-source override merely because the package has an archive.

Install and declare prerequisites

Variable Meaning
PKG_MAKE_INSTALL Set to 1 to call the source package's original make install, with its prefix set to PKG_INSTALL_DIR
PKG_INSTALL_DIR Optional install staging directory; defaults to PKG_BUILD_DIR/install_dir
PKG_BUILD_DEPENDS Optional list of packages that must be built before this package
PKG_INSTALL_DEPENDS Installation dependency used by packages to declare a requirement such as libstdc++

PKG_BUILD_DEPENDS describes build order. It does not, by itself, demonstrate that the required runtime files are present on the device. Inspect the package installation contents and the matching SDK dependency implementation when distributing libraries with an application.

The Hello World example also uses PKG_DESC and PKG_BUILD_PARALLEL. Preserve the working values when adapting it, and consult the installed package.mk for the variable behavior when customizing the package.

Override only the required build stage

Definition When to use it
Package/Install Copy the runtime files into the RPK destination represented by $(1)
Package/Install/Develop Install the headers and libraries needed to build other packages against this package; define it for a library package that exposes development files
Package/Configure Override the default configuration step when the source needs a particular script or configuration process
Package/Compile Override the compile step only when necessary; otherwise the default step calls make

Prefer adding arguments to CONFIGURE_ARGS when the default configure step can do the work. This keeps package-specific changes small and preserves the SDK's normal build sequence.

Append extra flags using the SDK variables, with values chosen for your source and target:

# Syntax reference: replace each placeholder before use.
CONFIGURE_ARGS += <configuration-arguments>
TARGET_CFLAGS += <target-C-compiler-flags>
TARGET_LDFLAGS += <target-linker-flags>
TARGET_CPPFLAGS += <target-preprocessor-flags>

These are syntax placeholders, not commands to paste unchanged. Avoid replacing the target compiler with the host compiler while adjusting flags. After a change, confirm the build log shows the intended target compilation and then locate the RPK generated by that build.

Package a C++ application with its runtime

A device must have the matching C++ runtime before it can run a dynamically linked C++ application. Do not assume libstdc++ is installed by default.

  1. In the SDK container, select the build target for the device.

  2. Build the runtime package from /root/ROS-SDK:

    make package/libstdc++/install
    
  3. Inspect the generated runtime package before installing it. For SDK 5.0.3 with the r1510 target, a roughly 1 KB libstdc++ RPK can contain only symbolic links without the library. Rebuild the runtime with the toolchain sysroot library directory shown below, then check that the resulting package contains the actual library.

    make package/libstdc++/install \
      TOOLCHAIN_LIB_DIR=/root/ROS-SDK/staging_dir/target-r1510/mips-24k-linux-gnu/mips-24k-linux-gnu/sysroot/lib
    
  4. Choose the matching release's supported distribution method: install libstdc++ as a separate application package, or package the required runtime with your application using the SDK's dependency mechanism.

  5. Build and export the application RPK, then verify installation and execution on the matching target device.

Keep the runtime, application, SDK toolchain, and target compatible. This step does not establish compatibility with a libstdc++ copied from another target or from the development host.

Find a useful SDK sample

Inspect the package/ directory in your actual SDK before choosing a starting point. The following catalogue explains the named examples; availability, exact directory names, hardware support, and cloud-service compatibility still depend on the release.

Package Starting point
sample_can Receive CAN-bus data and send it back to a peer
sample_https Fetch a Web URL and save its response content to a local file
sample_mqtt MQTT subscribe/publish using the Mosquitto library
sample_serial Open a serial port and exchange data with a peer
sample_dido Receive DI status and change DO behavior
sample_gps Obtain GPS position through the configuration/status interface
sample_shell Package an SDK application written in shell
sample_uci_upload Upload a file through an application configuration page
sample_uci Work with system/application status through the SDK interfaces
sample_cpp Build a C++ application
sample_sqlite SQLite usage example
sample_ble Control the R2110 BLE module
sample_ai Read R1520 analog voltage/current data
sample_agd Integrate an application with Guardian Service

Build a package directory with make package/<package-name>/install from the SDK root after selecting the target. A sample's presence does not mean your device has the hardware that it accesses.

Reuse or port a library

Use the headers and libraries for the selected SDK target. A package that provides headers for other packages should implement Package/Install/Develop; include the appropriate headers and link to the matching target library in dependent applications.

Package Purpose
json-c JSON handling
libmodbus Modbus
libpcre Regular-expression processing
mosquitto MQTT client library and mosquitto_pub / mosquitto_sub command-line clients
openssl OpenSSL library
paho_mqtt_c MQTT client library for C
libstdc++ C++ runtime
curl libcurl and the curl transfer tool
sqlite Embedded SQL database library
c-ares Asynchronous DNS requests
zlib Compression
e2fsprogs Utilities for ext2, ext3, and ext4 filesystems

When adding a library, use a comparable package in the installed SDK as the build and installation pattern. Confirm the target ABI, distribution obligations, required runtime files, and resulting package contents for that release. Check the selected SDK package for its library versions and link flags.

Use cloud-integration packages deliberately

Cloud SDK examples illustrate integrations bundled with particular SDK releases. Inspect their credentials, endpoint configuration, library version, and the provider's current service requirements before using them. Their catalogue entry alone does not establish that a cloud service remains available or accepts the old example unchanged.

Integration SDK package directories
ThingWorx lib_thingworx, tw_dev_properties, tw_steam_sensor, tw_steam_sensor_with_threads, tw_subscribed_properties
AWS IoT lib_aws_iot, aws_iot_shadow_sample, aws_iot_subscribe_publish_sample
Azure IoT azure_iot_sdk, azure_iot_hub_mqtt
Baidu IoT sample_iot_hub_baidu

Keep credentials out of source packages and shared build logs. Follow the current integration instructions for your selected cloud account rather than inferring configuration from the package name.

Check package dependencies before building

The dependency reference provides these relationships. Match every name against the installed package directory and Makefile before running a build:

Package Prerequisite packages
tw_steam_sensor lib_thingworx
azure_iot_sdk e2fsprogs
sample_sqlite sqlite
aws_iot_shadow_sample lib_aws_iot
sample_mqtt c-ares, mosquitto
tw_subscribed_properties lib_thingworx
tw_steam_sensor_with_threads lib_thingworx
azure_iot_hub_mqtt azure_iot_sdk
sample_iot_hub_baidu c-ares, mosquitto
tw_dev_properties lib_thingworx
aws_iot_subscribe_publish_sample lib_aws_iot
sample_modbus libmodbus

In SDK 5.0.3, use the package directory tw_subscribed_properties for package tw_sub_properties, and directory tw_steam_sensor_with_threads for package tw_steam_sensor_t. Use the directory name in the make package/<package-directory>/install target.

Verify the resulting package

Record the source revision, SDK image and target, changed Makefile settings, dependencies, build command/result, exported RPK and device firmware. Check that the intended source was compiled for the selected target and that the current build produced the package you exported. Inspect the RPK for all required runtime files, including a compatible C++ runtime when applicable.

Install the package on the matching development device through its authorized application workflow. Verify that the installed application produces the expected result, then test its start, stop and configuration behavior. Keep build success, package installation and device execution as separate results.

Related tasks