停止执行makefile

Mat*_*teo 9 bash shell makefile

我实现了一个配方,以便将所有剩余的字符串传递给命令,例如在此脚本中:

Makefile

run:
#   ./bin/run.sh $(filter-out $@,$(MAKECMDGOALS)) 
    @echo $(filter-out $@,$(MAKECMDGOALS))
Run Code Online (Sandbox Code Playgroud)

但是,当我作为例子跑:

>make run my custom input params
my custom input params
make: *** No rule to make target `my'.  Stop.
Run Code Online (Sandbox Code Playgroud)

makefile尝试执行剩余的字符串,所以错误:

make: *** No rule to make target `my'.  Stop.
Run Code Online (Sandbox Code Playgroud)

我怎么能阻止这个?

注意:作为解决方法,我定义了一个虚拟配方:

%:
    @echo
Run Code Online (Sandbox Code Playgroud)

所以这将打印一个空字符串而不是错误.

我想避免做类似的事情:

make run-example param="my custom param"
Run Code Online (Sandbox Code Playgroud)

Ren*_*let 9

你可以通过match-anything规则实现你想要的.示例(使用虚拟printf配方而不是真实配方):

PARAMS := $(filter-out run,$(MAKECMDGOALS))

run:
    @printf './bin/run.sh $(PARAMS)\n'

%:;
Run Code Online (Sandbox Code Playgroud)

演示:

$ make run my custom input params
./bin/run.sh my custom input params
make: 'my' is up to date.
make: 'custom' is up to date.
make: 'input' is up to date.
make: 'params' is up to date.
Run Code Online (Sandbox Code Playgroud)

您可以忽略这些make: 'target' is up to date.消息或使用--quiet选项(或--silent-s):

$ make --quiet run my custom input params
./bin/run.sh my custom input params
Run Code Online (Sandbox Code Playgroud)

如果你的Makefile比这个更复杂,match-anything规则可能是个问题,因为它可以捕获你不想被捕获的其他目标.在这种情况下,make条件是一个选项:

ifeq ($(SECONDPASS),)
PARAMS := $(filter-out run,$(MAKECMDGOALS))

run:
    @$(MAKE) --quiet $@ PARAMS='$(PARAMS)' SECONDPASS=true

%:;
else
run:
    @printf './bin/run.sh $(PARAMS)\n'

# other rules if any
endif
Run Code Online (Sandbox Code Playgroud)

最后,如果第一个目标的名称并不总是相同,您可以使用以下内容进行调整:

GOAL   := $(firstword $(MAKECMDGOALS))
PARAMS := $(filter-out $(GOAL),$(MAKECMDGOALS))

$(GOAL):
    @printf './bin/$(GOAL).sh $(PARAMS)\n'

%:;
Run Code Online (Sandbox Code Playgroud)

要么:

GOAL   := $(firstword $(MAKECMDGOALS))

ifeq ($(SECONDPASS),)
PARAMS := $(filter-out $(GOAL),$(MAKECMDGOALS))

$(GOAL):
    @$(MAKE) --quiet $@ PARAMS='$(PARAMS)' SECONDPASS=true

%:;
else
$(GOAL):
    @printf './bin/$(GOAL).sh $(PARAMS)\n'

# other rules if any
endif
Run Code Online (Sandbox Code Playgroud)

演示:

$ make --quiet nur foo bar
./bin/nur.sh foo bar
Run Code Online (Sandbox Code Playgroud)


Nic*_*ell 6

我认为你不应该使用Makefile.你想自己解析选项,这在make中比较麻烦.

如果你已经死了,你可以这样做:

%:
    @true
Run Code Online (Sandbox Code Playgroud)

...这将避免打印空行.

不过,最好在Bash中这样做.这是你可以做到的一种方式:

#!/usr/bin/env bash

if [ $# -lt 1 ]; then
    echo Not enough args
    exit 1
fi

case "$1" in
    "run")
        shift
        ./bin/run.sh $@
        ;;
    *)
        echo "Command $1 not recognized"
        exit 1
        ;;
esac
Run Code Online (Sandbox Code Playgroud)

这似乎更容易,更具可扩展性.