makefile - 为什么目标“mykernel.bin”的配方失败了?
问题描述
我正在尝试使用 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)
输出是:
make mykernel.bin ld -m elf_i386 -T linker.ld -o mykernel.bin loader.o kernel.o ld: i386:x86-64 architecture of input file loader.o' is incompatible with i386 output
ld: i386:x86-64 architecture of input file
kernel.o' is in compatible with i386 output Makefile:13: recipe for目标 'mykernel.bin' 失败 make: *** [mykernel.bin] 错误 1
解决方案
如果你要显示完整的输出,包括你的目标文件的编译行,那么很明显你的编译器标志没有被用来编译你的源代码。因此,生成的目标文件适用于您的本机操作系统,当您需要 32 位时,它很可能是 64 位。
原因正如我上面所描述的:您的模式规则是错误的。你%o : %.cpp
想写的时候就写了%.o : %.cpp
。您编写的模式规则告诉 make 如果它想要构建一个文件loader.o
(因此模式的 stem%o
匹配loader.
),它可以通过编译文件来实现loader..cpp
(因为模式字符%
in%.cpp
被替换为 stem 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
推荐阅读
- leaflet - 如何从用户输入的 ArcGIS 投影数据中计算出分辨率数组
- swift - Parse - 使用云代码发送推送通知 (Swift)
- javascript - 嵌入消息的记录字段
- javascript - 使用数组访问(深度)嵌套对象属性
- postgresql - PostgresSQL 无法读取我桌面上的 csv 文件
- xamarin - 自定义渲染器在 iOS 上的行为不符合预期
- c# - 如何从另一个 Ienumerable 获取 SelectList
- javascript - 当我的输入为空时,为什么 $(...).val() == "" false?
- testing - 需要一个用于 codeceptjs 的自动完成插件
- javascript - Vue.js 对话框/模态在父组件上关闭