Makefile运行报错No rule to make target 'put.h'原因及修复方案咨询
报错原因分析
这个报错本质是Make工具在处理straps.o的依赖项时,无法找到声明的put.h文件,和GCC编译阶段的头文件检索无关。触发问题的核心原因有两个:
- 子Makefile的VPATH路径配置错误
你在arch/riscv/kernel/Makefile中写的VPATH=../../include是基于直接进入kernel目录执行make的场景设计的,但通常编译这类项目都是在顶层根目录执行make run,此时递归调用子Makefile时的工作目录仍是项目根目录,../../include会被解析为根目录向上两层的路径,完全无法匹配到项目内的include目录,Make检索不到put.h就会抛出该报错。 - 顶层Makefile的INCLUDE相对路径不兼容递归编译场景
顶层定义的INCLUDE = -I ../include同样是基于子目录执行make的场景设计的,在根目录执行make时,该路径会指向根目录的上级目录,同样找不到头文件。
可行修复方案
可以根据你的编译习惯选择任意一种方案:
方案1:统一使用绝对路径适配全场景编译
该方案适配任意目录下执行make的场景,不会出现路径错乱问题:
- 首先修改顶层Makefile的配置,新增头文件绝对路径定义:
export CROSS_= riscv64-unknown-elf- AR=${CROSS_}ar GCC=${CROSS_}gcc LD=${CROSS_}ld OBJCOPY=${CROSS_}objcopy ISA ?= rv64imafd ABI ?= lp64 # 新增头文件目录绝对路径并导出 export INCLUDE_DIR := $(abspath ./include) INCLUDE = -I $(INCLUDE_DIR) CF = -g -O3 -march=$(ISA) -mabi=$(ABI) -mcmodel=medany -ffunction-sections -fdata-sections -nostartfiles -nostdlib -nostdinc -static -lgcc -Wl,--nmagic -Wl,--gc-sections CFLAG = ${CF} ${INCLUDE}
- 然后修改
arch/riscv/kernel/Makefile的VPATH配置:
VPATH=$(INCLUDE_DIR) all : straps.o entry.o head.o straps.o : straps.c put.h $(GCC) -c straps.c $(CFLAG) entry.o : entry.S $(GCC) -c entry.S $(CFLAG) head.o : head.S $(GCC) -c head.S $(CFLAG)
方案2:仅适配顶层目录执行编译的场景
如果你只会在项目根目录执行make,可以直接修正相对路径即可:
- 顶层Makefile的INCLUDE修改为:
INCLUDE = -I ./include
- 子Makefile的VPATH修改为:
VPATH = ./include
方案3:去掉手动头文件依赖,使用自动依赖生成
手动声明头文件依赖很容易出错,更推荐用GCC的自动依赖生成能力避免该问题:
- 在顶层Makefile的CF变量中加入自动依赖生成参数:
CF = -g -O3 -march=$(ISA) -mabi=$(ABI) -mcmodel=medany -ffunction-sections -fdata-sections -nostartfiles -nostdlib -nostdinc -static -lgcc -Wl,--nmagic -Wl,--gc-sections -MMD -MP
- 修改
arch/riscv/kernel/Makefile,去掉straps.o依赖中手动声明的put.h:
VPATH=../../include all : straps.o entry.o head.o straps.o : straps.c $(GCC) -c straps.c $(CFLAG) entry.o : entry.S $(GCC) -c entry.S $(CFLAG) head.o : head.S $(GCC) -c head.S $(CFLAG)
编译时GCC会自动生成.d后缀的依赖文件,自动识别straps.c引用的头文件并加入依赖,无需手动声明,从根源避免路径写错的问题。
内容的提问来源于stack exchange,提问作者Peter Yap
相关产品推荐
相关产品推荐

