apply the patches based on openwrt package version

守給你的承諾、 提交于 2021-02-11 14:09:23

问题


In openwrt, as we known, usually the patches for a certain package should be put in package/[pkg]/patches and it will be applied in Makefile via $(Build/Patch). Example:

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

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

When the package update to a new version, the patches sometimes also need to be updated. Example:

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

OR

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

For a single certain package version, this works well. The only thing is to update the package version and patches manually.

For a certion reason the old patch can not be applied and submit to package source when pacakge upgrade. So they have to be maintained via patches.

What I am doing is that, if the Makefile could automatically find the right patches based on the package version. I choose to put all these patches in "package/test/file/patches/" directory base on package verion, such as:

  • 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

In the Makefile, the right patches should be copied to "package/test/patches/" directory first in "define Build/Prepare" section, before $(Build/Patch).

Match rule: (I don't know how to insert a table here, I put an image instead ...)

match the latest version

So, in this way, all the patches can be stored in the "pacakge/test" directory and they will be auto matched and applied when building.

The question is , how can I achieve to find out the right match? Since it's a little complex to compare and match the version, especially in Makefile rather than in shell script.

Actually I found some interesting script to do part of this, such as:

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


回答1:


While I don't exactly understand which version number you want to compare to which patch or the other way around, the following snippet will give you an idea how solve the task with GNUmake programming with the help of the GNUmake table toolkit which was designed for such problems:

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)>)
                                                                                                                                                                                                                                             

Output:

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.


来源:https://stackoverflow.com/questions/62650114/apply-the-patches-based-on-openwrt-package-version

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!