在GNU Makefile中是否有类似Python装饰器的机制?

4
我是一位能翻译文本的助手。
我发现自己在声明GNU make目标为虚伪目标时有两种可能性,这让我有些纠结。
其中一种是一次性声明所有虚伪目标:
.PHONY: targ1 targ2 targ3

targ1:
     ...

targ2:
     ...

targ3:
     ...

这种方式更易读(对我来说)和更整洁,但是人们无法快速地看到哪些目标是伪造的。

另一种可能性是在规则中直接声明伪造目标(在前面或后面):

.PHONY: targ1
targ1:
     ...

.PHONY: targ2
targ2:
     ...

targ3:
     ...
.PHONY: targ3

对我来说,这种写法更难阅读。而且我不喜欢规则名称的重复。是否有类似于Python中函数修饰符的解决方案?例如:

@pny
targ1:
    ...

@pny
targ2:
    ...

@pny
targ3:
    ...

我觉得这种方法可能不仅仅适用于规则的模拟,对于其他应用也可能更有用,因为这只是基于个人偏好而言。因此,我在问题标题中使用了更广泛的名称。

我很高兴我不是地球上唯一一个想要同样事物的人。 我的用例略有不同:我喜欢使用makefiles,并且我使用了很多类似的模板,例如我所有的Terraform项目都有"make up"和"make plan",它们做相同的事情。我所有的k8s相关内容都有相同的"make up"和"make down",用于启动和关闭集群,等等。 - Riccardo
1个回答

3
我不知道Make中是否内置了相关功能。但是,如果您想要一个(不太便携,不建议使用的)解决方案,可以尝试以下操作:
MAKEFILE = $(lastword $(MAKEFILE_LIST))
.PHONY: $(shell grep -E -A1 "^\s*\#\s*phy" $(MAKEFILE) | \
                     grep -Pio "^[a-z][-_.a-z0-9]+\s*(?=:)")

#phy
targ1:
    ...

#phy
targ2:
    ...

#phy
targ3:
    ...

该解决方案在每个规则上面的行中搜索字符串#phy。它提取了规则名称,使用了Unix程序grep和shell调用两种方法。然后将这些规则名称作为.PHONY的源。

为了创建一个更通用的“装饰器”,您可以将其与此答案中的技术相结合:https://stackoverflow.com/a/36941727/8655091,即使用define构建具有输入参数的make规则文本的部分。然后,在foreach循环中调用该定义以实际创建规则。

但是,grep特别是使用-P选项可能不会在每个系统上都存在。此外,包含子Makefile可能会出现问题。大多数遇到这种肮脏的黑客的人都会想要伤害您。


3
哦,我真的想为你的狡猾点赞,但同时也想因为对同事的残忍而给你踩个反对。如果我继承了一个包含这样Makefile的项目,我会...好吧,我可能会说一些不好听的话。我还可能会找出你住在哪里。哦,还有谷歌附近的斧头店。 - Norman Gray
为了您的健康和安宁,我在我的回答中添加了免责声明。现在,斧头店老板们可能会感到失望。我想并不是每个人都能满意。 - con-f-use

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接