😡人生苦短,不要折腾Openwrt编译,编译不好往往不是你的问题,是源码混乱,网络狗屎,依赖管理差的问题
阅读本文前提 一点点Linux基础使用 一点点脑子 一点点git使用 非常不错的科学上网环境 家里有矿,闲得发慌 本地编译 准备Linux环境 Ubuntu 20.04 LTS最佳
安装必需软件 1 sudo apt full-upgrade -y
1 2 3 4 5 6 7 8 sudo apt install -y ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \ bzip2 ccache cmake cpio curl device-tree-compiler fastjar flex gawk gettext gcc-multilib g++-multilib \ git gperf haveged help2man intltool libc6-dev-i386 libelf-dev libfuse-dev libglib2.0-dev libgmp3-dev \ libltdl-dev libmpc-dev libmpfr-dev libncurses5-dev libncursesw5-dev libpython3-dev libreadline-dev \ libssl-dev libtool lrzsz mkisofs msmtp ninja-build p7zip p7zip-full patch pkgconf python2.7 python3 \ python3-pyelftools python3-setuptools qemu-utils rsync scons squashfs-tools subversion swig texinfo \ uglifyjs upx-ucl unzip vim wget xmlto xxd zlib1g-dev
拉取源码 使用git clone拉取源码
源码仓库
lede :
https://github.com/coolsnowwolf/lede
immortalwrt :
https://github.com/immortalwrt/immortalwrt
openwrt:
https://github.com/openwrt/openwrt
添加软件源 每个仓库都有自己维护的软件源,里面不一定有需要的
这时候需要通过添加自定义源来加入更多软件
sed -i "<n>i src-git 名称 github仓库链接" feeds.conf.default
例如kenzo8的软件源
https://github.com/kenzok8/openwrt-packages
1 2 sed -i '1i src-git kenzo https://github.com/kenzok8/openwrt-packages' feeds.conf.default sed -i '2i src-git small https://github.com/kenzok8/small' feeds.conf.default
更新并安装软件源 更新软件源
1 ./scripts/feeds update -a
安装软件源
1 ./scripts/feeds install -a
修改配置 图形化修改配置项
整个界面预览
图左上角为配置所在路径以及配置文件名称
最下面的菜单栏,使用左右键选择功能,回车键使用功能
其他四个选项用的比较少,都是顾名思义,不需要解释了,重点看看<Select>
<Select>
选择上下键选择配置,使用回车键进入二级目录,使用空格键修改参数状态,也可以使用Y/N/M
包含/排除/模块化也就是编译不加入
参数状态说明
[*]
编译加入
[ ]
编译排除
< >
编译排除
<M>
编译但不加入
<*>
编译并加入
使用/
搜索配置项
Help中有详细说明
使用数字键跳转对应配置路径 支持模糊搜索默认为搜索包含字符串的配置项 ^字符串
表示搜索已字符串开头的配置项字符串$
表示搜索已字符串结尾的配置项 两次<ESC>
用于回到上个界面
<?>
可以查看当前选择的配置项的说明
具体各个配置说明
一般首先需要修改
Target System 硬件架构 例如x86
Subtarget 处理器名称 例如n100
Target Profile 编译配置具体默认机器配置 一般 Multiple Deivces 表示该处理器型号所有机器都编译一遍
Target Images 编译固件类型 以及一些固件配置(固件最大大小等等)
谨慎修改
Enable experimental features by default 默认启用实验功能 Global build settings —> 全局构建设置 —> 高级打包配置,例如内核配置,一般不需要修改,除非想使用测试版内核或者一些高级打包配置
开发者使用的部分设置 Advanced configuration options (for developers) —> 高级配置选项 (供开发者使用) —> Build the OpenWrt Image Builder 构建 OpenWrt 固件生成器 Build the OpenWrt SDK 构建 OpenWrt SDK Package the OpenWrt-based Toolchain 打包OpenWrt基础工具链
个性化配置项 Image configuration —> 固件信息配置 —> 用于配置固件名称,默认IP,包含软件源等等 Base system —> 基本系统 —> Openwrt系统基础工具,例如busybox,dnsmasq,opkg,uci 等等 Administration —> 管理 —> Linux一些管理使用的工具配置,包含sudo,htop等常见工具 Boot Loaders —> 引导加载程序 —>boot引导编译配置,一般我们使用Github中发布的版本即可,除非你有自行修改boot的需求,小白不要碰 Development —> 开发 —> 开发者使用的工具编译选择,一边我们不需要选择,也不用管里面的内容,这个是用来编译开发相关工具使用的,例如gcc,make等等Extra packages —> 额外软件包 —> 额外软件包,里面可以选择额外的软件配置,例如ipv6-helper 可以一键帮你配置ipv6的配置项,autosamba(自动配置SMB共享),automount (自动挂载),Nginx(网页服务器)等等 Firmware —> 硬件驱动 —> 在这里选择需要的WIFI驱动等等(一般默认配置就有,x86除外) Fonts —> 字体 —> Kernel modules —> 内核模块 —> 一些内核依赖配置,也是一般不需要手动修改, Languages —> 语言 –→ 指的是编译语言,例如C++,GoLang ,Nodejs等等,用于语言相关配置,当需要xxx语言提供的工具时需要修改该配置,正常情况下无需修改 Libraries —> 库 —> 依赖库,很重要,但是我们一般不要手动改,容易出问题
我们重点需要修改的地方 LuCI —> LuCI —> WebUI界面的配置项,也就是我们配置后台插件的地方
Mail —> 邮件 —> 不了解,应该邮件服务器系统的核心文件配置 Multimedia —> 多媒体 —> 多媒体相关的核心文件配置,例如ublock - netease music 的核心文件配置Network —> 网络 —> 网络核心文件配置,DNS/VPN/Firewall等等网络相关的核心文件配置都在此处,一些网络工具也可以在此处配置例如tcping等 Sound —> 声音 –→ 顾名思义
Utilities —>Linux 工具 grep,ack等等
Xorg—>字体工具
设置路由器默认的 LAN IP
1 2 sed -i 's/192.168.1.1/192.168.10.1/g' package/base-files/files/bin/config_generate
替换默认主题
1 2 sed -i 's/luci-theme-bootstrap/luci-theme-argon/' feeds/luci/collections/luci/Makefile
预下载工具 1 make download -j$(nproc )
首次编译 1 make -j$(nproc ) || make -j$(nproc ) V=s
⚠️ 部分人可能会添加`V=s`产生来输出详细的日志,但是不好观察编译进度,出现错误后再次运行一遍带`V=s`参数的编译命令即可 如何排错 最后报错Error2,我们就从上往下 翻,看到第一个Error就停下,然后回退大概Error看看上面几行是什么内容(可以直接将日志复制到文本编辑器,然后用Ctrl+F
搜索日志Error
)
例子1:
比如编译lede固件加入adguardhome报错信息如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Finding targets go: ../../go.mod requires go >= 1.22.4 (running go 1.22.1; GOTOOLCHAIN=local ) Building targets go: ../../go.mod requires go >= 1.22.4 (running go 1.22.1; GOTOOLCHAIN=local ) make[3]: *** [Makefile:87: /workdir/openwrt/build_dir/target-aarch64_cortex-a53_musl/adguardhome-0.107.51/.built] Error 1 make[3]: Leaving directory '/workdir/openwrt/feeds/kenzo/adguardhome' time: package/feeds/kenzo/adguardhome/compile ERROR: package/feeds/kenzo/adguardhome failed to build. make[2]: *** [package/Makefile:116: package/feeds/kenzo/adguardhome/compile] Error 1 make[2]: Leaving directory '/workdir/openwrt' make[1]: *** [package/Makefile:110: /workdir/openwrt/staging_dir/target-aarch64_cortex-a53_musl/stamp/.package_compile] Error 2 make[1]: Leaving directory '/workdir/openwrt' make: *** [/workdir/openwrt/include/toplevel.mk:231: world] Error 2
此时我们需要关注的内容只有
1 2 3 4 5 6 7 8 Finding targets go: ../../go.mod requires go >= 1.22.4 (running go 1.22.1; GOTOOLCHAIN=local ) Building targets go: ../../go.mod requires go >= 1.22.4 (running go 1.22.1; GOTOOLCHAIN=local ) make[3]: *** [Makefile:87: /workdir/openwrt/build_dir/target-aarch64_cortex-a53_musl/adguardhome-0.107.51/.built] Error 1 make[3]: Leaving directory '/workdir/openwrt/feeds/kenzo/adguardhome'
显然提示需要go版本大于等于1.22.4,但我们的版本是1.22.1所以出错了,出错的地方是feeds/kenzo/adguardhome 这个源码,这时候我们有两种解决方案
解决提出问题的人 把adgardhome移除,比较暴力,但是最有效哈哈哈 解决问题 将go语言版本换成相应版本(不一定能解决,可能导致其他依赖报错) 例子2:
编译hysteria依赖报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Finding targets Building targets ../../../../../dl/go-mod-cache/github.com/apernet/quic-go@v0.44.1-0.20240520215222-bb2e53664023/http3/client.go:8:2: package log /slog is not in GOROOT (/workdir/openwrt/staging_dir/hostpkg/lib/go-cross/src/log/slog) ../../../../../dl/go-mod-cache/github.com/apernet/quic-go@v0.44.1-0.20240520215222-bb2e53664023/internal/wire/transport_parameters.go:10:2: package slices is not in GOROOT (/workdir/openwrt/staging_dir/hostpkg/lib/go-cross/src/slices) make[3]: *** [Makefile:62: /workdir/openwrt/build_dir/target-aarch64_cortex-a53_musl/hysteria-app-v2.4.5/.built] Error 1 make[3]: Leaving directory '/workdir/openwrt/feeds/small/hysteria' time: package/feeds/small/hysteria/compile ERROR: package/feeds/small/hysteria failed to build. make[2]: *** [package/Makefile:120: package/feeds/small/hysteria/compile] Error 1 make[2]: Leaving directory '/workdir/openwrt' make[1]: *** [package/Makefile:114: /workdir/openwrt/staging_dir/target-aarch64_cortex-a53_musl/stamp/.package_compile] Error 2 make[1]: Leaving directory '/workdir/openwrt' make: *** [/workdir/openwrt/include/toplevel.mk:230: world] Error 2
需要关注的地方
1 2 3 4 5 6 7 8 Finding targets Building targets ../../../../../dl/go-mod-cache/github.com/apernet/quic-go@v0.44.1-0.20240520215222-bb2e53664023/http3/client.go:8:2: package log /slog is not in GOROOT (/workdir/openwrt/staging_dir/hostpkg/lib/go-cross/src/log/slog) ../../../../../dl/go-mod-cache/github.com/apernet/quic-go@v0.44.1-0.20240520215222-bb2e53664023/internal/wire/transport_parameters.go:10:2: package slices is not in GOROOT (/workdir/openwrt/staging_dir/hostpkg/lib/go-cross/src/slices) make[3]: *** [Makefile:62: /workdir/openwrt/build_dir/target-aarch64_cortex-a53_musl/hysteria-app-v2.4.5/.built] Error 1 make[3]: Leaving directory '/workdir/openwrt/feeds/small/hysteria'
此时如果发现问题我们看不懂,就把内容复制到GPT问就行了
当然也有可能GPT给出的解决方案并不能够解决问题,我们需要自行Google搜索一下
⚠️ 绝大多数问题都是依赖版本不兼容导致的,引入软件时检查依赖是否冲突!!! 以上问题也是两种解决方法
移除hysteria依赖 找到slog/slices所需的go版本并替换(不一定能解决,可能导致其他依赖报错) 例子3:
路径中包含空格
1 2 3 4 5 6 find : The relative path 'Files/Bandizip/' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATHmake[2 ]: *** [package/Makefile :73 : package/install] Error 1 make[2 ]: Leaving directory '/home/insider/lede' make[1 ]: *** [package/Makefile :111 : /home/i nsider/lede/staging_dir/target-aarch64_cortex-a53_musl/stamp/.package_install ] Error 2 make[1 ]: Leaving directory '/home/insider/lede' make : *** [/home/i nsider/lede/include/toplevel.mk :231 : world] Error 2
WSL编译 如果你是使用WSL编译,由于 WSL 的 PATH 中包含带有空格的 Windows 路径,有可能会导致编译失败,也就是上面的报错,请使用
1 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin make -j$(nproc )
如果你新添加软件源,百分之99的问题是依赖冲突导致的,如果没有添加,那么百分之99是你网络太烂了,连接不上Github仓库,你能访问≠你连接上了,github.com和github的内容分发仓库不是一个域名,有些时候域名不一样,可能被GFW屏蔽了,剩下的才有可能是上游源码BUG
二次编译 更新源码
更新软件源
1 ./scripts/feeds update -a &&./scripts/feeds install -a
只是修改软件配置
修改架构,例如x86→MTK ARM
从头开始修改配置
1 rm -rf ./tmp && rm .config && rm .config.old
下载软件包
1 make download -j$(nproc )
编译固件
添加单独软件包(进阶) 1 git clone <软件包项目地址> package/<软件包名>
单独编译软件(进阶) 1 make ./package/<软件包名>/compile
编译完成 在./bin/target/*/*
. 目录中寻找固件
云编译 😋 Github公共资源有限,请大家不要滥用
当你完成了本地编译,确认配置无误,固件正常使用后 可以尝试云编译节省本地资源占用,同时可以用于固件同步上游源码使用,或者是你的电脑性能太差了,网络环境太差了,你想要使用云资源解决,那么当你make menuconfig
完成后可以使用云编译(调试报错起来非常麻烦),我认为此时你应该去挣钱买更好的电脑和梯子而不是编译Openwrt😓
https://github.com/P3TERX/Actions-OpenWrt
使用该模板创建仓库
修改.github/workflows/openwrt-builder.yml
为以下配置,根据其中注释信息自行修改配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 name: OpenWrt Builder on: repository_dispatch: workflow_dispatch: env: REPO_URL: https://github.com/coolsnowwolf/lede REPO_BRANCH: master FEEDS_CONF: feeds.conf.default CONFIG_FILE: .config DIY_P1_SH: diy-part1.sh DIY_P2_SH: diy-part2.sh UPLOAD_BIN_DIR: false UPLOAD_FIRMWARE: true TZ: Asia/Shanghai jobs: build: runs-on: ubuntu-20.04 steps: - name: Checkout uses: actions/checkout@main - name: 安装环境 env: DEBIAN_FRONTEND: noninteractive run: | sudo rm -rf /etc/apt/sources.list.d/* /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL sudo docker image prune --all --force sudo -E apt-get -qq update sudo -E apt-get -qq install ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential bzip2 ccache cmake cpio curl device-tree-compiler fastjar flex gawk gettext gcc-multilib g++-multilib git gperf haveged help2man intltool libc6-dev-i386 libelf-dev libfuse-dev libglib2.0-dev libgmp3-dev libltdl-dev libmpc-dev libmpfr-dev libncurses5-dev libncursesw5-dev libpython3-dev libreadline-dev libssl-dev libtool lrzsz mkisofs msmtp ninja-build p7zip p7zip-full patch pkgconf python2.7 python3 python3-pyelftools python3-setuptools qemu-utils rsync scons squashfs-tools subversion swig texinfo uglifyjs upx-ucl unzip vim wget xmlto xxd zlib1g-dev sudo -E apt-get -qq autoremove --purge sudo -E apt-get -qq clean sudo timedatectl set-timezone "$TZ" sudo mkdir -p /workdir sudo chown $USER:$GROUPS /workdir - name: 拉取源码 working-directory: /workdir run: | df -hT $PWD git clone $REPO_URL -b $REPO_BRANCH openwrt ln -sf /workdir/openwrt $GITHUB_WORKSPACE/openwrt - name: 执行DIY_P1_SH run: | [ -e $FEEDS_CONF ] && mv $FEEDS_CONF openwrt/feeds.conf.default chmod +x $DIY_P1_SH cd openwrt $GITHUB_WORKSPACE/$DIY_P1_SH - name: 更新软件源 run: cd openwrt && ./scripts/feeds update -a - name: 安装软件源 run: cd openwrt && ./scripts/feeds install -a - name: 加载CONFIG_FILE并执行DIY_P2_SH run: | [ -e files ] && mv files openwrt/files [ -e $CONFIG_FILE ] && mv $CONFIG_FILE openwrt/.config chmod +x $DIY_P2_SH cd openwrt $GITHUB_WORKSPACE/$DIY_P2_SH - name: 下载Package id: package run: | cd openwrt make defconfig make download -j8 find dl -size -1024c -exec ls -l {} \; find dl -size -1024c -exec rm -f {} \; - name: 编译固件 id: compile run: | cd openwrt echo -e "$(nproc) thread compile" make -j$(nproc) || make -j1 || make -j1 V=s echo "status=success" >> $GITHUB_OUTPUT grep '^CONFIG_TARGET.*DEVICE.*=y' .config | sed -r 's/.*DEVICE_(.*)=y/\1/' > DEVICE_NAME [ -s DEVICE_NAME ] && echo "DEVICE_NAME=_$(cat DEVICE_NAME)" >> $GITHUB_ENV echo "FILE_DATE=_$(date +"%Y%m%d%H%M")" >> $GITHUB_ENV - name: 检查空间占用 if: (!cancelled()) run: df -hT - name: 上传bin文件夹 uses: actions/upload-artifact@main if: steps.compile.outputs.status == 'success' && env.UPLOAD_BIN_DIR == 'true' with: name: OpenWrt_bin${{ env.DEVICE_NAME }}${{ env.FILE_DATE }} path: openwrt/bin - name: 进入bin/targets移除Packages编译文件 id: organize if: env.UPLOAD_FIRMWARE == 'true' && !cancelled() run: | cd openwrt/bin/targets/*/* rm -rf packages echo "FIRMWARE=$PWD" >> $GITHUB_ENV echo "status=success" >> $GITHUB_OUTPUT - name: 上传bin/targets中的文件 uses: actions/upload-artifact@main if: steps.organize.outputs.status == 'success' && !cancelled() with: name: OpenWrt_firmware${{ env.DEVICE_NAME }}${{ env.FILE_DATE }} path: ${{ env.FIRMWARE }}
Actions→选择相应workflows→Run workflows 没有报错的话等待1h左右就能从actions中下载打包好的编译文件
详细关于Github Workflows玩法,敬请期待( 画饼中)
编译过程中的一些坑 版本选择 编译前请先使用git log
查看更新日志,如果发现大更新,请立即回退上个版本
例如大雕在这个版本加入6.1内核,千万先别用,过段时间再更新,先回退,否则就是纯纯小白鼠
实现git checkout
命令就能回退了
如果想切换回主线版本就使用git checkout master
可以回到主分支,再使用git pull
更新源码即可
feeds安装过程中警告缺少依赖 make menuconfig
的时候如果啥都没有请忽略,如果有就复制完整日志向仓库提供iusse
编译完成后想精简部分组件 不熟悉的小伙伴前往别直接make menuconfig继续编辑,此时你取消luci的组件不会自动取消一些核心文件,导致处理luci全编译了,精简了但是没完全精简,只是没了最小的界面组件
熟悉的话可以查看该luci组件的仓库一般会提供依赖关系,通过/
在make menuconfig界面查找不需要的依赖文件并取消勾选
不熟悉的就rm .config&&rm .config.old
然后再重新make menuconfig
但是如果是默认配置提供的配置,你就只能使用上面那种方式删除不必要的组件了
make download过程中卡在utils-linux上 说明大概率是网络环境问题,编译过程中请全程保持稳定的科学上网环境
想回退到一开始拉取源码的仓库状态 暴力的方法就是rm -rf
然后git clone
比较干净
据说make distclean
就可以了,我感觉不够彻底哈哈哈,被不小心删除的文件不会变回来
依赖冲突我该如何解决 删除冲突组件 向作者仓库提iusse 二次编译命令的顺序问题 是先进行make menuconfig
再进行make clean
然后才make