Overview
Integrating a Qt application as a Buildroot package into the SDK offers the following advantages:
- Single build: The application is built alongside the rootfs when running
./build.sh all, no manual copying required - Automatic integration: Binaries are automatically installed to
target/usr/bin/and packaged into the rootfs image - Version management: Application version is tied to the SDK version, making tracking and rollback easier
This chapter uses tspi-sysmonitor (a system information monitoring panel) as an example to demonstrate the complete integration process. This application uses Qt5 Widgets + Qt5 Network and refreshes CPU temperature, memory usage, system uptime, and network IP address every 2 seconds.
Prerequisite: Qt cross-compilation environment setup is complete. See Buildroot Qt Build Environment.
Application Package Organization in the SDK
In the LCSC-TaishanPi-3M-RK3576 SDK, Rockchip custom applications follow these directory conventions:
| Type | Source location | SITE in .mk | Example |
|---|---|---|---|
| Applications | app/<package-name>/ under SDK root | $(TOPDIR)/../app/<package-name> | app/lvgl_demo, app/n4 |
| External libraries/services | external/<package-name>/ under SDK root | $(TOPDIR)/../external/<package-name> | external/rkwifibt-app |
Here $(TOPDIR) points to the buildroot/ directory, and $(TOPDIR)/../ is the SDK root directory.
Why not put source code inside buildroot/package/?
All Rockchip local applications in the SDK (lvgl_demo, n4, rkpartybox, etc.) place their source code in the app/ directory, separated from the Buildroot build system. The benefit is that source code is managed independently of the Buildroot version — upgrading Buildroot will not lose application code.
Creating Application Source Code
Placing Source Code
Create the application directory under the SDK root:
cd /home/lckfb/TaishanPi-3-Linux
mkdir -p app/tspi-sysmonitor2
Place the application source code inside:
/home/lckfb/TaishanPi-3-Linux/
├── app/
│ └── tspi-sysmonitor/ # Application source code
│ ├── main.cpp
│ ├── sysmonitor.h
│ ├── sysmonitor.cpp
│ └── tspi-sysmonitor.pro # qmake project file
├── buildroot/
│ └── package/
│ └── rockchip/
│ └── tspi-sysmonitor/ # Buildroot package definition (Config.in + .mk only)
│ ├── Config.in
│ └── tspi-sysmonitor.mk
└── ...2
3
4
5
6
7
8
9
10
11
12
13
14
.pro File Example
QT += widgets network
TARGET = tspi-sysmonitor
TEMPLATE = app
SOURCES += main.cpp sysmonitor.cpp
HEADERS += sysmonitor.h
target.path = /usr/bin
INSTALLS += target2
3
4
5
6
7
target.path = /usr/bin tells qmake the installation target path. Buildroot's qmake-package infrastructure will automatically execute make install INSTALL_ROOT=$(TARGET_DIR).
Creating the Buildroot Package Definition
Directory Structure
Create a package definition directory under buildroot/package/rockchip/ for the application (note: only build configuration goes here, not source code):
mkdir -p buildroot/package/rockchip/tspi-sysmonitorWriting Config.in
config BR2_PACKAGE_TSPI_SYSMONITOR
bool "tspi-sysmonitor"
depends on BR2_PACKAGE_QT5
depends on BR2_PACKAGE_QT5BASE_WIDGETS
help
System monitor panel for TaishanPi RK3576.
Displays CPU temperature, memory usage, uptime and IP address.2
3
4
5
6
7
depends on BR2_PACKAGE_QT5 ensures this option is only visible when Qt5 is enabled.
Writing the .mk File (qmake Method)
If the project uses qmake (.pro file), use the qmake-package infrastructure:
################################################################################
#
# tspi-sysmonitor
#
################################################################################
TSPI_SYSMONITOR_VERSION = 1.0.0
TSPI_SYSMONITOR_SITE = $(TOPDIR)/../app/tspi-sysmonitor
TSPI_SYSMONITOR_SITE_METHOD = local
TSPI_SYSMONITOR_DEPENDENCIES = qt5base
TSPI_SYSMONITOR_LICENSE = MIT
TSPI_SYSMONITOR_LICENSE_FILES = LICENSE
$(eval $(qmake-package))2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Key field descriptions:
| Field | Description |
|---|---|
TSPI_SYSMONITOR_SITE | Source path; $(TOPDIR)/../app/ points to the app/ directory under the SDK root |
TSPI_SYSMONITOR_SITE_METHOD = local | Use local source code, do not download from the network |
TSPI_SYSMONITOR_DEPENDENCIES | Declare dependencies; Buildroot will compile qt5base first |
TSPI_SYSMONITOR_LICENSE | License declaration (required by Buildroot conventions) |
$(eval $(qmake-package)) | Invoke the qmake build infrastructure, which automatically handles cross-compilation |
What does qmake-package do?
qmake-package (defined in buildroot/package/pkg-qmake.mk) automatically:
- Uses the Buildroot cross-compilation toolchain's
qmaketo generate a Makefile - Performs cross-compilation
- Executes
make install INSTALL_ROOT=$(TARGET_DIR)to install to the target rootfs
Writing the .mk File (CMake Method)
If the project uses CMake (CMakeLists.txt), use the cmake-package infrastructure:
################################################################################
#
# tspi-sysmonitor
#
################################################################################
TSPI_SYSMONITOR_VERSION = 1.0.0
TSPI_SYSMONITOR_SITE = $(TOPDIR)/../app/tspi-sysmonitor
TSPI_SYSMONITOR_SITE_METHOD = local
TSPI_SYSMONITOR_DEPENDENCIES = qt5base
TSPI_SYSMONITOR_LICENSE = MIT
TSPI_SYSMONITOR_LICENSE_FILES = LICENSE
TSPI_SYSMONITOR_CONF_OPTS = \
-DCMAKE_BUILD_TYPE=Release
$(eval $(cmake-package))2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Choose one of the two methods. The rest of this chapter uses the qmake method.
Registering the Package in Buildroot
Edit buildroot/package/rockchip/Config.in and add the following at an appropriate location within the if BR2_PACKAGE_ROCKCHIP block:
source "package/rockchip/tspi-sysmonitor/Config.in"You can use grep to find the location of other packages as a reference:
grep -n "source.*Config.in" buildroot/package/rockchip/Config.in | tail -10Add it before the final endif.
Enabling and Building in menuconfig
Enabling the Package
# Enter the SDK root directory
cd /home/lckfb/TaishanPi-3-Linux
# Interactive selection (recommended)
./build.sh lunch
# Select tspi_3m_rk3576_buildroot_defconfig
# Open menuconfig directly
./build.sh bconfig2
3
4
5
6
7
8
9
In the opened menuconfig interface, navigate to:
Target packages → Rockchip Platform → tspi-sysmonitorPress space to select it, then save and exit.
Building the Package Individually
# Build only tspi-sysmonitor (pass make target to Buildroot)
./build.sh bmake:tspi-sysmonitor
# Or use a full build (compile all packages + generate rootfs)
./build.sh all2
3
4
5
After successful compilation, the binary will appear at:
buildroot/output/rockchip_rk3576/target/usr/bin/tspi-sysmonitorRebuilding (After Source Code Changes)
# Force rebuild (clear build cache and rebuild)
./build.sh bmake:tspi-sysmonitor-rebuild2
About Buildroot's Build Cache
Buildroot uses stamp files to track build state. For packages with SITE_METHOD = local, you must use the -rebuild suffix after modifying source code to trigger recompilation; otherwise Buildroot will consider the package up-to-date and skip it.
Configuring Auto-Start at Boot
Writing the init.d Startup Script
Create the script file S99tspi-sysmonitor:
#!/bin/sh
#
# Start tspi-sysmonitor at boot
#
DAEMON=/usr/bin/tspi-sysmonitor
PIDFILE=/var/run/tspi-sysmonitor.pid
case "$1" in
start)
echo "Starting tspi-sysmonitor..."
export QT_QPA_PLATFORM=eglfs
export QT_QPA_EGLFS_INTEGRATION=eglfs_kms
export QT_QPA_EGLFS_KMS_CONFIG=/etc/qt-eglfs-kms.conf
export QT_QPA_FONTDIR=/usr/share/fonts/dejavu
export QT_QPA_EGLFS_HIDECURSOR=1
start-stop-daemon -S -b -m -p $PIDFILE -x $DAEMON
;;
stop)
echo "Stopping tspi-sysmonitor..."
start-stop-daemon -K -p $PIDFILE
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 02
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
The number 99 in the S99 prefix determines the startup order — higher numbers start later, ensuring it runs after display services.
Packaging into the Image via rootfs Overlay
Place the script in Buildroot's overlay directory, which will be automatically merged into the rootfs during build:
# Create the corresponding directory structure in the overlay
mkdir -p buildroot/board/rockchip/rk3576/fs-overlay/etc/init.d/
# Copy the script and grant execute permission
cp S99tspi-sysmonitor buildroot/board/rockchip/rk3576/fs-overlay/etc/init.d/
chmod +x buildroot/board/rockchip/rk3576/fs-overlay/etc/init.d/S99tspi-sysmonitor2
3
4
5
6
Overlay directory structure:
buildroot/board/rockchip/rk3576/fs-overlay/
├── etc/
│ └── init.d/
│ └── S99tspi-sysmonitor
└── ...2
3
4
5
Confirm the Overlay is Registered
The SDK's defconfig already has BR2_ROOTFS_OVERLAY="board/rockchip/common/base board/rockchip/rk3576/fs-overlay/" configured — no additional action is needed. You can verify with:
grep BR2_ROOTFS_OVERLAY buildroot/configs/rockchip_rk3576_defconfigAfter rebuilding the rootfs, the script will be automatically included in the image:
./build.sh allVerification
Build Verification
# Confirm the binary exists in the target directory
ls -la buildroot/output/rockchip_rk3576/target/usr/bin/tspi-sysmonitor
# Confirm the init script exists
ls -la buildroot/output/rockchip_rk3576/target/etc/init.d/S99tspi-sysmonitor2
3
4
5
Flashing the Image
After compilation, flash the new image to the development board. See System Flashing.
Confirming on the Board
After flashing and booting, log in via serial console or SSH:
# Confirm the program is installed
ls /usr/bin/tspi-sysmonitor
# Confirm the init script exists and has execute permission
ls -la /etc/init.d/S99tspi-sysmonitor
# Manual start test
/etc/init.d/S99tspi-sysmonitor start
# Check if the process is running
ps aux | grep tspi-sysmonitor2
3
4
5
6
7
8
9
10
11