坑边闲话:OpenWrt 的稳定版一直比较保守,RC 要 4~5 轮才放出正式版,而正式版中的关键组件更新也很保守。目前 22.03.5 的 AdGuardHome 版本很老旧,除非开机后通过命令行手动升级,否则很难直接搞定。最麻烦的是配置文件 /etc/adguardhome.yaml 不能向下兼容,即老版本软件无法解析新版本的配置文件。此外,软件升级需要连接外网,没有了 AdguradHome 做 DNS 也很成问题。

1. 下载最新版 linux-amd64 二进制·

该文件可以在 GitHub 官方仓库里找到,通过 wget 直接下载:

1
wget https://github.com/AdguardTeam/AdGuardHome/releases/download/v0.107.36/AdGuardHome_linux_amd64.tar.gz

在 OpenWrt 编译流程里,package 的 Makefile 依赖的源代码一般是一个 URI 链接,在编译时通过 curl 或者其他工具在线拉取。从某种意义上看,OpenWrt 也是一种符合 gentoo 思想的发行版。由于 Makefile 里也依赖压缩包的 SHA-256 校验和,因此,我们需要使用使用 sha256sum 工具计算得到校验和:

1
sha256sum AdGuardHome_linux_amd64.tar.gz

输出如下:

1
2
$ sha256sum AdGuardHome_linux_amd64.tar.gz
b06eb8b75c7bd2e2a4f38e1d4f583d1b327e0e01eebfbb14101695aa812658ec AdGuardHome_linux_amd64.tar.gz

复制哈希值,并修改对应的文件:

1
vim feeds/packages/net/adguardhome/Makefile

参考下面的 修改 1/2修改 2/2

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
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

# 包含其他 Makefile 规则
include $(TOPDIR)/rules.mk

PKG_NAME:=adguardhome
PKG_VERSION:=0.107.36 # 修改 1/2:版本号
PKG_RELEASE:=1

PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=v$(PKG_VERSION)
PKG_SOURCE_URL:=https://github.com/AdguardTeam/AdGuardHome

# 修改 2/2:将 sha256 校验和更改为对应的
PKG_MIRROR_HASH:=b06eb8b75c7bd2e2a4f38e1d4f583d1b327e0e01eebfbb14101695aa812658ec

PKG_LICENSE:=GPL-3.0-only
PKG_LICENSE_FILES:=LICENSE.txt
PKG_MAINTAINER:=Dobroslaw Kijowski <[email protected]>

PKG_BUILD_DEPENDS:=golang/host node/host node-yarn/host
PKG_BUILD_PARALLEL:=1
PKG_USE_MIPS16:=0

GO_PKG:=github.com/AdguardTeam/AdGuardHome
GO_PKG_BUILD_PKG:=github.com/AdguardTeam/AdGuardHome

AGH_BUILD_TIME:=$(shell date -d @$(SOURCE_DATE_EPOCH) +%FT%TZ%z)
AGH_VERSION_PKG:=github.com/AdguardTeam/AdGuardHome/internal/version
GO_PKG_LDFLAGS_X:=$(AGH_VERSION_PKG).channel=release \
$(AGH_VERSION_PKG).version=$(PKG_SOURCE_VERSION) \
$(AGH_VERSION_PKG).buildtime=$(AGH_BUILD_TIME) \
$(AGH_VERSION_PKG).goarm=$(GO_ARM) \
$(AGH_VERSION_PKG).gomips=$(GO_MIPS)

include $(INCLUDE_DIR)/package.mk
include ../../lang/golang/golang-package.mk

# 定义 BuildRoot 里 adguard 的组织信息:
# 所属分类:网络
# 目录:Network
# 标题:显示在 TUI 界面右侧的简短说明
# URL:软件源码目录
# 项目依赖:主要依赖 Go 和 ca-bundle
define Package/adguardhome
SECTION:=net
CATEGORY:=Network
TITLE:=Network-wide ads and trackers blocking DNS server
URL:=https://github.com/AdguardTeam/AdGuardHome
DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle
endef


# 定义 adguardhome 的配置文件 conf-files
define Package/adguardhome/conffiles
/etc/adguardhome.yaml
/etc/config/adguardhome
endef

# BuildRoot TUI 界面里的 help 信息
define Package/adguardhome/description
Free and open source, powerful network-wide ads and trackers blocking DNS server.
endef

# 定义如何编译 adguardhome
define Build/Compile
( \
pushd $(PKG_BUILD_DIR) ; \
make js-deps js-build ; \
popd ; \
$(call GoPackage/Build/Compile) ; \
)
endef

# 定义如何安装,其中包括
# (1) 复制二进制文件
# (2) 复制开机 init.d 初始化脚本
# (3) 复制配置文件和相关数据
#
define Package/adguardhome/install
$(call GoPackage/Package/Install/Bin,$(1))
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/adguardhome.init $(1)/etc/init.d/adguardhome

$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DATA) ./files/adguardhome.config $(1)/etc/config/adguardhome
endef

$(eval $(call GoBinPackage,adguardhome))
$(eval $(call BuildPackage,adguardhome))

随后即可正常编译。

2. 流程回顾·

2.1 清理目录·

如果你的 OpenWrt 刚刚拉取下来,那就可以忽略这一步。

反之,如果你之前编译过,或成功或失败,都要先将之前的痕迹清理干净:

1
2
make dirclean ; make clean
rm -fr feeds dl

其中,

  • feeds 目录是之前根据 feeds.conf.default 文件指导下载的 luci, package, routing, telephony 等 Makefile 配置信息。
  • dl 是下载目录,当根据以上 Makefile 拉取源码压缩包时,所有压缩包会临时存放在 dl 目录里。因为 dl 目录不会按期清理,多次编译之后容易存储同一软件的不同版本,造成空间浪费。

2.2 拉取 feeds·

在清理完 feeds 目录之后,需要重新拉取 feeds 上游信息:

1
./scripts/feeds update -a && ./scripts/feeds install -a -f

以上过程中,

  • ./scripts/feeds update -a 是拉取 feeds.conf.default 定义的所有上游库的记录信息到本地,包括所有 Makefile
  • ./scripts/feeds install -a -f 是在 package 目录下建立 package/feeds 子目录,并将 feeds 下的所有文件拷贝过来。当然,实际过程并非拷贝,而是直接建立软链接,这样可以节约空间。

2.3 修改文件·

根据本文第一节介绍的内容,修改对应文件即可。

2.4 下载并编译·

1
2
make download -j 16 V=s
make -j 16 V=s | tee compile.log

总结·

通过修改 feeds 目录里与软件相关的 Makefile,可以实现源码版本的拉取控制。不过,没有了官方支持,需要自己确认系统与软件的兼容性。