Application SDK

IoT Yocto allows user to generate application software development kit (SDK) and distribute it to other developers. The SDK contains all needed components for application development, including cross compiler, C runtime library, and development libraries corresponding to runtimes installed in rootfs image for the target board. Therefore developers can use it to develop applications without actually setting up a complete Yocto build environment.

For more information, please refer to Yocto Project Application Development and the Extensible Software Development Kit (eSDK).

The following sections will describe how to generate and install application SDK by using IoT Yocto.

Generate Application SDK Installer

The application SDK installer can be generated by running the command:

bitbake rity-demo-image -c populate_sdk

The generated installer is a big, self-contained shell script located under $BUILD_DIR/tmp/deploy/sdk, where file name looks like rity-demo-glibc-x86_64-rity-demo-image-armv8a-genio-1200-evk-toolchain-23.1-dev.sh.

Install Application SDK

To install SDK, copy the installer to a temporary folder, and run following commands:

chmod u+x rity-demo-glibc-x86_64-rity-demo-image-armv8a-genio-1200-evk-toolchain-23.1-dev.sh
sudo ./rity-demo-glibc-x86_64-rity-demo-image-armv8a-genio-1200-evk-toolchain-23.1-dev.sh

And follow instructions.

Note

The file name of installer might vary depending on your configuration.

To verify the installation, run following commands (assuming installation path is /opt):

source /opt/rity-demo/23.1-dev/environment-setup-armv8a-poky-linux
echo -e "#include <stdio.h>\nint main(){return 0;}" > test.c
$CC -o test test.c

Use with Docker

In addition to installing on the host machine, the SDK can also be installed in a Docker image. A simple Dockerfile is provided as an example:

FROM ubuntu:18.04

ENV SDK_INSTALLER=rity-demo-glibc-x86_64-rity-demo-image-armv8a-genio-1200-evk-toolchain-23.1-dev.sh

RUN apt-get update && \
    DEBIAN_FRONTEND=noniteractive apt-get -y upgrade && \
    apt-get -y install \
       python3 \
       locales \
    && rm -rf /var/lib/apt/lists/* \
    && locale-gen en_US.UTF-8

COPY ./${SDK_INSTALLER} /tmp
RUN /tmp/${SDK_INSTALLER} -y && rm -f /tmp/${SDK_INSTALLER}

WORKDIR /root

Put the installer script and Dockerfile in the same directory, and run following command to build a Docker image:

sudo docker build --force-rm -t sdk .

Cross-compiling 3rd Party Software

The application SDK can be used for building 3rd party softwares if they are not provided by IoT Yocto. Usually a 3rd party software (especially Open Source software) comes with its own building system, which can automatically detect cross-building environment setup by the application SDK, though we need to supply appropriate arguments to enable it. Here we take FFmpeg as an example to demonstrate the building process.

After downloading the source tarball, decompress it and change working folder to the newly created folder:

tar Jxf ffmpeg-4.4.1.tar.xz
cd ffmpeg-4.4.1

Then run following commands to build binary:

source <install dir>/opt/rity-demo/23.1-dev/environment-setup-armv8a-poky-linux
./configure --enable-cross-compile --cross-prefix=$CROSS_COMPILE --sysroot=$SDKTARGETSYSROOT --arch=aarch64 --target-os=linux --pkg-config=pkg-config
make

Note

The command used for configuration may vary depending on different software. Please read related documents to understand how to configure correctly.

Once the building process succeeds, we can install built binaries for later use. Note we shouldn’t install to the system directories of the host machine, because those binaries are not aiming for being run on host system. Instead, we should install them to a temporary folder:

make DESTDIR=<TEMPFOLDER> install

So that we can easily package the software for distribution.

Application Development

To use the SDK, the environment needs to be setup first:

source <install dir>/opt/rity-demo/23.1-dev/environment-setup-armv8a-poky-linux

The setup script exports several environment variables used for cross-building applications. Since the setup is quite complex, it’s not recommended to directly use a command such as aarch64-poky-linux-gcc to build programs. Instead, use $CC for compiler invocation in command line.

Here are examples:

# Compiling C source file
$CC -o out $CFLAGS test.c
# C++
$CXX -o out $CXXFLAGS test.cpp
# Linking
$LD -o out $LDFLAGS a.o b.o
# Stripping
$STRIP binary

The SDK also includes a pkg-config tool, which has different setup from the same tool installed in host system. The utility facilitates searching for include and library paths of dependent libraries when developing applications. For example,

$ pkg-config --cflags --libs glib-2.0
-I/opt/rity-demo/23.1-dev/sysroots/armv8a-poky-linux/usr/include/glib-2.0 -I/opt/rity-demo/23.1-dev/sysroots/armv8a-poky-linux/usr/lib64/glib-2.0/include -L/opt/rity-demo/23.1-dev/sysroots/armv8a-poky-linux/usr/lib64 -lglib-2.0

Note that the pkg-config of SDK outputs different paths compared to pkg-config in host system.

Cross-compiling with Make

Here is an example Makefile supporting cross-compilation:

BIN = test
OBJS = test.o
# CFLAGS += <your own flags>
# LDFLAGS += <your own flags>

.c.o:
    $(CC) -c -o $@ $(CFLAGS) $<

.PHONY: clean

all: $(BIN)

$(BIN): $(OBJS)
    $(CC) -o $@ $(LDFLAGS) $(OBJS)

clean:
    rm -f $(BIN) $(OBJS)

After sourcing the setup script mentioned in above section, all needed environment variables are exported, so we don’t need to setup those variables in Makefile. make will import them automatically.

Note

When copying the content listed above to your own Makefile, make sure that each shell command line should start with a tab. Otherwise a syntax error will happen when running make.

Cross-compiling with CMake

CMake is a modern software build tool widely used because of cross-platform support and easy-to-understand syntax. This section demonstrates how to integrate SDK with CMake build environment.

Here is the folder structure of an example cross-compiling environment:

.
├── cmake
│   └── toolchain-yocto-mtk.cmake
├── CMakeLists.txt
└── test.c

For cross-compilation, CMake uses a toolchain file to setup compiler before building. We can create a new one so that CMake can find necessary tools during configuration stage. An example toolcahin file is shown below:

# toolchain-yocto-mtk.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

set(CMAKE_SYSROOT $ENV{SDKTARGETSYSROOT})

set(CMAKE_C_COMPILER $ENV{CROSS_COMPILE}gcc)
set(CMAKE_C_FLAGS "-march=armv8-a+crc -fstack-protector-strong \
                   -Wformat -Wformat-security -Werror=format-security")
set(CMAKE_CXX_COMPILER $ENV{CROSS_COMPILE}g++)
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")

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

And here is an example CMakeLists.txt file:

cmake_minimum_required(VERSION 3.10)

project(Test)

add_executable(test test.c)

Arrange those files as the structure presented above. And we’re now ready to build program:

# Remember to source setup script first
$ mkdir build; cd build
$ cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain-yocto-mtk.cmake ..
$ make

Cross-compiling with Meson

Meson is yet another modern build tool that aims for simplicity and includes many built-in features which other build tools need to rely on external modules to offer. This section demonstrates how to integrate SDK with Meson build environment.

Here is the folder structure of an example cross-compiling environment:

.
├── meson.build
└── test.c

And the content of meson.build is quite simple:

project('Test', 'c')

executable('output', 'test.c')

Put the file in the same directory of source file, and run following commands:

# Remember to source setup script first
$ meson build
$ ninja -C build

Note

Because the original Meson doesn’t work well with the build environment of application SDK, the SDK bundles a modified version of Meson & Ninja tools. Always use bundled Meson to cross-build your projects. It’s not recommended to use the version installed in the host system.