为什么目标'mykernel.bin'的配方失败了?

时间:2018-05-25 09:07:39

标签: makefile

我正在尝试使用Ubuntu创建一个简单的mykernel.bin文件。

GPPPARAM = -m32 -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exception -fno-leading-underscore
ASPARAMS = --32
LDPARAMS = -m elf_i386
objects = loader.o kernel.o

%o: %.cpp
    g++ $(GPPPARAM) -o $@ -c $<

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

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

输出是:

制作mykernel.bin ld -m elf_i386 -T linker.ld -o mykernel.bin loader.o kernel.o ld:i386:x86-64输入文件架构loader.o' is incompatible with i386 output ld: i386:x86-64 architecture of input file kernel.o'与i386输出不兼容 Makefile:13:目标'mykernel.bin'的配方失败 make:*** [mykernel.bin]错误1

1 个答案:

答案 0 :(得分:0)

如果要显示完整的输出,包括目标文件的编译行,那么很明显您的编译器标志不会用于编译源代码。因此,生成的目标文件适用于您的本机操作系统,当您需要32位时,该文件很可能是64位。

原因如上所述:您的模式规则是错误的。您想写%o : %.cpp时写过%.o : %.cpp。您编写的模式规则告诉如果它想要构建文件loader.o(因此模式%o的词干匹配loader.),它可以通过编译文件来实现loader..cpp {1}}(因为%中的模式字符%.cpp已替换为词干loader.)。由于没有loader..cpp文件,因此您的模式将被丢弃,因为不匹配,并继续寻找另一个模式,并找到一个,作为内置规则。

但由于您使用的是非标准变量名GPPPARAM而不是标准CXXFLAGS,因此默认规则不会使用任何标志。

您有两种选择:您可以修复模式规则,使其正确无误:

%.o: %.cpp
        g++ $(GPPPARAM) -o $@ -c $<

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

或者您可以摆脱自己的模式规则并使用make的内置规则,并设置标准变量以确保使用您的选项:

CXX := g++
CXXFLAGS := -m32 -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exception -fno-leading-underscore

AS := as
ASFLAGS := --32