0%

OpenWrt 自编译编译记录

前几年刚搞家庭网络,捡垃圾捡来一个 TP-Link TL-WDR4310 v1 路由器,这玩意可以刷 OpenWrt

后来随着 OpenWrt 大版本更新,固件也越来越大,TL-WDR4310 本身自带的存储空间已经不够用了,于是给它物理扩容到 16MB

不过这样硬改之后,官方的固件他识别不到 16MB,需要自己编译固件。

本文最后更新于:2025-12-14

准备环境

基础环境镜像

构建镜像

docker build -t build-base - <<\EOF
FROM debian:13

RUN <<EOT
    sed -e 's|deb.debian.org|mirrors.aliyun.com|g' -i.bak /etc/apt/sources.list.d/debian.sources
    apt update
    apt install -y sudo bash-completion command-not-found procps vim wget curl net-tools git subversion
    apt update
    apt clean && rm -rf /var/lib/apt/lists/*
EOT

ENV TZ=Asia/Shanghai
RUN <<EOT
    useradd --create-home --uid 1000 --groups users,sudo --shell /bin/bash user
    echo "user:1111" | chpasswd
    ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime
    echo "${TZ}" > /etc/timezone
EOT

COPY <<EOT /etc/profile.d/aliases.sh
alias ll='ls -lh -F --color=auto --time-style=long-iso'
alias la='ls -lhA -F --color=auto --time-style=long-iso'
alias lt='ls -lht -F --color=auto --time-style=long-iso'
alias lat='ls -lhAt -F --color=auto --time-style=long-iso'
EOT

USER user
WORKDIR /home/user/
EOF
  1. 使用管道输入 Dockerfile 内容,自定义镜像标签为 build-base
    https://docs.docker.com/build/building/context/#how-to-build-without-a-context
  2. 使用 Here-Documents 运行 RUNCOPY 指令,注意如果是在 Dockerfile 中使用需要保证文件换行符是 LF
    https://docs.docker.com/reference/dockerfile/#here-documents
  3. 备用镜像站:
    - mirrors.aliyun.com
    - mirrors.cernet.edu.cn
    - mirrors.tuna.tsinghua.edu.cn

使用镜像

docker run -ti --rm build-base bash -l
  1. 默认为 non-loginshell,需要使用 ‘-l’ 参数登录以生效 /etc/profile 配置。
    https://github.com/gliderlabs/docker-alpine/issues/443

构建专用镜像

docker build -t build-openwrt - <<\EOF
FROM build-base
USER root

RUN <<EOT
    apt update
    apt install -y build-essential clang flex bison g++ gawk
    apt install -y gcc-multilib g++-multilib gettext git libncurses5-dev libssl-dev
    apt install -y python3-setuptools rsync swig unzip zlib1g-dev file wget
    apt clean &&  rm -rf /var/lib/apt/lists/*
EOT

USER user
EOF

下载源码

mkdir -p ~/projects/
git clone https://github.com/openwrt/openwrt.git -b v24.10.4 openwrt

构建固件

启动容器

docker run -ti --rm --privileged -v ~/projects/:/projects/ build-openwrt bash -l

初始化依赖

cd /projects/openwrt/

./scripts/feeds update -a
./scripts/feeds install -a

清理构建历史(可选)

cd /projects/openwrt/

# rm -rf bin build_dir
make clean
# rm -rf bin build_dir staging_dir toolchain logs
make dirclean
# 删除以上所有文件 , dl 和 .config
make distclean

初始化编译选项

cd /projects/openwrt/

wget https://downloads.openwrt.org/releases/24.10.4/targets/ath79/generic/config.buildinfo -O .config

这里是从 openwrt 官方拉取一个 ath79 系列机器的官方配置。如果直接使用的话,那么编译出来的固件功能和官方下载的就是一模一样的。

自定义编译选项

cd /projects/openwrt/

make menuconfig

启动可视化配置后,可按需配置构建项目:

# 设备配置
  Target Profile -> TP-Link TL-WDR4310 v1

# 镜像配置
* Image configuration -> Use preinit IP configuration as default LAN IP
* Image configuration -> Preinit configuration options
  Image configuration -> Preinit configuration options -> IP address for preinit network messages
    192.168.10.1
  Image configuration -> Preinit configuration options -> Netmask for preinit network messages
    255.255.255.0
  Image configuration -> Preinit configuration options -> Broadcast address for preinit network messages
    192.168.10.255
* Image configuration -> Version configuration options
  Image configuration -> Version configuration options -> Release repository
    https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/24.10.4

# 配置基本系统
* Base system -> ca-certificates
- Base system -> dnsmasq
* Base system -> dnsmasq-full

# 配置 LuCI 功能
* LuCI -> Modules -> Translations -> Simplified Chinese (zh_Hans)
* LuCI -> Applications -> luci-app-attendedsysupgrade
* LuCI -> Applications -> luci-app-dcwpad
* LuCI -> Applications -> luci-app-ddns
* LuCI -> Applications -> luci-app-wol

# 启用 DHCP 服务组件
* Network -> odhcpd-ipv6only
# 启用 sftp 服务
* Network -> File Transfer -> curl
* Network -> File Transfer -> vsftpd-tls
* Network -> File Transfer -> wget-ssl
# 启用 DDNS 服务
* Network -> IP Addresses and Names -> ddns-scripts
M Network -> IP Addresses and Names -> ddns-scripts-aliyun
* Network -> IP Addresses and Names -> ddns-scripts-cloudflare
* Network -> IP Addresses and Names -> ddns-scripts-dnspod
* Network -> IP Addresses and Names -> ddns-scripts-dnspod-v3
# 启用 WPAD, 支持企业无线网
* Network -> WirelessAPD -> wpad
- Network -> WirelessAPD -> wpad-basic-mbedtls

- 表示移除选中,* 表示编译进固件包,M 表示编译 ipk 但不打包进固件包。
编译系统自带的 ddns-scripts-aliyun 对子域名支持支持不好,建议使用三方包代替
https://openwrt.org/packages/index/start

适配硬改存储空间

修改 target/linux/ath79/dts/ar9344_tplink_tl-wdrxxxx.dtsitarget/linux/ath79/image/generic-tp-link.mk 适配硬改的存储空间区域:

git apply << \EOF
diff --git a/target/linux/ath79/dts/ar9344_tplink_tl-wdrxxxx.dtsi b/target/linux/ath79/dts/ar9344_tplink_tl-wdrxxxx.dtsi
index 94bfef57f6..a3a2ce1ba9 100644
--- a/target/linux/ath79/dts/ar9344_tplink_tl-wdrxxxx.dtsi
+++ b/target/linux/ath79/dts/ar9344_tplink_tl-wdrxxxx.dtsi
@@ -100,12 +100,12 @@
                        partition@20000 {
                                compatible = "tplink,firmware";
                                label = "firmware";
-                               reg = <0x020000 0x7d0000>;
+                               reg = <0x020000 0xfd0000>;
                        };

-                       partition@7f0000 {
+                       partition@ff0000 {
                                label = "art";
-                               reg = <0x7f0000 0x010000>;
+                               reg = <0xff0000 0x010000>;
                                read-only;

                                nvmem-layout {
diff --git a/target/linux/ath79/image/generic-tp-link.mk b/target/linux/ath79/image/generic-tp-link.mk
index b5b2ec8c7c..7ff2117edf 100644
--- a/target/linux/ath79/image/generic-tp-link.mk
+++ b/target/linux/ath79/image/generic-tp-link.mk
@@ -668,7 +668,7 @@ endef
 TARGET_DEVICES += tplink_tl-wdr4300-v1-il

 define Device/tplink_tl-wdr4310-v1
-  $(Device/tplink-8mlzma)
+  $(Device/tplink-16mlzma)
   SOC := ar9344
   DEVICE_MODEL := TL-WDR4310
   DEVICE_VARIANT := v1
EOF

下载构建中间件

cd /projects/openwrt/

# 访问 Github 等外网网站,如有必要可配置代理
export http_proxy=http://192.168.8.11:20170
export https_proxy=http://192.168.8.11:20170

make download -j$(nproc)

启动构建

cd /projects/openwrt/

# 全量编译
make -j$(nproc)

# 单独构建 ipk 包
make package/[包名]/compile

如遇编译错误可加上 V=sc 参数查看错误细节。

构建产物

user@44e5c274b084:/projects/openwrt$ ls -lh ./bin/targets/ath79/generic/
total 513M
-rw-r--r-- 1 user user 4.1K Dec 10 18:19 config.buildinfo
-rw-r--r-- 1 user user  395 Dec 10 18:19 feeds.buildinfo
-rw-r--r-- 1 user user  89M Dec 10 18:22 kernel-debug.tar.zst
-rw-r--r-- 1 user user  47M Dec 10 17:19 llvm-bpf-18.1.7.Linux-x86_64.tar.zst
-rw-r--r-- 1 user user 8.8M Dec 10 18:24 openwrt-24.10.4-ath79-generic-tplink_tl-wdr4310-v1-initramfs-kernel.bin
-rw-r--r-- 1 user user  16M Dec 10 18:24 openwrt-24.10.4-ath79-generic-tplink_tl-wdr4310-v1-squashfs-factory.bin
-rw-r--r-- 1 user user 9.9M Dec 10 18:24 openwrt-24.10.4-ath79-generic-tplink_tl-wdr4310-v1-squashfs-sysupgrade.bin
-rw-r--r-- 1 user user  25K Dec 10 18:24 openwrt-24.10.4-ath79-generic-tplink_tl-wdr4310-v1.bom.cdx.json
-rw-r--r-- 1 user user 5.9K Dec 10 18:24 openwrt-24.10.4-ath79-generic-tplink_tl-wdr4310-v1.manifest
-rw-r--r-- 1 user user  97M Dec 10 18:25 openwrt-imagebuilder-24.10.4-ath79-generic.Linux-x86_64.tar.zst
-rw-r--r-- 1 user user 205M Dec 10 18:27 openwrt-sdk-24.10.4-ath79-generic_gcc-13.3.0_musl.Linux-x86_64.tar.zst
-rw-r--r-- 1 user user  43M Dec 10 18:22 openwrt-toolchain-24.10.4-ath79-generic_gcc-13.3.0_musl.Linux-x86_64.tar.zst
drwxr-xr-x 3 user user  92K Dec 10 17:17 packages
-rw-r--r-- 1 user user 2.7K Dec 10 18:28 profiles.json
-rw-r--r-- 1 user user 139K Dec 10 18:28 sha256sums
-rw-r--r-- 1 user user   18 Dec 10 18:19 version.buildinfo
  • openwrt-*-initramfs-kernel.bin
    集成最小文件系统的 Linux 内核。适用于首次安装或故障恢复。
  • openwrt-*-squashfs-factory.bin
    首次刷机时,使用 Factory 映像以刷入 OpenWrt。通常您可以在原厂固件的 Web 界面中完成此操作。
  • openwrt-*-squashfs-sysupgrade.bin
    使用 Sysupgrade 映像以更新现有运行 OpenWrt 的设备。该映像可以在 LuCI 界面或终端中使用。
  • packages
    选中参与编译的 ipk 包目录。

问题

报错 python3-distutils 不存在

  • 现象
WARNING: Makefile 'package/feeds/packages/fail2ban/Makefile' has a dependency on 'python3-distutils', which does not exist
WARNING: Makefile 'package/feeds/packages/flent/Makefile' has a dependency on 'python3-distutils', which does not exist
WARNING: Makefile 'package/feeds/packages/onionshare-cli/Makefile' has a dependency on 'python3-pysocks', which does not exist
WARNING: Makefile 'package/feeds/packages/onionshare-cli/Makefile' has a dependency on 'python3-unidecode', which does not exist
WARNING: Makefile 'package/feeds/packages/python-babel/Makefile' has a dependency on 'python3-distutils', which does not exist
WARNING: Makefile 'package/feeds/packages/python-docker/Makefile' has a dependency on 'python3-distutils', which does not exist
WARNING: Makefile 'package/feeds/packages/python-incremental/Makefile' has a dependency on 'python3-distutils', which does not exist
  • 原因
python3-distutils 这个包在 python3.12 以上版本没有了, 所以会报错.

报错 libcrypt-compat 包不存在

  • 现象
WARNING: Makefile 'package/feeds/packages/alpine/Makefile' has a dependency on 'libcrypt-compat', which does not exist
WARNING: Makefile 'package/feeds/packages/alpine/Makefile' has a dependency on 'libcrypt-compat', which does not exist
WARNING: Makefile 'package/feeds/packages/apr/Makefile' has a dependency on 'libcrypt-compat', which does not exist
WARNING: Makefile 'package/feeds/packages/ccrypt/Makefile' has a dependency on 'libcrypt-compat', which does not exist
WARNING: Makefile 'package/feeds/packages/cyrus-sasl/Makefile' has a dependency on 'libcrypt-compat', which does not exist
WARNING: Makefile 'package/feeds/packages/dante/Makefile' has a dependency on 'libcrypt-compat', which does not exist
WARNING: Makefile 'package/feeds/packages/dante/Makefile' has a dependency on 'libcrypt-compat', which does not exist
WARNING: Makefile 'package/feeds/packages/dante/Makefile' has a dependency on 'libcrypt-compat', which does not exist
WARNING: Makefile 'package/feeds/packages/exim/Makefile' has a dependency on 'libcrypt-compat', which does not exist
WARNING: Makefile 'package/feeds/packages/exim/Makefile' has a dependency on 'libcrypt-compat', which does not exist
WARNING: Makefile 'package/feeds/packages/exim/Makefile' has a dependency on 'libcrypt-compat', which does not exist
WARNING: Makefile 'package/feeds/packages/exim/Makefile' has a dependency on 'libcrypt-compat', which does not exist

CMake 版本不匹配

  • 现象
Not searching for unused variables given on the command line.
CMake Error at CMakeLists.txt:1 (cmake_minimum_required):
  CMake 3.31 or higher is required.  You are running version 3.30.5


-- Configuring incomplete, errors occurred!
make[3]: *** [Makefile:60: /projects/openwrt/build_dir/target-mips_24kc_musl/rpcd-mod-luci-20240305/.configured_68b329da9893e34099c7d8ad5cb9c940] Error 1
make[3]: Leaving directory '/projects/openwrt/feeds/luci/libs/rpcd-mod-luci'
time: package/feeds/luci/rpcd-mod-luci/compile#0.28#0.22#0.44
    ERROR: package/feeds/luci/rpcd-mod-luci failed to build.
make[2]: *** [package/Makefile:176: package/feeds/luci/rpcd-mod-luci/compile] Error 1
make[2]: Leaving directory '/projects/openwrt'
make[1]: *** [package/Makefile:170: /projects/openwrt/staging_dir/target-mips_24kc_musl/stamp/.package_compile] Error 2
make[1]: Leaving directory '/projects/openwrt'
make: *** [/projects/openwrt/include/toplevel.mk:233: world] Error 2
  • 解决
    修改 ./feeds/luci/libs/rpcd-mod-luci/src/CMakeLists.txt./feeds/luci/libs/rpcd-mod-rrdns/src/CMakeLists.txt 文件,修改其中的 cmake_minimum_required(VERSION 3.31)cmake_minimum_required(VERSION 3.30)

可以通过命令 grep -nR cmake_minimum_required ./feeds/luci/libs/ 批量查找。

找不到 opkg-key 文件

  • 现象
cp: cannot stat '/projects/openwrt/staging_dir/target-mips_24kc_musl/root-ath79/usr/sbin/opkg-key': No such file or directory
make[3]: *** [Makefile:51: /projects/openwrt/bin/targets/ath79/generic/openwrt-imagebuilder-24.10.4-ath79-generic.Linux-x86_64.tar.zst] Error 1
make[3]: Leaving directory '/projects/openwrt/target/imagebuilder'
time: target/imagebuilder/install#0.12#0.24#0.37
    ERROR: target/imagebuilder failed to build.
make[2]: *** [target/Makefile:32: target/imagebuilder/install] Error 1
make[2]: Leaving directory '/projects/openwrt'
make[1]: *** [target/Makefile:26: /projects/openwrt/staging_dir/target-mips_24kc_musl/stamp/.target_install] Error 2
make[1]: Leaving directory '/projects/openwrt'
make: *** [/projects/openwrt/include/toplevel.mk:233: world] Error 2
  • 解决

选中 Base system -> opkg 包。

执行 install 冲突

  • 现象
Collected errors:
 * check_data_file_clashes: Package dnsmasq-dhcpv6 wants to install file /projects/openwrt/build_dir/target-mips_24kc_musl/root-ath79/etc/hotplug.d/ntp/25-dnsmasqsec
        But that file is already provided by package  * dnsmasq
 * check_data_file_clashes: Package dnsmasq-dhcpv6 wants to install file /projects/openwrt/build_dir/target-mips_24kc_musl/root-ath79/etc/init.d/dnsmasq
        But that file is already provided by package  * dnsmasq
 * check_data_file_clashes: Package dnsmasq-dhcpv6 wants to install file /projects/openwrt/build_dir/target-mips_24kc_musl/root-ath79/etc/uci-defaults/50-dnsmasq-migrate-ipset.sh
        But that file is already provided by package  * dnsmasq
 * check_data_file_clashes: Package dnsmasq-dhcpv6 wants to install file /projects/openwrt/build_dir/target-mips_24kc_musl/root-ath79/etc/uci-defaults/50-dnsmasq-migrate-resolv-conf-auto.sh
        But that file is already provided by package  * dnsmasq
 * check_data_file_clashes: Package dnsmasq-dhcpv6 wants to install file /projects/openwrt/build_dir/target-mips_24kc_musl/root-ath79/usr/lib/dnsmasq/dhcp-script.sh
        But that file is already provided by package  * dnsmasq
 * check_data_file_clashes: Package dnsmasq-dhcpv6 wants to install file /projects/openwrt/build_dir/target-mips_24kc_musl/root-ath79/usr/sbin/dnsmasq
        But that file is already provided by package  * dnsmasq
 * check_data_file_clashes: Package dnsmasq-dhcpv6 wants to install file /projects/openwrt/build_dir/target-mips_24kc_musl/root-ath79/usr/share/acl.d/dnsmasq_acl.json
        But that file is already provided by package  * dnsmasq
 * check_data_file_clashes: Package dnsmasq-dhcpv6 wants to install file /projects/openwrt/build_dir/target-mips_24kc_musl/root-ath79/usr/share/dnsmasq/dhcpbogushostname.conf
        But that file is already provided by package  * dnsmasq
 * check_data_file_clashes: Package dnsmasq-dhcpv6 wants to install file /projects/openwrt/build_dir/target-mips_24kc_musl/root-ath79/usr/share/dnsmasq/rfc6761.conf
        But that file is already provided by package  * dnsmasq
 * opkg_install_cmd: Cannot install package dnsmasq-dhcpv6.
make[2]: *** [package/Makefile:99: package/install] Error 255
make[2]: Leaving directory '/projects/openwrt'
make[1]: *** [package/Makefile:171: /projects/openwrt/staging_dir/target-mips_24kc_musl/stamp/.package_install] Error 2
make[1]: Leaving directory '/projects/openwrt'
make: *** [/projects/openwrt/include/toplevel.mk:233: world] Error 2
  • 解决
    移除多余包。

参考