问题
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