Replace 执行MAKE时文件中的字符串替换

Replace 执行MAKE时文件中的字符串替换,replace,makefile,Replace,Makefile,我有一个现有的项目,我正在工作,目前有一行在使文件 VERSION := $(shell ${GIT} describe --tags --always) 它最终将类似于v2.3-9-gcdf3820的字符串存储到VERSION变量中。在包过程中,该变量最终用于命名文件 我想做的是编写一个示例.version文件,该文件的格式如下 { "NAME":"Examle", "VERSION": { "MAJOR":2, "MINOR":3,

我有一个现有的项目,我正在工作,目前有一行在使文件

VERSION := $(shell ${GIT} describe --tags --always)
它最终将类似于
v2.3-9-gcdf3820
的字符串存储到
VERSION
变量中。在包过程中,该变量最终用于命名文件

我想做的是编写一个
示例.version
文件,该文件的格式如下

{
    "NAME":"Examle",
    "VERSION":
    {
        "MAJOR":2,
        "MINOR":3,
        "PATCH":0,
        "BUILD":0
    }
}
因此,它接收版本号,直到第一个
-
,然后用0填充其余的版本号。来自
descripe
的结果可能有1到4个版本号,所以我想灵活一些

问题是我现在被困在下一步该怎么做。我制作了一个
Example.version.template
文件

{
    "NAME":"Examle",
    "VERSION":
    {
        "MAJOR":{MAJOR},
        "MINOR":{MINOR},
        "PATCH":{PATCH},
        "BUILD":{BUILD}
    }
}
我知道如何从makefile内部读取文件和写出文件,并且知道一旦有了每个变量,如何替换文本。我不知道如何将
v2.3-9-gcdf3820
转换为

MAJOR := 2
MINOR := 3
PATCH := 0
BUILD := 0

当我完全同意@MadScientist的观点,make不是最适合这项任务的,而且一个小的shell脚本可能是一个更好的选择时,我如何将字符串拆分并从
make
中去掉前面的
v

使用make本身进行此操作

$ cat desc.mk
define p
$(info $1:$($(1)):)
endef
raw := v2.3-9-gcdf3820
$(call p,raw)
split := $(subst -, ,$(raw))
$(call p,split)
ver := $(subst v,,$(word 1,$(split)))
$(call p,ver)
versplit := $(subst ., ,$(ver))
$(call p,versplit)
MAJOR := $(or $(word 1,$(versplit)),0)
$(call p,MAJOR)
MINOR := $(or $(word 2,$(versplit)),0)
$(call p,MINOR)
PATCH := $(or $(word 3,$(versplit)),0)
$(call p,PATCH)
BUILD := $(or $(word 4,$(versplit)),0)
$(call p,BUILD)

all: ;
$ make -qf desc.mk
raw:v2.3-9-gcdf3820:
split:v2.3 9 gcdf3820:
ver:2.3:
versplit:2 3:
MAJOR:2:
MINOR:3:
PATCH:0:
BUILD:0:
使用
git descripe--tags--always--abbrev=0
让git从一开始就为您删除
-9-gcdf3820
(或其他任何内容)(至少对于这种用法而言)也是有意义的,因为这样可以省去大量所需的工作

编辑:@laune的一点小聪明使最后几行得到了清理:

versplit := $(subst ., ,$(ver)) 0 0 0 0
MAJOR := $(word 1,$(versplit))
$(call p,MAJOR)
MINOR := $(word 2,$(versplit))
$(call p,MINOR)
PATCH := $(word 3,$(versplit))
$(call p,PATCH)
BUILD := $(word 4,$(versplit))
$(call p,BUILD)

单独使用make不可能实现这种字符串操作。我建议您编写一个小的shell脚本,在给定版本字符串作为输入的情况下生成文件,然后编写一个调用shell脚本的make规则。太棒了通过使用
versplit:=$(subst.,$(ver))0 0 0
并省略
$(或)
MAJOR:=$(word 1,$(versplit))
等,可以稍微减少噪声。