编译环境
编译器默认使用gcccmake version>=3.13
依赖关系
ubus编译依赖json-c和libubox
libubox依赖json-c
源码下载路径
git clone https://github.com/json-c/json-c.git
git clone https://github.com/openwrt/libubox
git clone https://github.com/openwrt/ubus
编译方法
下载json-c、libubox、ubus源代码,解压重并命名文件夹(不要修改源码),保证文件目录结构如下。同时保证cmake文件具有可执行权限
复制粘贴运行本文档中的编译脚本,脚本运行参数all
.
├── build.sh
├── json-c
├── libubox
└── ubus
编译脚本
笔者测试用软件版本json-c版本:json-c-0.17-20230812libubox版本:2024-5-17 eb9bcb64185ac155c02cc1a604692c4b00368324ubus版本:2023-12-18 65bb027054def3b94a977229fd6ad62ddd32345b
编译产物
- 编译完成后会创建一个
products_and_depends名称的文件夹,用于存放编译产物ubus、ubusd和后续可能使用依赖库和头文件 ubus源码目录下的examples也会一起被编译,这个是一个官方demo
#!/bin/bash
base_path=$(pwd)
jsonC_path=$base_path/json-c
jsonC_build_path=$base_path/jsonC_build
libubox_path=$base_path/libubox
libubox_build_path=$base_path/libubox_build
ubus_path=$base_path/ubus
ubus_build_path=$base_path/ubus_build
ubus_examples_build_path=$ubus_path/examples/build
depend_path=$base_path/products_and_depends
depend_libs_path=$depend_path/lib
depend_inc_path=$depend_path/include
# json-c库编译
jsonC_build() {
echo "Start compiling jsonc"
mkdir $jsonC_build_path
cd $jsonC_build_path
$jsonC_path/cmake-configure --prefix=./ --enable-shared
make &&
# 拷贝编译产物
if [ ! -d "$depend_libs_path" ]; then
mkdir -p $depend_libs_path
fi
cp $jsonC_build_path/libjson-c* $depend_libs_path
}
# libubox库编译
libubox_build() {
echo "Start compiling libubox"
mkdir $libubox_build_path
cd $libubox_build_path
# 拷贝依赖文件
if [ ! -d "$depend_inc_path/json" ]; then
mkdir -p $depend_inc_path/json
fi
cp $jsonC_build_path/json.h $depend_inc_path/json &&
cp $jsonC_build_path/*.h $depend_inc_path &&
cp $jsonC_path/*.h $depend_inc_path &&
cmake -Djson=$depend_libs_path/libjson-c.so -DCMAKE_C_FLAGS="-I $depend_inc_path"\
-DBUILD_LUA:BOOL=OFF -DBUILD_EXAMPLES:BOLL=OFF -DBUILD_STATIC=ON $libubox_path -DCMAKE_BUILD_TYPE=Debug
make &&
# 拷贝编译产物
if [ ! -d "$depend_libs_path" ]; then
mkdir -p $depend_libs_path
fi
cp $libubox_build_path/libblobmsg_json* $depend_libs_path &&
cp $libubox_build_path/libjson_script* $depend_libs_path &&
cp $libubox_build_path/libubox* $depend_libs_path
}
# ubus库编译
ubus_build() {
echo "Start compiling ubus"
mkdir $ubus_build_path
cd $ubus_build_path
# 拷贝依赖文件
if [ ! -d "$depend_inc_path/libubox" ]; then
mkdir -p $depend_inc_path/libubox
fi
cp $libubox_path/*.h $depend_inc_path/libubox &&
cmake -Djson=$depend_libs_path/libjson-c.so -Dubox_library=$depend_libs_path/libubox.so \
-Dblob_library=$depend_libs_path/libblobmsg_json.so -Dubox_include_dir:PATH=$depend_inc_path -DBUILD_LUA=OFF\
-DBUILD_STATIC=ON $ubus_path -DCMAKE_BUILD_TYPE=Debug
make &&
# 拷贝编译产物
if [ ! -d "$depend_libs_path" ]; then
mkdir -p $depend_libs_path
fi
cp $ubus_path/*.h $depend_inc_path &&
cp $ubus_build_path/ubus $depend_path &&
cp $ubus_build_path/ubusd $depend_path &&
cp $ubus_build_path/libubus.* $depend_libs_path &&
cp $ubus_build_path/libubusd_library.* $depend_libs_path
ubus_examples_build
}
# ubus官方demo编译
ubus_examples_build() {
if [ ! -d "$ubus_examples_build_path" ]; then
mkdir -p $ubus_examples_build_path
fi
cd $ubus_examples_build_path
cmake .. -DBUILD_EXAMPLES=ON -DCMAKE_PREFIX_PATH=$depend_path -Dubox_library=ubox -DCMAKE_BUILD_TYPE=Debug
make
}
clean() {
echo "Clean up old files"
rm -rf $jsonC_build_path &&
rm -rf $libubox_build_path &&
rm -rf $ubus_build_path &&
rm -rf $depend_path &&
rm -rf $ubus_examples_build_path
}
build_all() {
jsonC_build
libubox_build
ubus_build
}
# 检查传递的参数并调用相应的函数
case "$1" in
jsonC)
jsonC_build
;;
libubox)
libubox_build
;;
ubus)
ubus_build
;;
all)
build_all
;;
clean)
clean
;;
*)
echo "Usage: $0 [jsonC|libubox|ubus|all|clean]"
exit 1
;;
esac
在Ubuntu上运行ubus
在Ubuntu上安装相关库
在完成上文中的编译步骤后,依次进入jsonC_build、libubox_build和ubus_build文件夹执行sudo make install命令在Ubuntu上安装json-c、libubox和ubus
笔者注:此处建议使用包管理工具先对编译成生产的二进制进行打包,然后再安装。这样可以使用包管理器进行管理
在终端手动执行ubus
创建三个终端
- 终端1:
su root
ubusd #ubusd进程
- 终端2:
su root
ubus listen test #监听ubus
- 终端3:
su root
ubus send test '{"hi!":"hello!"}' #发送ubus
如上述操作失败,可尝试将json-c、libubox和ubus的动态库库路径添加至系统动态库搜索路径
- 临时设置动态库加载路径
#设置临时动态库加载路径 export LD_LIBRARY_PATH=/path/to/lib:$LD_LIBRARY_PATH - 长期设置动态库加载路径
- 切换
root执行 :su root - 将动态库路径添加至系统动态库搜索路径:
echo [依赖库路径] >> /etc/ld.so.conf - 更新动态库搜索路径:
ldconfig
- 切换
运行官方demo
在ubus源码中存在一个examples文件夹存,里面是一个官方demo,上文中的编译脚本也会编译这个demo
运行方式
创建三个终端
终端1:
su root
./ubusd #执行在编译产物(products_and_depends文件夹)中的ubusd
终端2:
su root
./server #启动ubus/examples文件夹中的server端
在clinet端也成功执行后server侧的终端会出现如下打印
Watching object dd66ce76: Success
Object dd66ce76 went away
终端3:
su root
./client #启动ubus/examples文件夹中的client端
在启动clinet端后终端会出现如下打印,并不断新增直到client端进程结束
Avg time per iteration: 111 usec
Subscribers active: 1
Got fd from the server, watching...
completed request, ret: 0
Avg time per iteration: 111 usec
Got line: msg1: test received a message: blah
Sending count up to '100100'; string has length '592926'
Server validated our count up to '100100'
Got line: msg2: test received a message: blah
Avg time per iteration: 116 usec
Got line: msg3: test received a message: blah
Avg time per iteration: 121 usec
Got line: msg4: test received a message: blah
Sending count up to '100200'; string has length '593629'
Server validated our count up to '100200'
如果运行时提示找不到依赖库则需手动配置环境依赖(设置 LD_LIBRARY_PATH)
例如 libubox.so 位于 /usr/local/lib 目录下,执行以下命令;
PS:如果使用上文中的编译脚本执行ubus编译则libubox.so会在编译时存放在products_and_depends/lib文件中
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH