是否可以在 Makefile 中使用 bash 参数扩展?

ode*_*den 6 bash make

我的生成文件:

FULL_VERSION ?= 1.2.3
MINOR_VERSION := $(shell echo "${FULL_VERSION%.*}")

test:
    echo $(MINOR_VERSION)
Run Code Online (Sandbox Code Playgroud)

跑步make test什么也没给,我想得到1.2

我知道我可以通过 sed/grep 获得它,但我正在寻找一个更优雅的解决方案,似乎没有什么比 bash 参数扩展更简单了

Sté*_*las 11

您需要首先将值存储在 shell 变量中:

MINOR_VERSION := $(shell v='$(FULL_VERSION)'; echo "$${v%.*}")
Run Code Online (Sandbox Code Playgroud)

(假设$(FULL_VERSION)不包含单引号)

现在那个电话sh,不是bash${var%pattern}是标准sh运算符(来自ksh)。

如果你想使用bash-specific 操作符,你需要告诉makecallbash而不是shwith

SHELL = bash
Run Code Online (Sandbox Code Playgroud)

但是请注意bash,默认情况下许多系统都没有安装,这会使您的 Makefile 不可移植(但是,有些系统也没有 GNUmake并且您已经在那里使用了一些 GNUism))。


uzs*_*olt 5

您可以使用内置函数来完成此操作(假设您使用的是 GNU make):

VER=1.2.3
MINORVERTMP=$(subst ., ,${VER})
MINORVER=$(word 1,${MINORVERTMP}).$(word 2,${MINORVERTMP})


all:
    @echo ${MINORVER}
Run Code Online (Sandbox Code Playgroud)

如果你可以使用bmake(BSD make)可以有更多(也许更简单)的可能性:

VER=1.2.3

all: test1 test2

test1:
    # simple regular expression-based replace like sed
    @echo $@: ${VER:C,([^\.]*)\.([^\.]*).*,\1.\2,}

test2:
    # replace all dot to spaces (S),
    # print first and second element (:[1..2])
    # with dot separator (ts.)
    @echo $@: ${VER:S,., ,g:[1..2]:ts.}
Run Code Online (Sandbox Code Playgroud)