简体   繁体   English

Makefile 变量未按预期工作

[英]Makefile variables not working as expected

I am trying to compile a program using this makefile:我正在尝试使用此 makefile 编译程序:

GCCPARAMS = -m32 -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore
ASPARAMS = --32

objects = src/loader.o src/kernel.o

%.o: src/%.cpp
    gcc $(GCCPARAMS) -c -o $@ $<

%.o: src/%.s
    echo $(ASPARAMS)
    as $(ASPARAMS) -o $@ $<

kernel.bin: linker.ld $(objects)
    ld $(LDPARAMS) -T $< -o $@ $(objects)

install: kernel.bin
    sudo cp $< boot/mykernel.bin

The problem comes when doing make which prints the following:执行make时会出现问题,它会打印以下内容:

as   -o src/loader.o src/loader.s
src/loader.s: Assembler messages:
src/loader.s: Warning: end of file not at end of a line; newline inserted
src/loader.s:18: Error: operand type mismatch for `push'
src/loader.s:19: Error: operand type mismatch for `push'
make: *** [<builtin>: src/loader.o] Error 1

As you can se the variable is not properly set, instead, make puts a space where the variable should be.如您所见,该变量未正确设置,相反, make在变量应有的位置放置一个空格。 That causes the assembler compiler to think it's a 64 bit architecture and giving some errors.这会导致汇编编译器认为它是 64 位架构并给出一些错误。

Any idea of what is going on?知道发生了什么吗? I am doing this using WSL2 by the way.顺便说一句,我正在使用 WSL2 执行此操作。

The reason you see this is because your recipe rules are wrong.你看到这个的原因是你的食谱规则是错误的。

You have these object files:你有这些 object 文件:

objects = src/loader.o src/kernel.o

and you have this rule:你有这个规则:

%.o: src/%.s
        echo $(ASPARAMS)
        as $(ASPARAMS) -o $@ $<

When trying to build src/loader.o what does the stem of the pattern %.o match?在尝试构建src/loader.o时,模式%.o的主干匹配什么? It will match src/loader of course.它当然会匹配src/loader So then what will the prerequisite be?那么前提条件是什么呢? It will be src/%.s with the stem expanded, so it will be src/src/loader.s .它将是src/%.s扩展了词干,所以它将是src/src/loader.s I presume that this doesn't exist.我认为这不存在。

As a result of this, this pattern rule doesn't match.因此,此模式规则不匹配。 So what does make do?那么 make 做什么呢? It looks for a different pattern rule, and it turns out that GNU make provides a default pattern rule to build a .s file, which uses a pattern %.o: %.s and that pattern DOES match, so that's used.它寻找不同的模式规则,事实证明 GNU make 提供了一个默认模式规则来构建一个.s文件,该文件使用模式%.o: %.s并且该模式确实匹配,所以使用了。

But that built-in rule uses the standard make variables, which are AS and ASFLAGS .但是该内置规则使用标准 make 变量,即ASASFLAGS You haven't set ASFLAGS , so no flags are used.您尚未设置ASFLAGS ,因此不使用任何标志。

You can tell that it's not using your rule because your rule has an echo... in it and make does not print that command out.您可以说它没有使用您的规则,因为您的规则中有一个echo...并且 make 不会打印该命令。 Therefore, it's not running your rule.因此,它不符合您的规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM