bash - 根据 openwrt 包版本应用补丁
问题描述
我们知道,在openwrt中,通常某个包的补丁应该放在package/[pkg]/patches中,它会通过$(Build/Patch)应用到Makefile中。例子:
包/测试/0001-1.0.1.8.fix-A.patch
包/测试/0002-1.0.1.8.fix-B.patch
当包更新到新版本时,补丁有时也需要更新。例子:
- 包/测试/0001-1.0.1.9.fix-A.patch
- 包/测试/0002-1.0.1.9.fix-B.patch
或者
- 包/测试/0001-1.0.2.0.fix-A.patch
- 包/测试/0002-1.0.2.0.fix-B.patch
对于单个特定的包版本,这很好用。唯一的事情是手动更新软件包版本和补丁。
由于某种原因,旧补丁无法在升级包时应用并提交到包源。所以它们必须通过补丁来维护。
我正在做的是,如果 Makefile 可以根据包版本自动找到正确的补丁。我选择将所有这些补丁放在基于包版本的“package/test/file/patches/”目录中,例如:
- 包/测试/文件/补丁/1.0.1.8/0001-v1.0.1.8.fix-A.patch
- 包/测试/文件/补丁/1.0.1.8/0002-1.0.1.8.fix-B.patch
- 包/测试/文件/补丁/1.0.1.9/0001-1.0.1.9.fix-A.patch
- 包/测试/文件/补丁/1.0.1.9/0002-1.0.1.9.fix-B.patch
- 包/测试/文件/补丁/1.0.2.0/0001-1.0.2.0.fix-A.patch
- 包/测试/文件/补丁/1.0.2.0/0002-1.0.2.0.fix-B.patch
在 Makefile 中,应首先将正确的补丁复制到“define Build/Prepare”部分中的“package/test/patches/”目录中,在 $(Build/Patch) 之前。
匹配规则:(这里不知道怎么插入表格,我放了一张图片代替...)
因此,通过这种方式,所有补丁都可以存储在“pacakge/test”目录中,并在构建时自动匹配和应用。
问题是,我怎样才能找到正确的匹配?因为比较和匹配版本有点复杂,尤其是在Makefile中而不是在 shell 脚本中。
其实我找到了一些有趣的脚本来做这部分,比如:</p>
解决方案
虽然我不完全了解您想要将哪个版本号与哪个补丁或其他方式进行比较,但以下代码片段将让您了解如何借助专为此类设计的 GNUmake 表工具包GNUmake
通过编程解决任务问题:
include gmtt/gmtt.mk
# Helper function which converts a list of numbers into a decimal
# number with 3 digits per original version place:
vers-to-num = $(call lpad,$(word 1,$1),3,0)$(call lpad,$(word 3,$1),3,0)$(call lpad,$(word 5,$1),3,0)$(call lpad,$(word 7,$1),3,0)
VERSION := 1.1.1.4
VERS_LIST := $(call glob-match,$(word 1,$(VERSION)),*.*.*.*)
$(info VERS_LIST = $(VERS_LIST))
VERS_NUM := $(call vers-to-num,$(VERS_LIST))
$(info $(VERS_NUM))
PATCH := 1.0.2.0
# Patch to version relation:
# Table with 3 columns: patch-nr | first applicable version | last applicable version
# In case there is only one version it has to go into both columns (no empty cells!)
define PATCH_TO_VER :=
3
1.0.1.8 1.0.1.8 1.0.1.8
1.0.1.9 1.0.1.9 1.0.1.9
1.0.2.0 1.0.2.0 1.1.1.3
1.1.1.4 1.1.1.4 1.1.3.9
endef
VA_VB := $(call select,2 3,$(PATCH_TO_VER),$$(call str-eq,$(PATCH),$$1))
$(info VA_VB = $(VA_VB))
VA_LIST := $(call glob-match,$(word 1,$(VA_VB)),*.*.*.*)
VA_NUM := $(call vers-to-num,$(VA_LIST))
$(info $(VA_NUM))
VB_LIST := $(call glob-match,$(word 2,$(VA_VB)),*.*.*.*)
VB_NUM := $(call vers-to-num,$(VB_LIST))
$(info $(VB_NUM))
# Instead of comparing each version digit against upper and lower
# allowed value (the if-else tree for this gets hellish, try it
# yourself) we use gmtt's numeric range capability of at least 64
# digits to compare versions :
COMPARE_RESULT := $(if $(call int-ge,$(VERS_NUM),$(VA_NUM)),$(if $(call int-le,$(VERS_NUM),$(VB_NUM)),yes))
$(info patch version in range (empty=no): <$(COMPARE_RESULT)>)
输出:
VERS_LIST = 1 . 1 . 1 . 4
001001001004
VA_VB = 1.0.2.0 1.1.1.3
001000002000
001001001003
patch version in range (empty=no): <>
make: *** No targets. Stop.
推荐阅读
- javascript - .find 不是 Mongoose 中的函数
- javascript - 容器内的垂直可滚动滑块
- javascript - 在字符串中包装 ng-style
- ios - .element::-webkit-scrollbar{display:none} 在 Safari 和 iOS 设备中不起作用
- atom-editor - 如何验证 atom 包是否在 atom 编辑器中正确启动
- javascript - Jest 不会模拟(设置间谍)所需的功能
- php - PHP 文件未执行所有 3 个查询
- mysql - MYSQL:为给定过滤器选择一行和键的最大值
- javascript - 用逗号分割逗号分隔的字符串
- java - JAVA - HTTP 请求 - 得到错误的响应