我有一个Makefile定义docker-compose项目。它实际上是一个命令的汇编:
COMMAND := docker-compose --project-name=$(PREFIX) --file=$(FILE_PATH)
up:
$(COMMAND) up -d
我想添加一个名为target
的dc
,我可以将我想要的任何参数传递给它。
我知道有一种解决方案:
target:
$(COMMAND) $(ARGS)
然后以make target ARGS="--help"
命名。
但是没有像bash $@
中那样简单的方法吗?我想跳过ARGS = ...部分,并将所有内容发送到target
名称之后的命令中。
=
)解释为要构建的目标名称,您无法覆盖它。因此,即使您可以获得命令行上给出的参数列表(通过GNU make-specific $(MAKECMDGOALS)
变量),也无法防止将这些参数视为目标。您可以做这样的事情,这实在是太骇人了:
KNOWN_TARGETS = target
ARGS := $(filter-out $(KNOWN_TARGETS),$(MAKECMDGOALS))
.DEFAULT: ;: do nothing
.SUFFIXES:
target:
$(COMMAND) $(ARGS)
(未经测试)。这里的问题是,您必须使KNOWN_TARGETS
与所有“真实”目标保持最新,以便可以从命令行中提供的目标列表中将其删除。然后添加.DEFAULT
目标,该目标将针对任何不知道如何构建的目标运行,而该目标什么也不做。重置.SUFFIXES
元目标以删除内置规则。我怀疑这仍然会有一些奇怪的边缘情况,但无法正常工作。
[还要注意,您不能仅在make命令行中添加
--help
之类的选项,因为make会自行解释它们。您必须为它们加上--
前缀,以强制make忽略它们:
make target -- --help
另一种选择是添加这样的目标:
target%: $(COMMAND) $*
然后您可以运行此:
make "target --help"
但是您必须包括引号。一般来说,我建议您重新考虑要做什么。
#/bin/bash
make target ARGS=\"$@\"
您不想在make中执行此操作的原因是,make会解析命令行参数before,它会解析makefile本身,因此在您阅读makefile时,目标,变量等已经已经设定。这意味着make将已经将额外的参数解释为新的目标,变量等。
# Makefile:
COMMAND := $(PYTHON) this_shit_got_real.py
LOCAL_MK ?= local.mk
# '-' important, absence of LOCAL_MK is not cause for error, just run with no overrides
- include $(LOCAL_MK)
target:
$(COMMAND) $(ARGS)
现在查看如何使用env添加分支:
echo "ARGS=--help">>local.mk # make target
和另一个由cli控制的分支
echo "ARGS=--doit">>runner.mk # LOCAL_MK=runner.mk make target