
编译 OpenWrt 官方固件

示例环境
本文默认你能访问所有互联网环境。如果遇到任何问题,请搜索相关项目文档以及Google。
- OpenWrt版本: 23.05.5
- 目标设备: TP-Link TL-XDR6088
- 编译系统: ArchLinux
- 磁盘: 至少 20G
- 内存: 推荐 16G 以上
- CPU: 越快越好
环境搭建
准备工作
首先,在 https://github.com/openwrt/openwrt 中找到你需要构建的版本,如 v23.05.5
。然后替换以下命令中的 <tag>
为你需要的版本号。
1 | $export OPENWRT_VER=<tag> |
然后在 https://openwrt.org/toh/start 中搜索你的设备型号,点击搜索结果后的 Edit
进入详细页面。找到 Dataentry
中的 Target
和 Subtarget
替换到下面的命令中。
1 | $export OPENWRT_TARGET=<Target> |
确保你设置的变量都正确无误,后面会频繁用到。
拉取源码
1 | $git clone -b $OPENWRT_VER --single-branch https://www.github.com/openwrt/openwrt |
或者拉取整个仓库
1 | $git clone https://github.com/openwrt/openwrt |
之后的所有操作都在 openwrt
目录下进行。
Docker 环境搭建
安装 Docker
1 | # 安装 |
Dockerfile
官方提供用来编译固件的镜像不太好用,所以我们来自己构建一个。在 openwrt
目录下创建一个 Dockerfile
文件,内容如下:
1 | FROM ubuntu:24.10 |
编译镜像并启动
1 | $docker build -t openwrt. |
此时你已经进入容器了,执行 ./setup.sh
拉取源码,并执行 apt-get update && apt-get install vim
安装编辑器。之后的步骤参考下面的本机环境搭建。
本机环境搭建
本文示例环境为 Archlinux,所以默认你拥有 Linux 系统。
如果你是 Windows 用户,参考这个 文档安装 WSL,并按照此文档进行额外设置。
如果你是 MacOs 用户,请参考此处部署构建环境。
安装依赖
在 Build system setup 中找到自己系统对应的发行版依赖设置,按照文档中的说明安装即可。
这里以 Arch/Manjaro/EndeavourOS 为例,如果你安装了 yay
或 paru
可以直接从 AUR 中安装 openwrt-devel
包:
1 | $yay -S openwrt-devel |
或者手动安装所有依赖
1 | # 必选依赖项 |
添加并更新软件包
使用 feeds.conf.default
定义软件包的文件是feeds.conf.default
。通常你还需要添加一些额外的软件包,比如kenzok8。找到你希望添加的仓库,然后执行
1 | $echo 'src-git kenzo https://github.com/kenzok8/openwrt-packages feeds.conf.default |
手动拉取
你也可以使用 git clone
命令手动拉取软件包到 package
目录下。
1 | $git clone https://github.com/kenzok8/openwrt-packages package |
更新软件包
在每次对软件包进行修改后,都需要对其进行更新。
1 | $./scripts/feeds update -a |
可能的 Golang 版本问题
在选择部分软件包后,编译时可能会导致 Go 版本冲突,提示类似如下:
1 | go: .... requires go >= 1.22 (running go 1.21.5; GOTOOLCHAIN=local) |
此时需要在更新软件包后手动拉取符合条件的 Go 版本:
1 | $rm -rf feeds/packages/lang/golang |
修改源码
vermagic
自己编译的固件 vermagic
很可能和官方的不一致,此时 OpenWrt 无法使用 opkg install
安装任何包。所以我们需要手动获取 vermagic
值。
1 | $curl -s https://downloads.openwrt.org/releases/${OPENWRT_VER#v}/targets/$OPENWRT_TARGET/$OPENWRT_SUBTARGET/openwrt-${OPENWRT_VER#v}-$OPENWRT_TARGET-$OPENWRT_SUBTARGET.manifest | grep kernel | awk '{print $3}' | awk -F- '{print $3}' > vermagic |
手动获取 vermagic
值的方式见此处。
修改 vermagic 获取方式
我们还需要修改源码中 vermagic 的获取方式,让他设置为我们刚刚获取到的 vermagic
值。
1 | # 编辑配置文件 |
修改后的代码如下所示
1 | # grep '=[ym]' $(LINUX_DIR)/.config.set | LC_ALL=C sort | $(MKHASH) md5 > $(LINUX_DIR)/.vermagic |
修改时区
1 | # 编辑配置文件 |
修改后的代码如下所示
1 | set system.@system[-1].hostname='OpenWrt' |
修改IP
1 | # 设置一个自己希望的IP地址 |
配置和编译
如果你不确定一个模块的作用,那么就不要取消任何默认选中的模块。
OpenWrt 的编译配置比较复杂,需要你了解你当前设备所需要的软件包,不过你也可以直接使用官方配置并在此基础上进行修改。
1 | # 拉取官方配置 |
在拉取了官方配置后,此时你就拥有了和官方一致的配置文件,此时直接编译就能得到和官方一致的固件。
但是官方配置中,默认情况下会编译当前架构下所有设备的固件,在大多数情况下我们只需要编译我们拥有的设备的固件。此外,你可能还需要添加一些额外的软件包。
使用菜单进行配置
执行以下命令打开配置菜单。
1 | make menuconfig |
菜单中的操作如下
按键 | 功能 |
---|---|
↑|↓ |
切换模块 |
Y |
选中模块 |
N |
取消选中模块 |
M |
选中模块但是不编译进内核,选中的模块会单独编译 |
/ |
搜索模块 |
←|→ |
切换下方子菜单 |
Enter |
选择子菜单 |
ESC``ESC |
退出 |
? |
帮助 |
模块的选中状态如下,模块前面的括号可能是 [ ]
, { }
, < >
。
1 | [ ] 被排除的模块 |
注意 { }
的模块只能选择是否被编译进内核,不能取消。
选择具体设备
之前说过,OpenWrt 官方的默认配置会编译当前架构下的所有设备的固件,因此我们需要在 Target Profile
中选择自己的设备型号。
LuCI
LuCI是一个OpenWrt的Web框架,大部分常用工具都有更便捷的LuCI版本,让我们通过Web网页就能完成大部分设置。
如果你需要使用LuCI的包,那么我还推荐你选择这些模块:
1 | LuCI |
之后就可以在 Applications
和 Themes
中选择喜欢的主题和应用。
其他常用包
以下包是我在 TL-XDR6088
上常用的软件包,可以按需选择。注意官方配置中有些模块是不被编译进内核的。
1 | Base system |
编译
如果你在编译中遇到了错误,那么你最好使用 make clean
来清理编译环境,然后重新编译。
因为遇到错误时,很可能会出现一些编译到一半的文件,在下次编译时就会认为这些文件已经被编译过了。
在编译之前,我们最好先下载所有依赖的源码,这能提升编译的成功率。
1 | # 进行单核下载 |
在下载完成后,我们就可以开始编译了。和下载类似,编译也支持多核编译。
1 | $make -j$(nproc) V=s |
如果你不希望编译时占用过多的资源,那么可以参考如下命令让其只使用4和核心和空闲资源进行编译(注意,这可能会让构建时间变得非常长)。
1 | # 将编译输出到 build.log,并且输出包含 error 的日志到屏幕。 |
推荐优先使用多核编译,但是如果在编译过程中遇到问题,并且不能通过日志来确定错误原因,那么最简单的方式是使用单核编译(注意,这可能会让构建时间长达6小时以上)。
1 | $make V=s |
在编译完成后,在 bin/targets/<target>/<subtarget>
下就能找到编译好的固件。
参考
OpenWrt 编译说明
OpenWrt Snapshots 编译 xray-core & xray-plugin 1.8.8 提示需要 golang 1.22.0 版本的解决方法
使用 OpenWrt 23.05.5 官网源码编译固件
Docker OpenWrt Image Generation
Quick image building guide
Build system essentials
Build system usage