K1 OH5.0 三方包移植说明
修订记录
| 修订版本 | 修订日期 | 修订说明 |
| 001 | 2025-04-01 | 初始版本 |
| 002 | 2025-06-06 | 添加libaio,fio移植方法 |
| 003 | 2025-07-24 | 添加bash移植方法 |
| 004 | 2025-07-25 | 添加iperf3移植方法 |
在 K1 OH5.0 系统中,第三方软件包的编译支持两种集成方式:
- 源码集成编译(推荐用于结构简单的包)
- 使用 NDK 编译(推荐用于依赖复杂的包)
以下章节将对这两种方式分别进行详细说明和示例演示。
1. 源码中集成并编译三方包
该方式是将第三方包的源代码集成至 OpenHarmony 源码树中进行统一编译。
主要工作内容包括:依据 OpenHarmony 的构建规范,为该第三方包编写对应的 BUILD.gn 构建脚本。
1.1. BUILG.gn 扫盲
OpenHarmony 使用 GN 构建系统,BUILD.gn 是其核心配置文件,用于定义编译目标及构建规则。其功能与传统的 Makefile 类似。
1.1.1. 简单示例:可执行程序
将 hello_world.c 编译为可执行程序,该程序依赖静态库 lib_utils。lib_utils 静态库由 utils.c 源文件编译生成,并通过 utils.h 提供相关函数接口。
config("default_flags") {
cflags = ["-Wall", "-O2"] # 编译器参数
}
ohos_executable("hello_world") {
sources = ["hello_world.c"] # 指定源文件
deps = [":lib_utils"] # 声明依赖项
configs = [":default_flags"] # 应用编译配置
}
ohos_shared_library("lib_utils") {
sources = ["utils.c"] # 指定源文件
include_dirs = [ # 指定头文件
"include"
]
public_configs = [":default_flags"]
}
目标类型:
executable():生成可执行文件static_library():构建静态库shared_library():构建动态库
关键参数:
sources:必需项,指定源文件列表deps:非必需项,声明依赖的其他目标configs:非必需项,应用编译配置项
1.2. 前置准备
参考编译文档完成系统编译、烧录:K1 OH5.0 下载编译烧录说明
1.3. 示例:编译 iperf3
-
将源码集成至 OpenHarmony 源码树中,路径为
device/soc/spacemit/k1/tools(该目录用于存放各类工具)。同时,在上级目录的BUILD.gn文件中添加对应依赖项,以确保iperf3能够被正常编译。group("tools") {
deps = [
":getevent",
":busybox",
":route",
":GP_daemon_fps",
":hdc",
":native_player_demo",
":fio",
":bash",
"//device/soc/spacemit/k1/tools/memtester:memtester",
"//device/soc/spacemit/k1/tools/iperf3:iperf3",
"//device/soc/spacemit/k1/tools/rtwpriv:rtwpriv",
"//device/soc/spacemit/k1/tools/aicrf_test:aicrf_test",
"//device/soc/spacemit/k1/tools/ecnr:ecnr",
"//device/soc/spacemit/k1/tools/ddr_bw:ddr_bw",
]
} -
编写 iperf3 的
BUILD.gnimport("//build/ohos.gni") # 一般都需要
import("//drivers/hdf_core/adapter/uhdf2/uhdf.gni") # 一般都需要
cflags_c_common = [ # C语言编译选项
"-Wno-pointer-sign",
"-Wno-unused-function",
"-Wno-pointer-to-int-cast",
"-Wno-deprecated-non-prototype",
]
cflags_cc_common = [ # C++语言编译选项
"-Wno-pointer-sign",
"-Wno-unused-function",
"-Wno-pointer-to-int-cast",
"-Wno-deprecated-non-prototype",
]
ohos_executable("iperf3") { # 编译可执行程序iperf3
sources = [
"src/tcp_info.c",
"src/iperf_error.c",
"src/timer.c",
"src/net.c",
"src/main.c",
"src/iperf_client_api.c",
"src/iperf_udp.c",
"src/iperf_tcp.c",
"src/iperf_api.c",
"src/iperf_locale.c",
"src/iperf_server_api.c",
"src/cjson.c",
"src/tcp_window_size.c",
"src/iperf_util.c",
"src/units.c",
]
include_dirs = [
"src",
]
output_name = "iperf3"
cflags_c = cflags_c_common
cflags_cc = cflags_cc_common
deps = [
]
external_deps = [
]
install_enable = true # 是否安装
install_images = [ system_base_dir ] # 安装在system/bin
module_install_dir = "bin" # 安装在system/bin
part_name = "spacemit_products"
} -
完整编译后,在输出目录
out下是确认生成iperf3的可执行文件fuqiang@snode2:~/workspace/oh5/out/xxx/packages$ find . -name iperf3
./phone/system/bin/iperf3 -
烧录镜像,启动后,执行
iperf3 -h, 若显示如下,则表示编译与安装成功。# iperf3 -h
Usage: iperf [-s|-c host] [options]
iperf [-h|--help] [-v|--version]
Server or Client:
-p, --port # server port to listen on/connect to
-f, --format [kmgKMG] format to report: Kbits, Mbits, KBytes, MBytes
-i, --interval # seconds between periodic bandwidth reports
-F, --file name xmit/recv the specified file
-A, --affinity n/n,m set CPU affinity
...
2. 使用 NDK 编译三方包
2.1. 前置准备
下载指定版本的 NDK (NDK 下载路径)并进行解压。解压完 成后,NDK 的目录结构如下所示:
fuqiang@snode2:/data/home/fuqiang/workspace/native$ tree -L 1
.
|-- build
|-- build-tools
|-- compatible_config.json
|-- llvm
|-- nativeapi_syscap_config.json
|-- ndk_system_capability.json
|-- oh-uni-package.json
`-- sysroot
4 directories, 4 files
2.2. 三方包编译
以下示例展示如何使用 NDK 编译多个典型三方包的流程。
2.2.1. 编译 libaio
- 下载
libaio源码,如下:
fuqiang@snode2:~/workspace/oh5_r_release/device/soc/spacemit/k1/tools/libaio$ tree -L 1
.
|-- ChangeLog
|-- COPYING
|-- harness
|-- INSTALL
|-- libaio.spec
|-- Makefile
|-- man
|-- src
`-- TODO
3 directories, 6 files
- 编写构建脚本
libaio_env.sh,如下,将该脚本放置到libaio的根目录
#!/bin/bash -e
CURRENT_DIR=$(pwd)
export NDK_DIR=/home/fuqiang/workspace/native # 导入NDK路径
PACKAGE=libaio # 包名
PACKAGE_DIR=$CURRENT_DIR # 包源码路径
INSTALLED_DIR=${NDK_DIR}/sysroot/usr # 安装路径,安装在sysroot中,因为fio编译会依赖libaio
export TOOLCHAIN=$NDK_DIR/llvm # 导入工具链
export PATH=$TOOLCHAIN/bin:$PATH # 添加工具链环境变量
export SYSROOT=$NDK_DIR/sysroot # 导入sysroot路径
export TARGET=riscv64-linux-ohos # 导入target变量
export AR=$TOOLCHAIN/bin/llvm-ar # 导入一些工具和配置
export CC="$TOOLCHAIN/bin/clang --target=$TARGET"
export AS=$TOOLCHAIN/bin/llvm-as
export CXX="$TOOLCHAIN/bin/clang++ --target=$TARGET"
export LD=$TOOLCHAIN/bin/ld.lld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
export CFLAGS="--sysroot=${SYSROOT} -march=rv64gcv_zba_zbb_zbc_zbs_zihintpause_zfh -I/home/fuqiang/workspace/native/sysroot/usr/include/asm-riscv -D__MUSL__ -O2"
export LDFLAGS=""
make -j8
#make PREFIX=$INSTALLED_DIR install
make install
echo $PACKAGE build\&install success.
- 执行
libaio_env.sh脚本,进行libaio的编译安装,安装的头文件和库如下:
install -D -m 644 libaio.h /home/fuqiang/workspace/native/sysroot/usr/include/libaio.h
install -D -m 644 libaio.a /home/fuqiang/workspace/native/sysroot/usr/lib/libaio.a
install -D -m 755 libaio.so.1.0.1 /home/fuqiang/workspace/native/sysroot/usr/lib/libaio.so.1.0.1
ln -sf libaio.so.1.0.1 /home/fuqiang/workspace/native/sysroot/usr/lib/libaio.so.1
ln -sf libaio.so.1.0.1 /home/fuqiang/workspace/native/sysroot/usr/lib/libaio.so
libaio的编译生成文件已经安装至 ND K 的sysroot中,再编译其他依赖libaio的三方包(比如下文示例的fio),就可以直接使用 NDK 进行编译
2.2.2. 编译 fio(依赖 libaio)
- 下载
fio源码fio-3.39.tar.gz - 编写构建脚本
fio_env.sh,如下,将该脚本放置到fio的根目录
#!/bin/bash -e
CURRENT_DIR=$(pwd)
export NDK_DIR=/home/fuqiang/workspace/native
PACKAGE=fio-3.39
PACKAGE_DIR=$CURRENT_DIR
INSTALLED_DIR=${CURRENT_DIR}/installed
export TOOLCHAIN=$NDK_DIR/llvm
export PATH=$TOOLCHAIN/bin:$PATH
export SYSROOT=$NDK_DIR/sysroot
export TARGET=riscv64-linux-ohos
export AR=$TOOLCHAIN/bin/llvm-ar
export CC="$TOOLCHAIN/bin/clang --target=$TARGET"
export AS=$TOOLCHAIN/bin/llvm-as
export CXX="$TOOLCHAIN/bin/clang++ --target=$TARGET"
export LD=$TOOLCHAIN/bin/ld.lld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
export CFLAGS="--sysroot=$SYSROOT -march=rv64gcv_zba_zbb_zbc_zbs_zihintpause_zfh -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wa,--noexecstack -Wformat -Werror=format-security -D__MUSL__ -O2"
export LDFLAGS="--rtlib=compiler-rt -fuse-ld=lld -Wl,--warn-shared-textrel -Wl,--fatal-warnings -lunwind -Wl,--no-undefined -Qunused-arguments -Wl,-z,noexecstack -Wl,--gc-sections"
# ./configure --prefix=$INSTALLED_DIR --host=$TARGET
./configure --prefix=$INSTALLED_DIR --cpu=riscv64 --extra-cflags="-I/home/fuqiang/workspace/native/sysroot/usr/include/asm-riscv -I/home/fuqiang/workspace/native/sysroot/usr/include"
make -j8
make install
popd > /dev/null
popd > /dev/null
echo $PACKAGE build\&install success.
- 执行
fio_env.sh脚本,进行fio的编译安装,安装的头文件和库如下:
install -m 755 -d /home/fuqiang/workspace/oh5_r_release/device/soc/spacemit/k1/tools/fio-3.39/installed/bin
install fio t/fio-genzipf t/fio-btrace2fio t/fio-dedupe t/fio-verify-state ./tools/fio_generate_plots ./tools/plot/fio2gnuplot ./tools/genfio ./tools/fiologparser.py ./tools/hist/fiologparser_hist.py ./tools/hist/fio-histo-log-pctiles.py ./tools/fio_jsonplus_clat2csv /home/fuqiang/workspace/oh5_r_release/device/soc/spacemit/k1/tools/fio-3.39/installed/bin
install -m 755 -d /home/fuqiang/workspace/oh5_r_release/device/soc/spacemit/k1/tools/fio-3.39/installed/man/man1
install -m 644 ./fio.1 /home/fuqiang/workspace/oh5_r_release/device/soc/spacemit/k1/tools/fio-3.39/installed/man/man1
install -m 644 ./tools/fio_generate_plots.1 /home/fuqiang/workspace/oh5_r_release/device/soc/spacemit/k1/tools/fio-3.39/installed/man/man1
install -m 644 ./tools/plot/fio2gnuplot.1 /home/fuqiang/workspace/oh5_r_release/device/soc/spacemit/k1/tools/fio-3.39/installed/man/man1
install -m 644 ./tools/hist/fiologparser_hist.py.1 /home/fuqiang/workspace/oh5_r_release/device/soc/spacemit/k1/tools/fio-3.39/installed/man/man1
install -m 755 -d /home/fuqiang/workspace/oh5_r_release/device/soc/spacemit/k1/tools/fio-3.39/installed/share/fio
install -m 644 ./tools/plot/*gpm /home/fuqiang/workspace/oh5_r_release/device/soc/spacemit/k1/tools/fio-3.39/installed/share/fio/
fio源码编译主要生成fio的bin文件,可直接部署至系统中使用。
2.2.3. 编译 bash
- 下载
bash源码bash-5.2.tar.gz - 编写构建脚本
bash_env.sh,如下,将该脚本放置到 bash 的根目录
#!/bin/bash -e
CURRENT_DIR=$(pwd)
export NDK_DIR=/home/fuqiang/workspace/native
PACKAGE=bash-5.2
PACKAGE_DIR=$CURRENT_DIR
INSTALLED_DIR=${CURRENT_DIR}/installed
export TOOLCHAIN=$NDK_DIR/llvm
export PATH=$TOOLCHAIN/bin:$PATH
export SYSROOT=$NDK_DIR/sysroot
export TARGET=riscv64-linux-ohos
export AR=$TOOLCHAIN/bin/llvm-ar
export CC="$TOOLCHAIN/bin/clang --target=$TARGET"
export AS=$TOOLCHAIN/bin/llvm-as
export CXX="$TOOLCHAIN/bin/clang++ --target=$TARGET"
export LD=$TOOLCHAIN/bin/ld.lld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
export CFLAGS="--sysroot=$SYSROOT -march=rv64gcv_zba_zbb_zbc_zbs_zihintpause_zfh -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wa,--noexecstack -Wformat -D__MUSL__ -O2"
export LDFLAGS="--rtlib=compiler-rt -fuse-ld=lld -Wl,--warn-shared-textrel -Wl,--fatal-warnings -lunwind -Wl,--no-undefined -Qunused-arguments -Wl,-z,noexecstack -Wl,--gc-sections"
./configure --prefix=$INSTALLED_DIR --host=x86_64-pc-linux-gnu --enable-static-link --enable-history --without-bash-malloc
make -j8
make install
popd > /dev/null
popd > /dev/null
echo $PACKAGE build\&install success.
- 执行
bash_env.sh脚本,进行bash的编译安装,安装的头文件和库如下:
/usr/bin/install -c -m 0755 bash /home/fuqiang/workspace/oh5_r_release/device/soc/spacemit/k1/tools/bash-5.2/installed/bin/bash
/usr/bin/install -c -m 0555 bashbug /home/fuqiang/workspace/oh5_r_release/device/soc/spacemit/k1/tools/bash-5.2/installed/bin/bashbug
bash源码编译主要生成bash的bin文件,可直接部署至系统中使用。
3. FAQ
3.1. 编译构建中如何指定产物名称和拓展名
以 ohos_shared_library 为例,在其中指定 output_prefix_override 和 output_name 以及 output_extension 即可
ohos_shared_library("libelf") {
output_prefix_override = **true** _# 覆盖默认的文件名前缀_
output_name = **"libelf"** _# 指定输出文件的名称(不含扩展名)。_
output_extension = **"so"** _# 指定输出文件的扩展名。_
include_dirs = [
** ...**
]
cflags = [
** ...**
]
sources = [
** ...**
]
public_deps = []
install_images = [
** ...**
]
relative_install_dir = **""**
part_name = **""**
}

