gpt4 book ai didi

linux - 递归 make 递归太多,需要一个虚拟先决条件

转载 作者:太空宇宙 更新时间:2023-11-04 11:32:12 24 4
gpt4 key购买 nike

我有一个非常简单的 Makefile,它没有按照我的预期执行。最终目标是它应该递归地调用自己,每次都包含适当的文件,从而生成特定于所包含内容的构建(我正在构建几个项目,它们都共享相同的代码库,但使用源文件的不同组合).我从来没有真正处理过递归调用,所以我一定遗漏了一些明显的东西。目前,我的 Makefile 所在的文件夹中只有一个 .mk 文件。这是一个简单的单行代码,仅用于此测试。它最终将包含各种针对每个项目的设置。

生成文件:

SHELL = /bin/sh

ifdef MYFILE
include $(MYFILE)
PROGRAM = $(basename $(MYFILE))
endif

all: $(wildcard *.mk)

dummy:
@echo -- Entering dummy stub ... why do I need this?

%.mk: dummy
@echo Calling $(MAKE) MYFILE=$@ $*
$(MAKE) MYFILE=$@ $*

$(PROGRAM): objs
@echo Time to link!

objs:
@echo Building objs!

测试.mk

SOMEVAR = SomeValue

我有以下两个问题:

问题1

如果我从我的模式规则中删除 dummy 先决条件,则永远不会调用模式规则(我得到可怕的“Nothing to be done for all”错误)。有没有一种方法可以让 %.mk 规则下的食谱在不需要虚拟先决条件的情况下运行?

问题2

鉴于上述两个文件,我希望 make 执行以下操作:

  1. make[1] 启动并命中all 规则
  2. make[1] 跳转到 %.mk 模式规则
  3. make[1] 递归调用自身(调用看起来像 make MYFILE=test.mk test)
  4. make[2] 启动,包含test.mk 文件,并设置PROGRAM 变量
  5. make[2] 跳转到 $(PROGRAM) 规则(因为我们是用那个目标明确调用的)
  6. make[2] 跳转到 objs 规则,运行配方,然后返回链上

实际上,make 卡在 %.mk 模式规则上并进入无限循环。我不明白为什么它坚持要达到模式规则,当我在我的第一次递归调用中明确告诉它构建 test (应该对应于 $(PROGRAM) 目标)。我在这里缺少什么?

最佳答案

问题 0:
这是过度设计的。您不需要在此处使用递归 Make。

问题 1:
Make 不尝试重建 test.mk(没有虚拟 preq)的原因是 test.mk 是最新的。更好的方法是切换到静态模式规则并使用 PHONY:

MKS = $(wildcard *.mk)
.PHONY: $(MKS)

$(MKS): %.mk:
@echo Calling $(MAKE) MYFILE=$@ $*
$(MAKE) MYFILE=$@ $*

更好的方法是不使用真实文件的名称作为不重建(甚至“触摸”)该文件的规则的目标。

问题 2:
在 make[2] 中,makefile 包含 test.mk。如果 makefile 包含另一个文件,Make 将在执行任何其他操作之前尝试重建该文件。如果该文件有规则(存在)并且成功(确实如此),则 Make 会重新调用自身。

您应该从头开始重新考虑此设计。有很多方法可以获得您正在寻找的行为,具体取决于具体情况(foo.mk 中将定义多少变量?您真的想通过手动移动这些变量来管理构建吗?周围的文件?等等)。

P.S. 我想到了一个问题。它是否适合您的情况取决于具体情况:

生成文件:

# includes nothing

%.mk: dummy
@echo Calling $(MAKE) MYFILE=$@ -f $@ $*
$(MAKE) MYFILE=$@ -f $@ $*

测试.mk:

SOMEVAR = SomeValue
include makefile

关于linux - 递归 make 递归太多,需要一个虚拟先决条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10451959/

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