试图理解有关GNU makefile解析/执行的EXACT过程流/逻辑



我一直在阅读GNU make站点,但很多东西似乎被遗漏了。很明显,变量扩展有两个阶段,但我不清楚扩展/组合规则会发生什么。

例如,我在这里为链接器编写了一条规则,我故意用它触发了一个错误。。。


$(BUILD)/$(APP_NAME): $(OBJ_LIST)
$(FP_COMPILER) $(PARAMS) $^ $(LPARAMS) -o $(BUILD)/$(APP_NAME)
$(BUILD)/$(APP_NAME): foo
foo:
@echo bar

在调用链接器配方之前的某个阶段,"foo"被附加到先决条件列表中,并通过扩展$^显示在输入列表中。因为foo不是一个对象文件,所以我们得到了错误。

C:/msys64/mingw64/bin/g++.exe -Wall -g3 build/obj/main.o build/obj/phase1.o build/obj/phase2.o build/obj/phase3.o build/obj/helper/line_fetcher.o foo -lstdc++ -lm  -o build/test.exe
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find foo: No such file or directory
collect2.exe: error: ld returned 1 exit status

即使将"foo"列为.phoney也不会阻止它在$^扩展时出现。如果我想有一个先决条件目标,在链接之前做一些事情,我必须找到其他地方放它,这样当$^扩展时它就不会出现。

我知道有一些方法可以提取"*"。o";我想要的链接器文件(我已经想好了(。这不是我的问题。我更感兴趣的是理解";制造";所以我不会遇到其他类型的错误,因为事情的解析/执行顺序出乎我的意料。

对于SO问题,这里有太多非常不同的问题。请选择一个问题并清晰地提问。

您似乎已经找到了最好的资源,GNU制作手册。你问:

没有解释的是如何以及何时扩展规则集本身。

但这已经解释过了,在显示规则如何扩展的同一页中:

immediate : immediate ; deferred
deferred

如果这不是你想要的答案,你需要更清楚地关注你的问题,并解释为什么这还不清楚。

你也会问:

如果我想有一个先决条件目标在链接之前做一些事情,我必须找到其他地方放它,这样当$^展开时它就不会出现。

;另一个放它的地方";。Makefile只有目标和先决条件,$^的定义是它扩展到所有先决条件。就这样,没有别的了。

如果有一些先决条件不希望出现在链接行中,则必须使用一个函数仅扩展到所需的先决条件,例如$(filter %.o,$^)

最新更新