目标内的Makefile字符串比较

问题描述 投票:0回答:2

我有以下Makefile

FIRSTARG := $(firstword $(MAKECMDGOALS))
# use the rest as arguments
RUNARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
# ...and turn them into do-nothing targets
$(eval $(RUNARGS):;@:)


test:
    if [[ "$(FIRSTARG)" == "test" ]]; then \
        pytest --cov --cov-report term-missing ;\
    elif [[ "docker" == "$(FIRSTARG)" ]]; then \
        sudo docker run merlot:latest ;\
    fi; 

docker : $(RUNARGS)
    @echo first word: $(FIRSTARG)


.PHONY: docker build test prune

但我收到错误

if [[ "test" == "test" ]]; then \
    pytest --cov --cov-report term-missing ;\
elif [[ "docker" == "test" ]]; then \
    sudo docker run merlot:latest ;\
fi; 
/bin/sh: 1: [[: not found
/bin/sh: 3: [[: not found

我也尝试过使用

ifeq ("test","@(FIRSTARG)")
,它引发了不同的错误。我已经对此进行了相当多的搜索,但似乎找不到比较目标内部字符串的正确方法。您能帮我找到在 make 目标中进行字符串比较的正确方法吗?

谢谢!

makefile gnu-make
2个回答
0
投票

所有 make 程序都会调用

/bin/sh
,这是一个符合 shell 脚本 POSIX 规范的 shell。 POSIX 标准没有定义运算符
[[
,所以你不能使用它。

最好的办法是使用 POSIX 标准脚本,因此只需使用

[
而不是
[[
,并且仅使用
=
而不是
==


0
投票

错误消息中的关键线索是

/bin/sh: 1: [[: not found

也就是说,它是

/bin/sh
抱怨命令
[[
不存在。这是真的,因为
sh
中没有这样的命令。这是
bash
中的有效语法,它通常是功能更强大的 shell,但 Makefile 默认情况下使用
/bin/sh
执行其操作。

可以更改 Make 使用的 shell,但通常最好顺其自然并在操作中使用仅限 sh 的语法。因此我怀疑,如果你改变你的行为

if test "$(FIRSTARG)" = "test"; ...

(有关详细信息,请参阅

man test
)那么您所拥有的可能会起作用。

旁注:

[[
不是
bash
中的命令 – 它是内置语法。
[
sh
中都有一个命令
bash
,它只是
test
的同义词。

© www.soinside.com 2019 - 2024. All rights reserved.