为什么要自己编译OpenWrt

自己编译OpenWrt有以下几个原因:

  • 定制:用户可以根据自己的需求选择安装哪些软件包,从而使得固件文件的大小更小。

  • 更新:如果你想使用最新的内核版本或者其他软件,可以自己编译。

  • 安全:如果你想确保自己的设备安全,可以通过自己编译的方式保证固件不存在漏洞。

  • 学习:编译固件对于理解系统工作原理是一个很好的机会。

总的来说,自己编译OpenWrt可以让用户更好地控制设备,并且有助于提高技能。

为什么又不推荐自己编译OpenWrt

我并不希望用户自行编译OpenWrt的固件,反而希望用户使用官网现成提供的固件,原因如下:

  1. 自行编译与官方编译的固件在执行效率上没有差别

    一般来说,官方更推荐我们使用ImageBuilder(固件生成器)去生成固件,固件生成器被用于仅次于源码交叉编译的方法,用于:

    • 在较小的固件中容纳更多软件

    • 设备仅有 32MB 或更少的 RAM,并且 没有opkg功能

    使用固件生成器可以避免因不合理的配置导致的额外系统资源占用和降低系统运行效率的可能性。

    如果只想编译某个软件,也可以尝试使用OpenWrt SDK,这样可以节省部署编译环境期间的用时。

  2. 自行编译OpenWrt固件需要花费大量的时间和精力

    自行编译OpenWrt固件需要花费30分钟到3个小时不等的时间,这不仅对计算机配置有要求,更需要用户有足够的耐心去排错和补充依赖,

    由于众所周知中国国际互联网拥堵和管制情况,会使编译失败率惊人的高,且国内镜像源并不能解决此问题,因为在编译初我们虽然可以使用国内镜像的feeds,但是feeds中各个组件需要通过git去获取源码,这并不是几个镜像就可以解决的事情

    而且,增加的功能越多,编译成功的概率将会越低,且不可避免的使固件包容量变大。

  3. 需要有Linux基础

    编译操作需要在兼容的Linux发行版本中进行,或者您可以使用特殊发行版本并自行解决依赖问题。

    注:官方推荐交叉编译操作系统为Ubuntu版本为18.04、20.04和22.04,同时您也可以使用CentOS系统进行,但是官方的文档较少

综上所述,如果没有特别需求,我并不希望用户自行编译OpenWrt固件,但是如果存在(不仅限于)以下几种情况,只能选择自行编译这一种方式:

  • 相较于通用固件,有较大的差异以至于无法启动OpenWrt,例如您使用的设备使用的是相对冷门的硬件,例如一些冷门的以太网接口,或您使用的设备需要其他特殊支持,例如增加人体交互设备支持、大容量存储以及更多的硬盘格式支持;

  • 希望深度定制或优化代码;

  • 所使用的的软件需要内核或驱动支持才可运行

前期准备

电脑或者虚拟机(最好是Debian或者Ubuntu,本文以Ubuntu为例)

编译步骤(建议全局科学)

配置编译所需环境

1
sudo apt-get install subversion g++ zlib1g-dev build-essential git python3 python3-distutils rsync man-db libncurses5-dev gawk gettext unzip file libssl-dev wget zip time libssh-dev 

建议提前更新下系统软件:

1
2
sudo apt update
sudo apt upgrade

下载源码

1
2
git clone https://github.com/openwrt/openwrt.git
sudo chmod 777 openwrt #给到最高权限

添加所需应用

建议一次性整理好需要编译的程序,一次性添加好,每次来回操作很浪费时间!

本文以编译luci-theme-argon主题为例:

依次运行以下命令:

1
2
cd openwrt/package
git clone https://github.com/jerrykuku/luci-theme-argon.git

接着运行以下命令:

1
2
3
./scripts/feeds clean
./scripts/feeds update -a
./scripts/feeds install -a

配置

输入:

1
make menuconfig

界面基本操作说明:

  • 上下方向键来选择项目,左右方向键选择退出和保存;

  • 如果要编译插件写入固件,请按 Y

  • 如果只编译不写入固件,请按 M

  • 如果不编译或者取消已经内置的选择,请按 N

简单选择一下:

  1. 选择 Target System ,我是x86的,选择x86

  2. 选择 Subtarget ,选择 x86_64,也是根据自己机型进行选择;

    Generic 仅适用于32位硬件(旧硬件或某些Atom处理器),应为i586 Linux体系结构,将在Pentium 4及更高版本上运行。仅当您的硬件无法运行64位版本时才使用此功能。

    Legacy 用于奔腾4之前的非常旧的PC硬件,在Linux体系结构支持中称为i386。它会错过许多现代硬件上想要/需要的功能,例如多核支持以及对超过1GB RAM的支持,但实际上会在较旧的硬件上运行,而其他版本则不会。

  3. 添加管理界面:选择 Image Configuration 下的 LuCI - Collections

  4. 如果要添加一个中文语言包,选择 Modules - Translations

  5. 来到 Themes , 选择 luci-theme-argon

  6. 选择 Save 并退出。

    这边强烈建议仔细看每一项设置,如果少选了组件或者核心,非常容易出问题!

其他设置一般不用动,可以参考:

编译配置选项 含义
Target System (x86) 目标平台,例如一般 Windows 系统均为 X86 系统架构,嵌入式路由器通常有ARM、MIPS系统和博通系统等
Target Images 编译生成物控制,根据目标平台不同选项不同。例如根文件系统格式、 内核空间大小和是否生成VMware或VirtualBox映像文件等
Global build settings 全局编译设置,例如是否打开内核namespace等
Advanced configuration option (for developers) 针对开发人员的高级配置选项,包含设置下载文件目录、编译 log 和外 部编译工具目录等
Build the OpenWrt SDK 是否生成 OpenWrt 的软件开发包,这样就可以离开 OpenWrt 整体环境 而进行模块编译和增加功能
Image configuration 固件生成的软件包模块,即是否打开 feed.conf 中的各个模块
Base system OpenWrt 基本系统。包括 OpenWrt 的基本文件系统 base-files 模块、实 现 DHCP 和 DNS 代理的 dnsmasq 模块、软件包管理模块 opkg、通用库 ubox、系统总线 ubus 和防火墙 firewall,等等
Development 开发包,例如调试工具 gdb,代码检查和调优工具 valgrind 等
Firmware 各种硬件平台固件
Kernel modules 内核模块,运行在操作系统内部。例如加密模块、各种 USB 驱动和 netfilter 扩展模块等
Languages 不是国际化中的多语言支持模块,而是软件开发语言模块,现在可选的有perl和lua
libraries 一些动态链接库。例如XML语言解析库libxml2,和内核进行通信的libnfnetlink库,压缩和解压缩算法库zlib,微型数据库libsqlite3等
luCI OpenWrt管理UI模块,例如动态DNS管理模块luci-app-ddns、防火墙管理模块luci-app-firewall 和QOS管理模块luci-app-qos等
Mail 邮件传输客户端模块,例如 msmtp 软件包
MultiMedia 多媒体模块,例如 ffmpeg
Network 网络功能,OpenWrt 最具特色的核心模块。例如防火墙、路由、VPN 和文件传输等
Sound 音频模块
Utilities 一些不常用的实用工具模块

编译

最后输入:

1
2
3
4
make  V=s  -j4
# V=s:可以输出编译过程中每一步的执行动作,出错后显示详细的错误信息
# -j4: 使用 4 个线程进行并行编译,这样编译速度将大大加快
# 整个过程大约要1-2个小时

编译的大致流程与注意事项:

大致流程:

编译过程首先检查编译环境,然后编译 host 工具,再编译编译工具链,最后编译目标平台的各个软件包。编译make进入各个模块进行编译时,首先下载代码压缩包,然后解压缩,并打补丁,再根据设置选项来生成 Makefile,最后根据生成的 Makefile 进行编译和安装。

注意事项:

在编译时需要连接互联网,因为OpenWrt采用补丁包方式来管理代码,第三方的代码不放在它自己的代码库中,仅在编译前从第三方服务器下载(编译时首先从Internet 上下载软件模块代码,因为OpenWrt 仅有编译及配置指令,各种依赖的代码包在上游网站及代码仓库里面。 OpenWrt 网站也有第三方的代码包镜像,在上游网站不可用时将使用 OpenWrt 自己的服务器地址,下载地址为 http://downloads.openwrt.org/sources/ )。

编译完成

编译完成后在 ./openwrt/bin/targets/x86/64/ 文件夹内大致可能会输出如下几个文件:

文件名 描述
sha256sums 固件完整性校验文件
config.buildinfo OpenWrt 编译配置文件
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 引导)

测试

将自己所需的固件版本拷贝出来,我在虚拟机上测试了一下,没有问题。这次只是简单的配置,连【软件包】都没有。。。当然这些也不影响,直接可以通过SSH进行命令行安装。

云编译

当然也可以进行云编译,可以参考:

openwrt官方云编译地址:https://firmware-selector.openwrt.org/

最后

再次强调一下,不推荐编译,又费时又费力。本文只是简单的接触一下编译,后面还是需要自行摸索。

真的不到万不得已千万不要编译。。。