群晖 DSM 系统在 Linux 环境下的 armv7 架构交叉编译及环境配置实践

关于代码块的问题,文章我放在 Github Gist 上了,应该会有更好的阅读体验。
记录配置群晖 218j (armv7l 架构) 常用环境,仅作为记录。关于交叉编译网络上的资料比较少,很多地方踩了很多坑,有一些心得,同时群晖自带的套件中心套件很少,本人的型号没有什么第三方库,想要装一个 aria2 网络上能查到的资料都很少,且 DSM7.0 之后本来能用的方法也失效了,即使装了 Entware ,很多包版本也是落后的,只能自己编译,所以本文可能有参考价值。但 这不是一篇参考指南,编译等操作本就门槛不低,而且相比常规的编译,armv7l 架构不管是本地编译还是交叉编译都非常抽象,比较基本的操作我也都省略了,也懒得截图。很多地方不一定是标准操作,仅供参考。
本人交叉编译时踩的坑
有调试编译了一整天,最后发 issue 才知道不支持交叉编译的(不写在文档里,issue 里也没有相关的说话)。
也有搞了半天依赖都编译不出来的,结果人家开发者最近已经不用这个依赖,发过 pull request 了的。
群晖自带的内核版本太低, 有的即使调试一整天,系统调用也可能会报错。
总之交叉编译,特别是给 armv7l 编译是一件很麻烦的事,网上几乎查不到资料,下文给出的配置文件 (针对 armv7l) 对于大部分软件应该是适用的,但是具体到每个软件里还得看情况,即使都用的是 make,configure,cmake,但是具体到参数里也不一定通用,如果条件允许尽量本地编译。
对于莫名其妙的问题,善用 StackOverFlow 和 Google 或许会有帮助,或者可能是项目本身的问题,尽量下载最近的 release 进行编译,很多时候直接编译 git master 不一定是好选择 。


关于 root 账号的配置
sudo -i 切换到 root 账号
更改 root 密码
$ synouser --setpw root password
更改 ssh 账号登录限制,修改 /etc/ssh/sshd_config (synosystemctl restart sshd 重启)
PermitRootLogin 项改为 yes
PubkeyAuthentication 项取消注释
本机修改 ~/.ssh/config
Host MyNAS HostName 192.168.50.125 Port 22 User root
上传公钥
$ ssh-copy-id -i ~/.ssh/id_ed25519.pub MyNAS
交叉编译环境配置
CMake toolchain 配置实例 (arm-unknown-linux-gnueabi.toolchain.cmake)
set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_C_COMPILER "arm-unknown-linux-gnueabi-gcc") set(CMAKE_CXX_COMPILER "arm-unknown-linux-gnueabi-g++") set(CMAKE_FIND_ROOT_PATH "/home/chumeng/cross_compile/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi/lib") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
编译命令
$ cmake -DCMAKE_TOOLCHAIN_FILE=~/cross_compile/arm-unknown-linux-gnueabi.toolchain.cmake -DCMAKE_INSTALL_PREFIX=/home/chumeng/cross_compile/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi ..
Rust 交叉编译环境
$ rustup target add armv7-unknown-linux-gnueabihf
配置文件实例 (.cargo/config.toml)
[build] target = "armv7-unknown-linux-gnueabihf" [target.armv7-unknown-linux-gnueabihf] linker = "arm-unknown-linux-gnueabi-gcc"
编译命令
$ cargo build --release --target=armv7-unknown-linux-gnueabihf
Go 交叉编译
编译命令
CC=arm-unknown-linux-gnueabi-gcc CXX=arm-unknown-linux-gnueabi-g++ AR=arm-unknown-linux-gnueabi-ar GOARM=7 GOOS=linux GOARCH=arm go build
一些必要的工作
!! 轻易不要乱动 /usr 目录 !!
本人因为乱改 /usr 重装了很多次系统,有一次提前准备了 busybox,但是是动态链接的,环境都配的差不多了,只能前功尽弃,所以提前备好一些常用工具非常重要。
交叉编译静态 rsync
$ CC=arm-linux-gnueabihf-gcc make -j32 $ prefix=~/cross_compile/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi make install
编译 zstd
$ cd build/cmake $ make build && cd build $ cmake -DCMAKE_TOOLCHAIN_FILE=~/cross_compile/arm-unknown-linux-gnueabi.toolchain.cmake -DCMAKE_INSTALL_PREFIX=/home/chumeng/cross_compile/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi .. $ make -j32 $ make install
编译 rsync
$ ./configure CFLAGS="-static" --host=arm-unknown-linux-gnueabi --prefix=/home/chumeng/rsync-static --disable-md2man --disable-openssl $ make -j32 $ arm-unknown-linux-gnueabi-strip rsync $ make install $ mv ~/rsync-static/bin/rsync ~/rsync-static/bin/rsync-static $ scp -r -O ~/rsync-static MyNAS:/root/
交叉编译静态 BusyBox
配置编译选项(.config)
# config.patch 44c44 < # CONFIG_STATIC is not set --- > CONFIG_STATIC=y 51c51 < CONFIG_CROSS_COMPILER_PREFIX="" --- > CONFIG_CROSS_COMPILER_PREFIX="arm-unknown-linux-gnueabi-"
$ git clone https://git.busybox.net/busybox $ cd busybox $ make defconfig $ patch .config config.patch
编译
$ make -j32 $ scp -r -O _install MyNAS:/root/busybox
Fish shell 配置
编译ncurses (链接非常痛苦,开发组计划去除 ncurses,这是我浪费一上午编译不出来忍无可忍发 issue 得到的答复,拉取 Remove (n)curses dependency by faho · Pull Request #10269 可解)编译
$ mkdir build $ cmake -DRust_CARGO_TARGET=armv7-unknown-linux-gnueabihf .. $ make && arm-unknown-linux-gnueabi-strip fish $ cmake --install . --prefix ~/fish
安装
$ cd ~/fish $ scp -r -O etc bin MyNAS:/ $ scp -r -O share MyNAS:/usr/local/ # Target $ mv /bin/ash /bin/ash.bak $ ln -s /bin/fish /bin/ash
添加 PATH 路径
$ mkdir -p /volume1/software/bin $ mkdir -p /volume1/software/.cargo/bin $ fish_add_path /volume1/software/bin /volume1/software/.cargo/bin /opt/bin /usr/local/bin
环境配置
改 lib 脚本
# ~/.config/fish/functions/change-lib.fish set prefix /opt function change-lib if not test "$no_change_lib" = "true" patchelf --set-rpath $prefix/usr/lib $argv end end function change-interpreter if not test "$no_change_interpreter" = "true" patchelf --set-interpreter $prefix/usr/lib/ld-linux-armhf.so.3 $argv end end function change change-lib $argv change-interpreter $argv end
安装 patchelf 以修改 ELF
系统自带的库文件版本太老,很多程序不能正常运行
$ git clone --depth=1 https://github.com/NixOS/patchelf.git $ cd patchelf $ ./bootstrap.sh $ ./configure CXXFLAGS="-static" --host=arm-unknown-linux-gnueabi --prefix=/home/chumeng/patchelf $ make -j32 $ make install-strip $ yay patchelf $ scp -r -O /home/chumeng/patchelf/* MyNAS:/
安装 Entware
命令行相关
常用软件
neovim 编辑器 opkg install neovim
git 版本管理工具 opkg install git git-http
tmux 终端复用器 opkg install tmux
nodejs JavaScript 运行环境 opkg install node node-npm
python 常用语言 参考 Entware 页面
ranger 管理文件 HOME=/volume1/software/python pip install ranger-fm
bat 替代 cat 使用 cargo 交叉编译
lazygit git GUI 使用 go 交叉编译
hyfetch 命令行系统信息工具 pip 安装
配置 dotfile
这是我的 dotfiles 仓库,可以参考一下
$ yadm clone https://github.com/lihaoze123/dotfiles
NAS 相关
ddns-go
个别 DNS 服务商无法访问,需要配置 proxy,这个没什么说的
使用 go 交叉编译
安装服务
$ ddns-go -s install $ systemctl enable ddns-go.service
修改 EnvironmentFile (ddns-go 读取不了 fish 设置的环境变量,需要配置 EnvironmentFile)
# /etc/sysconfig/ddns-go HTTP_PROXY=http://127.0.0.1:7890 HTTPS_PROXY=http://127.0.0.1:7890
Transmission
安装 参考 Using Transmission
修改 /opt/etc/transmission/settings.json 中 rpc-bind-address 项为 :: 以支持 IPv6 (首先关闭进程)
aria2
安装 参考 Using Aria2
下载 AriaNG,放在 /volume1 的子目录中
群晖自带套件 WebStation 中 网页服务门户 - 新增 - 虚拟主机 中 门户类型 选基于端口,设置端口,下一步选择网页文件放置的目录
同理选基于名称,设置域名,端口以支持域名访问
作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

dzhgd
校验提示文案
值友6921984534
校验提示文案
放牛儿
校验提示文案
开心小馒头吖
校验提示文案
爪爪酱
校验提示文案
嗯halou
校验提示文案
嗯halou
校验提示文案
爪爪酱
校验提示文案
开心小馒头吖
校验提示文案
放牛儿
校验提示文案
值友6921984534
校验提示文案
dzhgd
校验提示文案