如何无需编写完整路径引入本地头文件?
编译时头文件找不到的替代解决方案
项目结构
project │ ├── bin │ └── makefile ├── include │ ├── defs.h │ ├── func.h │ └── print.h └── src ├── func.c ├── main.c └── print.c
当前使用的Makefile
OBJS = func.o print.o main.o TARGET = program INCLUDE_DIR = ../include SRC_DIR = ../src vpath %.h $(INCLUDE_DIR) vpath %.c $(SRC_DIR) .PHONY: clean $(TARGET): $(OBJS) $(CC) $^ -o $@ $(OBJS): defs.h clean: rm $(OBJS) $(TARGET)
报错信息
cc -c -o func.o ../src/func.c cc -c -o print.o ../src/print.c cc -c -o main.o ../src/main.c ../src/main.c:1:10: fatal error: func.h: Нет такого файла или каталога #include "func.h" ^~~~~~~~ compilation terminated. make: *** [<встроенное>: main.o] Ошибка 1
注:俄文“Нет такого файла или каталога”意为“没有该文件或目录”
替代解决方案(无需修改#include路径)
问题根源是:vpath仅用于帮助Make工具定位源文件和头文件以生成依赖规则,但编译器在预处理阶段并不知道vpath的设置,仍需要明确告知头文件搜索目录。
方案1:添加全局编译参数指定头文件目录
修改Makefile,添加CFLAGS变量传递头文件搜索路径给编译器:
OBJS = func.o print.o main.o TARGET = program INCLUDE_DIR = ../include SRC_DIR = ../src # 新增:告诉编译器去INCLUDE_DIR目录下查找头文件 CFLAGS += -I$(INCLUDE_DIR) vpath %.h $(INCLUDE_DIR) vpath %.c $(SRC_DIR) .PHONY: clean $(TARGET): $(OBJS) $(CC) $^ -o $@ $(OBJS): defs.h clean: rm $(OBJS) $(TARGET)
-I参数的作用是向编译器的头文件搜索路径中添加指定目录,这样编译器就能识别#include "func.h"这类相对路径的头文件。
方案2:显式编写目标文件的编译规则
如果不想全局设置CFLAGS,可以为每个.o文件编写显式编译规则,在命令中指定-I参数:
OBJS = func.o print.o main.o TARGET = program INCLUDE_DIR = ../include SRC_DIR = ../src vpath %.h $(INCLUDE_DIR) vpath %.c $(SRC_DIR) .PHONY: clean $(TARGET): $(OBJS) $(CC) $^ -o $@ # 显式指定每个.o文件的编译命令,添加头文件搜索路径 %.o: %.c defs.h $(CC) $(CFLAGS) -I$(INCLUDE_DIR) -c $< -o $@ clean: rm $(OBJS) $(TARGET)
这种方式更灵活,适合需要为不同目标定制编译参数的场景。
内容的提问来源于stack exchange,提问作者Maks Ternovoy
相关产品推荐
相关产品推荐

