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 runtime components installed in the 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 software 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 toolchain 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.