我正在尝试使用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
答案 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