求助:运行Makefile时第19行报错Error 1的原因排查
内核Makefile构建报错:
make: *** [makefile:19: all] Error 1 排查指南 问题重现
我编写了用于内核项目构建的Makefile:
COMPILER = gcc LINKER = ld ASSEMBLER = nasm CFLAGS = -m32 -c -ffreestanding ASFLAGS = -f elf32 LDFLAGS = -m elf_i386 -T src/link.ld EMULATOR = qemu-system-i386 EMULATOR_FLAGS = -kernel OBJS = obj/kasm.o obj/kc.o obj/idt.o obj/isr.o obj/kb.o obj/screen.o obj/string.o obj/system.o obj/util.o obj/shell.o OUTPUT = iknow/boot/kernel.bin run: all $(EMULATOR) $(EMULATOR_FLAGS) $(OUTPUT) all:$(OBJS) mkdir iknow/ -p mkdir iknow/boot/ -p $(LINKER) $(LDFLAGS) -o $(OUTPUT) $(OBJS) obj/kasm.o:src/kernel.asm $(ASSEMBLER) $(ASFLAGS) -o obj/kasm.o src/kernel.asm obj/kc.o:src/kernel.c $(COMPILER) $(CFLAGS) src/kernel.c -o obj/kc.o obj/idt.o:src/idt.c $(COMPILER) $(CFLAGS) src/idt.c -o obj/idt.o obj/kb.o:src/kb.c $(COMPILER) $(CFLAGS) src/kb.c -o obj/kb.o obj/isr.o:src/isr.c $(COMPILER) $(CFLAGS) src/isr.c -o obj/isr.o obj/screen.o:src/screen.c $(COMPILER) $(CFLAGS) src/screen.c -o obj/screen.o obj/string.o:src/string.c $(COMPILER) $(CFLAGS) src/string.c -o obj/string.o obj/system.o:src/system.c $(COMPILER) $(CFLAGS) src/system.c -o obj/system.o obj/util.o:src/util.c $(COMPILER) $(CFLAGS) src/util.c -o obj/util.o obj/shell.o:src/shell.c $(COMPILER) $(CFLAGS) src/shell.c -o obj/shell.o build:all #Activate the install xorr if you do not have it already installed #sudo apt-get install xorriso rm iknow/boot/grub/ -r -f mkdir iknow/boot/grub/ echo set default=0 >> iknow/boot/grub/grub.cfg echo set timeout=0 >> iknow/boot/grub/grub.cfg echo menuentry "IKnow" { >> iknow/boot/grub/grub.cfg echo set root='(hd96)' >> iknow/boot/grub/grub.cfg echo multiboot /boot/kernel.bin >> iknow/boot/grub/grub.cfg echo } >> iknow/boot/grub/grub.cfg grub-mkrescue -o iknow.iso iknow/ clear: rm -f obj/*.o rm -r -f iknow/
执行make(已用root权限)时出现报错:
make: *** [makefile:19: all] Error 1
已排查第19行语法,参考相关社区方案未解决,需要定位报错原因。
排查步骤
1. 强制显示完整命令输出
Make默认会隐藏中间命令的错误信息,重新执行时加参数显示所有细节:
make all V=1
这能直接看到mkdir或ld命令的具体失败原因(比如文件不存在、工具链缺失)。
2. 检查obj目录是否存在
你的Makefile没有创建obj目录的规则,第一次执行时编译生成.o文件会因目录不存在失败。需提前创建:
在Makefile中添加prepare目标并修改all规则:
prepare: mkdir -p obj/ all: prepare $(OBJS) mkdir -p iknow/boot/ $(LINKER) $(LDFLAGS) -o $(OUTPUT) $(OBJS)
3. 验证链接脚本src/link.ld
LDFLAGS指定了-T src/link.ld,如果该文件不存在或格式错误,ld会直接退出。确认:
- 文件路径正确
- 脚本符合i386 ELF链接规范(比如指定入口点、段布局)
4. 检查32位编译工具链完整性
64位系统编译32位内核需要安装多架构依赖:
sudo apt install gcc-multilib nasm binutils-i386 grub-pc-bin xorriso
缺少binutils-i386会导致ld无法生成32位ELF文件,触发链接失败。
5. 手动测试单文件编译
单独编译某个.o文件,排查源文件或编译参数问题:
nasm -f elf32 src/kernel.asm -o obj/kasm.o gcc -m32 -c -ffreestanding src/kernel.c -o obj/kc.o
如果命令执行失败,说明对应源文件或编译环境有问题。
6. 检查Makefile缩进格式
Makefile要求命令行必须用Tab缩进,不能用空格。用以下命令查看缩进是否合规:
cat -A makefile
Tab会显示为^I,如果看到空格代替Tab的情况,直接替换即可。
内容的提问来源于stack exchange,提问作者Akshat Shukla
相关产品推荐
相关产品推荐

