gpt4 book ai didi

makefile - 使溢出¹,或 “How to override a target?”

转载 作者:行者123 更新时间:2023-12-01 04:50:38 24 4
gpt4 key购买 nike

我有一系列(数十个)项目,其中包含 git 存储库中的大量内容。每个存储库都有一个通用工具包的 git 子模块。该工具包包含处理内容存储库和构建可发布结果所需的库和脚本。所有存储库都被推送到运行 CI 并发布结果的主机。这个想法是将重复的代码保持在绝对最低限度,并且大部分内容都在存储库中,并且依赖于工具包以将每个项目以相同的方式组合在一起。

每个项目都有一个顶级 Makefile,通常只有几行,例如:

STAGE = stage

include toolkit/Makefile

stage 变量有一些关于这个特定的阶段的信息,它决定了构建哪些格式。几乎所有其他内容都由工具包中的 600 行 Makefile 处理。构建某些输出格式可能需要一长串依赖关系:源的过程可能会触发目标规则,但要到达目标可能需要 8-10 个中间依赖关系,其中在最终目标生成之前会生成各种文件制作。

我遇到了几种我想要 的情况完全替换 (不仅仅是扩展)一个项目中的特定目标规则。目标在一系列依赖关系的中间被触发,但我想为这一步做一些完全不同的事情。

我尝试只替换顶级 Makefile 中的目标:
STAGE = stage

%-target.fmt:
commands

include toolkit/Makefile

这是专门记录的 不是 得到支持,但诱人的是它有时会起作用。我尝试更改声明自定义目标和包含的顺序,但这似乎并没有显着影响。如果它很重要,是的,在目标中使用模式很重要。

Sometimes it is useful to have a makefile that is mostly just like another makefile. You can often use the ‘include’ directive to include one in the other, and add more targets or variable definitions. However, it is invalid for two makefiles to give different recipes for the same target.



有趣的是,如果我将自定义函数放在包含下方的顶级 Makefile 中,我可以覆盖工具包中的函数,以便 $(call do_thing)将使用我的覆盖:
STAGE = stage

include toolkit/Makefile

define do_thing
commands
endef

然而,目标似乎并非如此。我知道 two colon syntax ,但我不想仅仅扩展具有更多依赖项的现有目标,我想用生成相同文件的不同方式完全替换目标。

我考虑过使用递归调用来进行 as suggested in the documentation ,但是包括在工具包 Makefile 中广泛设置的帮助函数的环境将不可用于顶级 Makefile 中的任何目标。这将是一个表演的终结者。

有什么办法可以让我破例吗?可以强制它成为压倒一切的目标吗?我只使用最新版本的 GNU-Make,并且不太关心可移植性。如果做不到这一点,还有另一种实现相同目的的概念方法吗?

¹我的大脑今天没有喝足够的咖啡。在尝试打开 Stack Overflow 来询问这个问题时,我输入了 makeoverflow.com进入我的浏览器,很困惑为什么没有自动完成。

最佳答案

更新答案:
如果您的配方具有依赖项,则默认情况下无法覆盖这些依赖项。然后 $(eval) 可能会像这样为您节省:

在工具包中有一个带有通用规则的宏定义:

ifndef TARGET_FMT_COMMANDS
define TARGET_FMT_COMMANDS
command1 # note this these commands should be prefixed with TAB character
command2
endef
endif

define RULE_TEMPLATE
%-target.fmt: $(1)
$$(call TARGET_FMT_COMMANDS)

endef

# define the default dependencies, notice the ?= assignment
TARGET_DEPS?=list dependencies here

# instantiate the template for the default case
$(eval $(call RULE_TEMPLATE,$(TARGET_DEPS)))

然后进入调用代码,只需在包含工具包之前定义 TARGET_FMT_COMMANDS 和 TARGET_DEPS 就可以了。

(请原谅定义/变量的名称,它们只是一个示例)

初步答案:
好吧,我会在工具包中写这个:
define TARGET_FMT_COMMANDS
command1 # note this these commands should be prefixed with TAB character
command2
endef

%-target.fmt:
$(call TARGET_FMT_COMMANDS)

您可以在 include toolkit/Makefile 之后简单地重新定义 TARGET_FMT_COMMANDS

诀窍是系统地在定义中的命令之前使用 TAB 字符,否则会出现奇怪的错误。

您也可以像往常一样为定义提供参数。

关于makefile - 使溢出¹,或 “How to override a target?”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41391847/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com