.. include:: /keyword.rst =============== 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|. .. contents:: Sections :local: :depth: 1 .. _generate-sdk: Generate Application SDK Installer ================================== The application SDK installer can be generated by running the command: .. prompt:: bash 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: .. prompt:: bash 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``): .. prompt:: bash source /opt/rity-demo/23.1-dev/environment-setup-armv8a-poky-linux echo -e "#include \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: .. code:: 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: .. prompt:: bash 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: .. prompt:: bash tar Jxf ffmpeg-4.4.1.tar.xz cd ffmpeg-4.4.1 Then run following commands to build binary: .. prompt:: bash source /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: .. prompt:: bash make DESTDIR= install So that we can easily package the software for distribution. Application Development ======================= To use the SDK, the environment needs to be setup first: .. prompt:: bash source /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: .. code:: # 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, .. code:: $ 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: .. code:: BIN = test OBJS = test.o # CFLAGS += # LDFLAGS += .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: .. code:: . ├── 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: .. code:: # 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: .. code:: 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: .. code:: # 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: .. code:: . ├── meson.build └── test.c And the content of meson.build is quite simple: .. code:: project('Test', 'c') executable('output', 'test.c') Put the file in the same directory of source file, and run following commands: .. code:: # 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.