如何优雅地交叉编译Zerotier到树莓派
背景
在给树莓派上刷写了最新的Rocky 10之后,发现Zerotier官方没有针对其发布相应的软件包,要是在树莓派上编译Zerotier则更是地狱,1G版本的rpi不仅慢还有可能爆内存,如此看来只能选择交叉编译的方式了。而Zerotier官方的编译流程并没有交叉编译这一步,所以需要改一些参数才行。
准备
获取源码
要交叉编译肯定需要Zerotier的代码,先将其克隆到本地仓库:
1 | git clone https://github.com/zerotier/ZeroTierOne.git -b 1.16.1 # 只需要1.16.1分支下的内容 |
配置编译环境
还需要编译所用的工具和交叉编译工具链。一般编译所用工具直接安装build-essential和cmake就行,
1 | sudo apt install build-essential cmake --install-suggests |
交叉编译工具链可以直接使用系统提供的版本,写一个正则在apt里搜一下:
1 | apt search ^[a-z+]+-[0-9]+-aarch64-linux-gnu$ |
这也不是很老的软件,显然安装gcc-12-aarch64-linux-gnu和g++-12-aarch64-linux-gnu两个包就行。
1 | sudo apt install gcc-12-aarch64-linux-gnu g++-12-aarch64-linux-gnu |
装好之后验证一下gcc和g++能不能用:
1 | $ aarch64-linux-gnu-gcc --version |
交叉编译
阅读编译配置
官方的编译说明给的很简短:
- To build on Mac and Linux just type
make. On FreeBSD and OpenBSDgmake(GNU make) is required and can be installed from packages or ports. For Windows there is a Visual Studio solution inwindows/. - The project supports various build targets and platforms:
- Standard build:
make - Self-test build:
make selftest - Platform-specific requirements:
- FreeBSD/OpenBSD: Use
gmake(GNU make) - Windows: Visual Studio solution in
windows/
- FreeBSD/OpenBSD: Use
- Standard build:
观察一下./Makefile,看看从哪里下手进行交叉编译:
1 | # Common makefile -- loads make rules for each platform |
根据提示看一下./make-linux.mk,这里给出一些关键片段:
1 | # Determine system build architecture from compiler target. This is hairy due to "ARM wrestling." |
上文这一段负责获取编译器的target,
1 | ifeq ($(CC_MACH),arm64) |
上面这一段是当target是aarch64时配置的编译选项。
1 | ifeq ($(ZT_SSO_SUPPORTED), 1) |
1 | ifeq ($(ZT_SSO_SUPPORTED), 1) |
上面这两段分别描述了当ZT_SSO_SUPPORTED参数开启时增加的链接库和编译过程。由于另外链接了rust库,而cargo的交叉编译配置需要对ZT_CARGO_FLAGS做额外的修改,还要改链接位置,十分不优雅(而且编译完跑起来碰到了段错误),索性直接不编译,之后make的时候加上ZT_SSO_SUPPORTED=0就好了。
1 | # Note: keep the symlinks in /var/lib/zerotier-one to the binaries since these |
install明显就是复制一下文件,因为需要把编译成果拷贝走,编译的时候记得指定DESTDIR安装目录,这里就选./install。
1 | mkdir -p ./install |
执行交叉编译
明确了编译参数之后即可进行交叉编译,据前文,我们的编译参数有:
CC=aarch64-linux-gnu-gccCXX=aarch64-linux-gnu-g++ZT_SSO_SUPPORTED=0
安装时需要的参数有:
DESTDIR=$(pwd)/install
直接带参数用全部线程make:
1 | make -j$(nproc) CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ ZT_SSO_SUPPORTED=0 |
如果编译过程报错,别用多线程编译,单线程跑一下看是哪的问题。
编译通过后可以执行安装了,记得带参数:
1 | make install DESTDIR=$(pwd)/install |
看一下./install里的文件:
1 | tree |
可以再看一下编译出来的ELF文件头:
1 | readelf -h ./install/usr/sbin/zerotier-one |
没啥毛病,把对应文件改一下权限,复制到树莓派对应目录就行,完美。
如何优雅地交叉编译Zerotier到树莓派