上一篇博客我们简单测试了swupdate的基础功能,当时使用的是buildroot进行编译的,依赖关心有buildroot进行处理了。今天我自己手动编译一些swupdate。下面记录了编译swupdate的过程。
基本过程就是下载源码,配置选项,然后进行编译。
swupdate是在github上下载的,下载地址为:
https://codeload.github.com/sbabic/swupdate/tar.gz/refs/tags/2023.05
libconfig是必须支持的库,下载地址如下:
http://hyperrealm.github.io/libconfig/dist/libconfig-1.7.3.tar.gz
如果选中了lua功能,需要下载和编译lua包,连接如下:
https://www.lua.org/ftp/lua-5.4.6.tar.gz
如果选中了delta功能,就拥有对delta升级能力(二进制差分)。librsync下载路径如下:
https://github.com/librsync/librsync/releases
https://codeload.github.com/zchunk/zchunk/tar.gz/refs/tags/1.3.1
如果选中了archive功能,就可以对归档文件的处理,就依赖libarchive。 libarchive库下载路径如下:
https://github.com/libarchive/libarchive/releases/tag/v3.6.2
如果选中了diskpart功能,就可以对disk分区进行操作。就依赖util-linux/misc-utils库下载地址
https://github.com/util-linux/util-linux/blob/master/misc-utils/blkid.c
如果选中了ext234功能,就可以对disk分区进行格式化操作。就依赖libext2fs库,下载地址
https://sourceforge.net/projects/e2fsprogs/
我们的设备使用的emmc所以不需要支持mtd,把mtd功能取消掉,就不用处理mtd的依赖了。如果你需要,那么你自行处理。
lua库就是比较简单,直接使用MakefIle进行构建。那么我们就直接修改Makefile进行交叉编译。我这里使用了quilt作为patch工具,来记录修改,其实用git更好,我就是试一下quilt。下面修改记录,主要是进行交叉编译和lua.pc文件生成功能修改。
Index: lua-5.4.6/Makefile
===================================================================
--- lua-5.4.6.orig/Makefile
+++ lua-5.4.6/Makefile
@@ -10,13 +10,14 @@ PLAT= guess
# so take care if INSTALL_TOP is not an absolute path. See the local target.
# You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with
# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h.
-INSTALL_TOP= /usr/local
+INSTALL_TOP= $(AARCH64_SYSROOT)/usr/local
INSTALL_BIN= $(INSTALL_TOP)/bin
INSTALL_INC= $(INSTALL_TOP)/include
INSTALL_LIB= $(INSTALL_TOP)/lib
INSTALL_MAN= $(INSTALL_TOP)/man/man1
INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V
INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V
+INSTALL_PKG= $(INSTALL_TOP)/lib/pkgconfig
# How to install. If your install program does not support "-p", then
# you may have to run ranlib on the installed liblua.a.
@@ -54,8 +55,8 @@ all: $(PLAT)
$(PLATS) help test clean:
@cd src && $(MAKE) $@
-install: dummy
- cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD)
+install: dummy pc
+ cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD) $(INSTALL_PKG)
cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN)
cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC)
cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
@@ -99,6 +100,20 @@ pc:
@echo "prefix=$(INSTALL_TOP)"
@echo "libdir=$(INSTALL_LIB)"
@echo "includedir=$(INSTALL_INC)"
+ @echo "prefix=$(INSTALL_TOP)" > $(INSTALL_PKG)/lua.pc
+ @echo -n "libdir=$$" >> $(INSTALL_PKG)/lua.pc
+ @echo "{prefix}/lib" >> $(INSTALL_PKG)/lua.pc
+ @echo -n "includedir=$$" >> $(INSTALL_PKG)/lua.pc
+ @echo "{prefix}/include" >> $(INSTALL_PKG)/lua.pc
+ @echo "" >> $(INSTALL_PKG)/lua.pc
+ @echo "Name: lua" >> $(INSTALL_PKG)/lua.pc
+ @echo "Description: lua library." >> $(INSTALL_PKG)/lua.pc
+ @echo "Version: $R" >> $(INSTALL_PKG)/lua.pc
+ @echo -n "Libs: -L$$" >> $(INSTALL_PKG)/lua.pc
+ @echo "{libdir} -llua" >> $(INSTALL_PKG)/lua.pc
+ @echo -n "Cflags: -I$$" >> $(INSTALL_PKG)/lua.pc
+ @echo "{includedir}" >> $(INSTALL_PKG)/lua.pc
+
# Targets that do not create files (not all makes understand .PHONY).
.PHONY: all $(PLATS) help test clean install uninstall local dummy echo pc
Index: lua-5.4.6/src/Makefile
===================================================================
--- lua-5.4.6.orig/src/Makefile
+++ lua-5.4.6/src/Makefile
@@ -6,13 +6,19 @@
# Your platform. See PLATS for possible values.
PLAT= guess
-CC= gcc -std=gnu99
+TOOLCHAIN-PREFIX= aarch64-linux-gnu-
+
+CC= $(TOOLCHAIN-PREFIX)gcc -std=gnu99
CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_3 $(SYSCFLAGS) $(MYCFLAGS)
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
LIBS= -lm $(SYSLIBS) $(MYLIBS)
-AR= ar rcu
-RANLIB= ranlib
+CFLAGS+= --sysroot=$(AARCH64_SYSROOT)
+LDFLAGS+= --sysroot=$(AARCH64_SYSROOT)
+
+
+AR= $(TOOLCHAIN-PREFIX)ar rcu
+RANLIB= $(TOOLCHAIN-PREFIX)ranlib
RM= rm -f
UNAME= uname
常规的configure编译,3步走。我这里是将系统的CC环境变量修改了的,如下:
./configure --host=aarch64 --with-sysroot=$AARCH64_SYSROOT --prefix=$AARCH64_SYSROOT/usr
make
make install
环境变量
CXX=aarch64-linux-gnu-g++
LD=aarch64-linux-gnu-ld
AARCH64_SYSROOT=/home/yp/workspace/toolchain/staging-8.3
AR=aarch64-linux-gnu-ar
NM=aarch64-linux-gnu-nm
CC=aarch64-linux-gnu-gcc
使用meson进行编译,交叉编译时,一定要把环境变量中的CC,AR,NM等变量unset掉。我的编译环境变量中CC=aarch64-linux-gnu-gcc时,meson setup --cross-file crosscompile.txt build-aarch64一直报错。报错如下:
zchunk-1.3.1$ meson setup --cross-file crosscompile.txt build-aarch64
The Meson build system
Version: 0.53.2
Source dir: /home/yp/workspace/packages/zchunk-1.3.1
Build dir: /home/yp/workspace/packages/zchunk-1.3.1/build-aarch64
Build type: cross build
Project name: zck
Project version: 1.3.1
/lib/ld-linux-aarch64.so.1: No such file or directory
meson.build:1:0: ERROR: Executables created by c compiler aarch64-linux-gnu-gcc are not runnable.
A full log can be found at /home/yp/workspace/packages/zchunk-1.3.1/build-aarch64/meson-logs/meson-log.txt
当我把编译的环境变量CC,AR,NM等unset后,执行setup恢复正常。 crosscompile.txt内容如下:
[binaries]
c = 'aarch64-linux-gnu-gcc'
cpp = 'aarch64-linux-gnu-g++'
ar = 'aarch64-linux-gnu-ar'
strip = 'aarch64-linux-gnu-strip'
[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'
[properties]
sys_root = '/home/yp/workspace/toolchain/staging-8.3'
[build_machine]
system = 'linux'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'
完整的编译流程如下:
unset CC AR CXX NM LD LDFLAGS PKG_CONFIG_PATH
配置交叉编译
meson setup --cross-file crosscompile.txt --prefix=/your/aarch64_sysroot/usr/local build-aarch64
如果你有什么东西漏配置了,可以编译路径下执行
meson --reconfigure --prefix=/your/aarch64_sysroot/usr/local
执行编译
ninja
执行安装
ninja install
是cmake进行编译,需要注意的是,我的编译中环境变量CC,AR,NM都是修改过的,已经是交叉工具链。编译脚本如下。
#!/bin/bash
rm build -rf
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=$AARCH64_SYSROOT/usr/local ..
if [ $? -ne 0 ];then
echo "cmake .. error"
exit 1
fi
make
if [ $? -ne 0 ];then
echo "make error"
exit 1
fi
make install
if [ $? -ne 0 ];then
echo "make install error"
exit 1
fi
echo "all is ok"
env命令的打印, 编译的环境变量如下:
CXX=aarch64-linux-gnu-g++
LD=aarch64-linux-gnu-ld
AARCH64_SYSROOT=/home/yp/workspace/toolchain/staging-8.3
AR=aarch64-linux-gnu-ar
NM=aarch64-linux-gnu-nm
CC=aarch64-linux-gnu-gcc
之前已经移植了,今天就不在移植了。
libarchive 是一个可以创建和读取多种不同流式归档格式的程序库,包含了最流行的 tar 格式变体、一些 cpio 格式,以及所有的 BSD 和 GNU ar 变体。bsdtar 是一个使用 libarchive 的 tar 实现。
编译的环境变量如2.4。编译脚本如下:
#!/bin/bash
rm cbuild -rf
mkdir cbuild
cd cbuild
export PKG_CONFIG_PATH=$AARCH64_SYSROOT/usr/lib/pkgconfig:$AARCH64_SYSROOT/usr/local/lib/pkgconfig
export CFLAGS="--sysroot=$AARCH64_SYSROOT -I$AARCH64_SYSROOT/include -I$AARCH64_SYSROOT/usr/local/include"
export LDFLAGS="--sysroot=$AARCH64_SYSROOT -L$AARCH64_SYSROOT/usr/loacl/lib"
cmake -DCMAKE_INSTALL_PREFIX=$AARCH64_SYSROOT/usr/local ..
if [ $? -ne 0 ];then
echo "cmake .. error"
unset PKG_CONFIG_PATH CFLAGS LDFLAGS
exit 1
fi
make
if [ $? -ne 0 ];then
echo "make error"
unset PKG_CONFIG_PATH CFLAGS LDFLAGS
exit 1
fi
make install
if [ $? -ne 0 ];then
echo "make install error"
unset PKG_CONFIG_PATH CFLAGS LDFLAGS
exit 1
fi
unset PKG_CONFIG_PATH CFLAGS LDFLAGS
echo "all is ok"
blkid - command-line utility to locate/print block device attributes.
又来了一个meson编译的东西,我们模仿上面的编译流程。完整的编译流程如下:
unset CC AR CXX NM LD LDFLAGS PKG_CONFIG_PATH
配置交叉编译
meson setup --cross-file crosscompile.txt --prefix=/your/aarch64_sysroot/usr/local build-aarch64 -Dbuild-libmount=disabled
如果你有什么东西漏配置了,可以编译路径下执行
meson --reconfigure --prefix=/your/aarch64_sysroot/usr/local
执行编译
ninja
执行安装
ninja install
编译中找不到Python.h头文件。我已经不想再去搞Python了,我们直接把对应的工具disabled掉-Dbuild-libmount=disabled,-Dbuild-plymouth-support=disabled。这些定义我是在meson.build文件中看到的。但是disbale掉还是解决不了问题。
meson --reconfigure --prefix=/your/aarch64_sysroot/usr/local -Dbuild-libmount=disabled -Dbuild-plymouth-support=disabled
配置完后是这种状态
util-linux 2.39
components
libblkid: enabled
libuuid: enabled
libmount: disabled
libsmartcols: enabled
libfdisk: enabled
uuidd: enabled
cryptsetup support: disabled
plymouth support: disabled
static programs:
然而还是没有解决问题,ninja就是要编译libmount中的东西,使用pythone。那我们就单独编译 blkid,fdisk,uuidd,然后再手动安装
ninja blkid
cp ./libblkid/libblkid.so* /home/hy/workspace/toolchain/staging-8.3/usr/local/lib -d
mkdir /home/hy/workspace/toolchain/staging-8.3/usr/local/include/blkid/ -p
cp libblkid/blkid.h /home/hy/workspace/toolchain/staging-8.3/usr/local/include/blkid/
cp ./meson-private/blkid.pc /home/hy/workspace/toolchain/staging-8.3/usr/local/lib/pkgconfig/
ninja fdisk
cp ./libfdisk/libfdisk.so* /home/yp/workspace/toolchain/staging-8.3/usr/local/lib -d
mkdir -p /home/yp/workspace/toolchain/staging-8.3/usr/local/include/libfdisk
cp libfdisk/libfdisk.h /home/yp/workspace/toolchain/staging-8.3/usr/local/include/libfdisk
cp meson-private/fdisk.pc /home/yp/workspace/toolchain/staging-8.3/usr/local/lib/pkgconfig/
ninja uuidd
mkdir -p /home/hy/workspace/toolchain/staging-8.3/usr/local/include/uuid
cp ./libuuid/src/uuidd.h ./libuuid/src/uuid.h ./libuuid/src/uuidP.h /home/hy/workspace/toolchain/staging-8.3/usr/local/include/uuid
cp ./build-aarch64/libuuid/libuuid.so* /home/hy/workspace/toolchain/staging-8.3/usr/local/lib -d
cp ./build-aarch64/meson-private/uuid.pc /home/hy/workspace/toolchain/staging-8.3/usr/local/lib/pkgconfig/
但是编译报错找不到一些符号,我看了半天没有找到解决办法,改天再研究一下,后来发现在/lib/libblkid.a已经有一个旧库了,连接查找库错误了。删除旧的库即可正常编译分区相关功能。
常规编译三步走,如下:
mkdir build
cd build
build$ ../configure --prefix=$AARCH64_SYSROOT/usr/local --host=aarch64 --with-sysroot=$AARCH64_SYSROOT
make
install
1)设置 SWUpdate Settings → Build Options
设置工具链前缀:aarch64-linux-gnu-
设置交叉编译的sys_root: /your/aarch64_sysroot
设置LD选项:-ldl -lm (后面编译会报错,所以加上这2个库)
选中你需要的功能,然后进行make编译。当报错缺头文件时,大概率是你的库没有安装。这里举例几个错误场景。
报错:
ld: lua_interface.c:(.text.update_table+0x200): undefined reference to `lua_pushstring'
lua.pc内容:
$ cat ~/workspace/toolchain/staging-8.3/usr/local/lib/pkgconfig/lua.pc
prefix=/home/yp/workspace/toolchain/staging-8.3/usr/local
libdir=${prefix}/lib
includedir=${prefix}/include
Name: lua
Description: lua library.
Version: 5.4.6
Libs: -L${libdir} -llua
Cflags: -I${includedir}
解决办法:
export PKG_CONFIG_PATH=/home/yp/workspace/toolchain/staging-8.3/usr/local/lib/pkgconfig/
liblua.a(loadlib.o): undefined reference to symbol 'dlsym@@GLIBC_2.17'
(.text+0x398): undefined reference to `sin'
in function `ext2fs_inode_alloc_stats2':
alloc_stats.c:(.text+0xf8): undefined reference to `com_err'
手动编译成功指令
aarch64-linux-gnu-gcc -Wall -Wshadow -Wwrite-strings -Wundef -Wstrict-prototypes -Wunused -Wunused-parameter -Wunused-function -Wunused-value -Wmissing-prototypes -Wmissing-declarations -Wno-format-security -Wno-format-truncation -Wold-style-definition -finline-limit=0 -fno-builtin-strlen -fomit-frame-pointer -ffunction-sections -fdata-sections -fno-guess-branch-probability -funsigned-char -falign-functions=1 -falign-jumps=1 -falign-labels=1 -falign-loops=1 -static-libgcc -fno-unwind-tables -fno-asynchronous-unwind-tables -Os --sysroot=/home/hy/workspace/toolchain/staging-8.3 -I/home/hy/workspace/toolchain/staging-8.3/usr/local/include -ldl -lm -lcom_err -Wl,-E -o swupdate_unstripped -Wl,--sort-common -Wl,--sort-section,alignment -Wl,--gc-sections -Wl,--start-group core/built-in.o handlers/built-in.o bootloader/built-in.o suricatta/built-in.o ipc/built-in.o corelib/lib.a mongoose/lib.a parser/lib.a fs/lib.a -Wl,--end-group -Wl,--start-group -lpthread -llua -lcurl -lconfig -larchive -lcrypto -lssl -lz -lzstd -lfdisk -lblkid -lext2fs -luuid -lblkid -lrsync -lzck -lcom_err -Wl,--end-group
最终编译出来的文件swupdate的依赖库如下,有些库是使用的静态库,如lua,ext2fs库:
swupdate-2023.05$ readelf -d swupdate
Dynamic section at offset 0x78d40 contains 35 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libcurl.so]
0x0000000000000001 (NEEDED) Shared library: [libarchive.so.19]
0x0000000000000001 (NEEDED) Shared library: [libcrypto.so.1.1]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libzstd.so.1]
0x0000000000000001 (NEEDED) Shared library: [librsync.so.2]
0x0000000000000001 (NEEDED) Shared library: [libzck.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
libarchive-3.6.2.tar.gz librsync-2.3.4.tar.gz swupdate-2023.05.tar.gz zchunk-1.3.1.tar.gz
libconfig-1.7.3.tar.gz lua-5.4.6.tar.gz util-linux-2.39.tar.gz e2fsprogs-1.47.0.tar.gz
最终我们支持了分区操作,ext文件格式操作,delta,签名,lua等功能的swupdate已经是比较全的了,另外zmq(ipc功能), uboot是没有支持的。
我们测试了一些功能正常,编译这到这里吧!!还是自动构建套件好选中就行,例如openwrt,buildroot等。如果这篇文章帮助到你,请帮忙点赞。