0. 前言

个人使用 OpenWrt 多年,固件大多用的都是恩山论坛几位大佬编译好的现成固件,什么高大全,骷髅头,suninggegeg。其实用大佬编译好的固件挺好的,但是因为每个人的需求不一样。导致使用高大全固件又是总觉得太臃肿,使用一些精简版的固件又没有自己需要的插件。最后还是萌生了自己根据自己的需求去编译 OpenWrt。经过一番折腾下来也是把固件给编译出来了,这个编译过程大概需要 1-3 小时左右。

1. 环境要求

1.1 系统版本

  • 推荐是 Debian11 或者是 Ubuntu LTS 18.x 或者 20.x 、22.x

1.2 网络和配置要求

  • 编译的主机最好是境外美区的 VPS,如果要本地编译需要给编译主机配置全局国际网络环境。
  • 编译主机至少需要预留 50G 以上的硬盘空间。在编译的过程中会下载大量的依赖文件,如果硬盘空间不足或网络不稳定都可能会编译失败。
  • 编译主机配置推荐 2H4G 以上,这会减少编译等待时间。
  • 这边推荐使用腾讯或阿里按量付费港区或美区的云主机,编译完成就可以销掉云主机,可以选到较高的配置同时支出的费用也不会太多。

1.3 编译依赖安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 升级
apt update -y
apt full-upgrade -y

# 安装依赖
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 libglib2.0-dev libgmp3-dev libltdl-dev \
libmpc-dev libmpfr-dev libncurses5-dev libncursesw5-dev libreadline-dev libssl-dev libtool lrzsz \
mkisofs msmtp nano ninja-build p7zip p7zip-full patch pkgconf python2.7 python3 python3-pyelftools \
libpython3-dev qemu-utils rsync scons squashfs-tools subversion swig texinfo uglifyjs upx-ucl unzip \
vim wget xmlto xxd zlib1g-dev python3-setuptools

# 清理(可选)
sudo apt autoremove --purge
sudo apt clean

2. 开始编译

2.1 创建普通用户

  • 编译的过程一定要使用 “普通用户!” “普通用户!” “普通用户!”

  • 我这边以 Ubuntu 系统为示例,其他系统可自行百度

  • 打开终端输入下面命令,创建一个名为opwrt的普通用户

1
2
3
4
5
6
7
8
adduser opwrt

# 然后会提示输入新用户密码和再次确认密码;请设置一个符合系统规范的密码,不然系统会提示密码太简单。这里可以自行百度解决

# 切换普通用户
su opwrt
# 进入用户主目录
cd ~

2.2 拉取源码,这里使用的是 Lean 大佬的 LEDE 分支

1
2
git clone https://github.com/coolsnowwolf/lede
cd lede

2.3 添加软件源

  • L 大源码里默认有四个软件源里面包含了大部分常用插件,如果要添加其他没有的插件则需要自行添加软件源至feeds.conf.default文件,当然也可以单独添加某个插件。
  • 如果选择插件的时候没有某 s*p 请检查一下这个配置文件的Hello Word字样代码是不是被注释了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
vim feeds.conf.default

# 添加软件源(打开下方仓库链接可以查看包含的插件列表,一般选前两个源就行)
src-git kenzo https://github.com/kenzok8/openwrt-packages
src-git small https://github.com/kenzok8/small

src-git haibo https://github.com/haiibo/openwrt-packages
src-git liuran001 https://github.com/liuran001/openwrt-packages

# 单独添加(在更新并安装插件之前执行)
## 插件
git clone https://github.com/esirplayground/luci-app-poweroff.git package/luci-app-poweroff

# 更新并安装插件
./scripts/feeds clean
./scripts/feeds update -a
./scripts/feeds install -a

2.4 自定义配置

  • 这边建议和我一起执行下面的命令,可以避免出现奇奇怪怪的错误。
1
2
3
4
5
6
7
8
# 修改默认IP为 10.1.1.252
sed -i 's/192.168.1.1/10.1.1.252/g' package/base-files/files/bin/config_generate

# 修改默认主机名
sed -i '/uci commit system/i\uci set system.@system[0].hostname='Soft_Router'' package/lean/default-settings/files/zzz-default-settings

# 加入编译者信息
sed -i "s/OpenWrt /Kinoko build $(TZ=UTC-8 date "+%Y.%m.%d") @ OpenWrt /g" package/lean/default-settings/files/zzz-default-settings

2.5 配置设备和添加插件

  • 执行make menuconfig 命令进入编译菜单
1
make menuconfig
  • 请本着不懂不要乱动的原则,选择自己需要的插件。有些插件与其他插件是有冲突的,一起选中编译是一定会报错的!

a61174ffa833f.png

  • 菜单选项简要说明:
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
# 选择 CPU 类型
Target System (x86) --> # 软路由选择 x86,硬路由根据型号厂家自行选择
Subtarget (x86_64) --> # CPU 子选项
Target Profile (Generic x86/64) --> # 厂家具体型号

# 设置镜像编译的格式(squashfs,ext4)
Target Images --> # 默认 squashfs

# 添加较多插件时,为了避免空间不足,建议修改下面两项默认大小(x86/64)
Target Images --> (16) Kernel partition size (in MB) # 默认是16,建议修改为100
Target Images --> (400) Root filesystem partition size (in MB) # 默认是400,建议修改为1024

# 开启 IPv6 支持
Extra packages --> ipv6helper(选定这个后,下面几项会自动选择)
Network --> odhcp6c
Network --> odhcpd-ipv6only
LuCI --> Protocols --> luci-proto-ipv6
LuCI --> Protocols --> luci-proto-ppp

# 开启适用于 VMware 的 VMware Tools
Utilities --> open-vm-tools
Utilities --> open-vm-tools-fuse

# 选择插件
LuCI --> Applications # 根据需要选择,按键盘空格切换选中状态,* 代表编入固件,M 表示编译成模块或者IPK包,为空表示不编译

# 选择主题
LuCI --> Themes # 选择喜欢的主题,可以选多个

# 其他选项一般不需要调整,如感兴趣可以自行了解

2.6 下载软件包

  • 配置完成之后按键盘左右方向键移动光标到Save保存,然后退出菜单Exit,开始下载软件包
1
2
3
4
5
6
7
# 预下载编译所需的软件包
make download -j8
# 检查文件完整性(下面为可选操作)
find dl -size -1024c -exec ls -l {} \;
# 检查文件完整性命令可以列出下载不完整的文件,小于1k的文件属于下载不完整,如果存在则用下面的命令删除,然后重新下载编译所需的软件包,再次检查
# 确认所有文件完整可大大提高编译成功率,避免浪费时间
find dl -size -1024c -exec rm -f {} \;

2.7 开始编译固件

  • 编译完成后输出路径是bin/targets,默认密码是password
  • 很多教程都教大家使用单线程处理首次编译,我的建议是第一次直接最大线程编译,如果出错了再使用单线程编译。
  • 已经编译成功的插件系统是不会二次编译的,最大线程编译可以减少等待的时间。
1
2
3
4
# 编译固件(-j 后面是线程数,单线程)
make V=s -j1
# 自动处理编译线程,使用最大线程编译或者单线程
make -j$(nproc) || make -j1 || make -j1 V=s

2.8 OpenWrt编译成功说明

文件名 描述
sha256sums 固件完整性校验文件
packages-server.zip IPK 软件包归档
openwrt-x86-64-generic.manifest 固件内已集成软件包列表
openwrt-x86-64-generic-generic-rootfs.tar.gz RootFS 文件
openwrt-x86-64-generic-rootfs-ext4.img.gz 不带引导的 RootFS 镜像
openwrt-toolchain-x86-64_gcc-8.4.0_musl.Linux-x86_64.tar.bz2 OpenWrt 工具链
openwrt-sdk-x86-64_gcc-8.4.0_musl.Linux-x86_64.tar.xz OpenWrt SDK
openwrt-imagebuilder-x86-64.Linux-x86_64.tar.xz OpenWrt Image Builder
openwrt-x86-64-generic-squashfs-combined.vdi VDI 虚拟磁盘映像 (Legacy 引导)
openwrt-x86-64-generic-squashfs-combined.vmdk VMDK 虚拟磁盘映像 (Legacy 引导)
openwrt-x86-64-generic-squashfs-combined-efi.vdi VDI 虚拟磁盘映像 (UEFI 引导)
openwrt-x86-64-generic-squashfs-combined-efi.vmdk VMDK 虚拟磁盘映像 (UEFI 引导)
openwrt-x86-64-generic-squashfs-combined.img.gz Squashfs 格式安装 / 升级固件 (Legacy 引导)
openwrt-x86-64-generic-squashfs-combined-efi.img.gz Squashfs 格式安装 / 升级固件 (UEFI 引导)

3. 二次编译

  1. 拉取最新 OpenWrt 源码和更新 feeds 源中的软件包源码
1
2
3
4
cd lede
git pull
./scripts/feeds update -a
./scripts/feeds install -a
  1. 清除旧的编译产物和目录(可选)
1
2
3
4
5
6
7
make clean
# 源码有大规模更新或者内核更新后执行,以保证编译质量
# 此操作会删除 /bin 和 /build_dir 目录中的文件

make dirclean
# 更换架构编译前必须执行
# 此操作会删除 /bin 和 /build_dir 目录的中的文件(make clean),以及 /staging_dir、/toolchain、/tmp 和 /logs 中的文件
  1. 同首次编译,多线程编译失败后自动进入单线程编译,失败则输出详细日志
1
2
3
4
5
6
7
8
9
10
11
make defconfig
make download -j8
find dl -size -1024c -exec ls -l {} \;
make -j$(nproc) || make -j1 || make -j1 V=s

# 如果需要重新配置
rm -rf ./tmp && rm -rf .config # 清除临时文件和编译配置文件
make menuconfig
make download -j8
find dl -size -1024c -exec ls -l {} \;
make -j$(nproc) || make -j1 || make -j1 V=s

4.OpenWrt 编译的奇技淫巧——编译指定版本Op

lede这个库一直都是走在 openwrt 官方前面的,如果直接拉去代码编译都是 Openwrt 的最新版。新的版本往往可能存在一些奇怪的问题,比如下载插件时候自己编译的版本高于官方版本导致安装失败、新版有些特性对于一些插件存在奇怪的兼容性问题的时候,就需要编译几乎和官方同稳定版的 OpenWrt 了。

一下方法都是参考 Github 和恩山论坛的内容:

  1. 拉取lede仓库指定提交记录

    这里需要查看官方最新稳定版的发布时间和内核版本,根据官方的更新时间和内核版本去定位到lede提交版本。

    例如,官方最新的稳定版是OpenWrt 23.05.0-rc4内核版本5.15.134发布时间是 2023-10-13 OpenWrt 23.05.0。那么就去lede仓库中找到内核版本相差不多的那条提交记录。

    image-20231118220928363

  2. 使用 git 命令根据提交记录创建一个编译分支

    1
    2
    # 创建并切换到 byop 分支上
    git checkout -b byop 21c3e8e4a1d391a6244ebc854e41d07654ea5e80
  3. 修改lede/target/linux/x86/Makefile

    1
    2
    # 这个值为你想要的内核大版本 x.xx.x 中最后一个x最好让系统来决定;这能尽量避免报错
    KERNEL_PATCHVER:=6.15 改成 5.15

    接下来就是正常的编译环节了,这个编译指定版本的方法并不保证一定有效,请自行尝试。

5. 参考文档

6. 碎碎念

  • 这里需要特别提醒,就现在这个时间点来说不要想着去嫖 Github 的 Actions 来编译了。GitHub 提供的机器存储完全不够用来编译加了很多软件源的 OpenWrt。

支持的运行器和硬件资源

a4e94b66f06cc.png