【问题标题】:apply the patches based on openwrt package version根据 openwrt 包版本应用补丁
【发布时间】:2020-06-30 04:03:40
【问题描述】:

在openwrt中,众所周知,通常某个包的补丁应该放在package/[pkg]/patches 它将通过 $(Build/Patch) 在 Makefile 中应用。 示例:

  • package/test/0001-1.0.1.8.fix-A.patch

  • package/test/0002-1.0.1.8.fix-B.patch

当包更新到新版本时,补丁有时也需要更新。 示例:

  • package/test/0001-1.0.1.9.fix-A.patch
  • package/test/0002-1.0.1.9.fix-B.patch

或

  • package/test/0001-1.0.2.0.fix-A.patch
  • package/test/0002-1.0.2.0.fix-B.patch

对于单个特定的包版本,这很好用。唯一的事情就是手动更新软件包版本和补丁。

由于某种原因,旧补丁无法在升级包时应用并提交到包源。所以它们必须通过补丁来维护。

我正在做的是,如果 Makefile 可以根据包版本自动找到正确的补丁。 我选择根据包的版本将所有这些补丁放在“package/test/file/patches/”目录下,例如:

  • package/test/file/patches/1.0.1.8/0001-v1.0.1.8.fix-A.patch
  • package/test/file/patches/1.0.1.8/0002-1.0.1.8.fix-B.patch
  • package/test/file/patches/1.0.1.9/0001-1.0.1.9.fix-A.patch
  • package/test/file/patches/1.0.1.9/0002-1.0.1.9.fix-B.patch
  • package/test/file/patches/1.0.2.0/0001-1.0.2.0.fix-A.patch
  • package/test/file/patches/1.0.2.0/0002-1.0.2.0.fix-B.patch

在 Makefile 中,应首先将正确的补丁复制到“define Build/Prepare”部分中的“package/test/patches/”目录中,在 $(Build/Patch) 之前。

匹配规则:(这里我不知道怎么插入表格,我放个图片代替...)

match the latest version

这样,所有的补丁都可以存放在“pacakge/test”目录下,构建时会自动匹配并应用。

问题是,我怎样才能找到合适的匹配? 因为比较和匹配版本有点复杂,尤其是在 Makefile 中而不是在 shell 脚本中。

其实我发现了一些有趣的脚本来做这部分,比如:

how-to-compare-two-strings-in-dot-separated-version-format-in-bash

【问题讨论】:

    标签: bash makefile package gnu-make openwrt


    【解决方案1】:

    虽然我不完全了解您想将哪个版本号与哪个补丁或其他方式进行比较,但以下 sn-p 将让您了解如何在 @ 的帮助下使用 GNUmake 编程解决任务987654321@ 专为此类问题设计:

    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.
    

    【讨论】:

    • 这是基于 gmtt/gmtt.mk 它是否适用于每个 openwrt 项目以及我如何安装它?如果我没有 GMT 怎么办。
    • 实际上我已经在 Makefile 中写了一些并实现了其中的一部分。 #part-A : 比较 a.b.c.d 等版本,如果 ge version_greater_equal = $(shell if printf '%s\n%s\n' '$(2)' '$(1)' | \ sort -Ct. -k1,1n -k2,2n -k3,3n -k4,4n ; 然后 echo YES; else echo NO; fi) #part-B: 获取子文件夹名称,每个如 SUB_DIR_LISTS := $(foreach eachdir, $(filter %/, $(wildcard ./files/patches/*/)), $(shell echo ${eachdir} | cut -d/ -f4))
    • 对不起...我未能按照要求的格式插入代码...。
    • @RobertHu 无需安装 gmtt,只需从 github 下载并将其放在您的 makefile 或任何您认为合适的地方。这是一个简单的includeable makefile。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    相关资源
    最近更新 更多