Makefile:如何正确包含头文件及其目录?
我有以下makefile:
CC=g++ INC_DIR = ../StdCUtil CFLAGS=-c -Wall -I$(INC_DIR) DEPS = split.h all: Lock.o DBC.o Trace.o %.o: %.cpp $(DEPS) $(CC) -o $@ $< $(CFLAGS) clean: rm -rf *o all
这个makefile和所有三个源文件Lock.cpp
, DBC.cpp
, Trace.cpp
都位于名为Core
的当前目录中。 其中一个源文件Trace.cpp
包含一行,其中包含当前目录之外的头文件:
//in Trace.cpp #include "StdCUtil/split.h"
头文件split.h
位于当前目录上方的一个级别,然后位于名为StdCUtil
的子目录中。 这就是我在makefile中添加INC_DIR = ../StdCUtil
的原因。 整个目录结构如下所示:
root |___Core | | | |____Makefile | |____DBC.cpp | |____Lock.cpp | |____Trace.cpp | |___StdCUtil |___split.h
但是当我做它时,它给了我错误:
Trace.cpp:8:28: fatal error: StdCUtil/split.h: No such file or directory #include "StdCUtil/split.h" ^ compilation terminated. : recipe for target 'Trace.o' failed
为什么即使我在makefile中指定INC_DIR
,也找不到头文件split.h
? 怎么纠正这个?
makefile中的这些行,
INC_DIR = ../StdCUtil CFLAGS=-c -Wall -I$(INC_DIR) DEPS = split.h
和.cpp文件中的这一行,
#include "StdCUtil/split.h"
有冲突
使用源目录中的makefile并使用-I
选项,您应该#include "split.h" in your source file, and your dependency should be
使用#include "split.h" in your source file, and your dependency should be
../ StdCUtil / split.h`。
另外一个选项:
INC_DIR = ../StdCUtil CFLAGS=-c -Wall -I$(INC_DIR)/.. # Ugly! DEPS = $(INC_DIR)/split.h
这样你的#include
指令将保持为#include "StdCUtil/split.h"
。
另一种选择是将makefile放在父目录中:
root |____Makefile | |___Core | |____DBC.cpp | |____Lock.cpp | |____Trace.cpp | |___StdCUtil |___split.h
通过这种布局,通常将目标文件(可能还有可执行文件)放在与Core
和StdCUtil
目录并行的子目录中。 例如, Object
。 有了这个,你的makefile变成:
INC_DIR = StdCUtil SRC_DIR = Core OBJ_DIR = Object CFLAGS = -c -Wall -I. SRCS = $(SRC_DIR)/Lock.cpp $(SRC_DIR)/DBC.cpp $(SRC_DIR)/Trace.cpp OBJS = $(OBJ_DIR)/Lock.o $(OBJ_DIR)/DBC.o $(OBJ_DIR)/Trace.o # Note: The above will soon get unwieldy. # The wildcard and patsubt commands will come to your rescue. DEPS = $(INC_DIR)/split.h # Note: The above will soon get unwieldy. # You will soon want to use an automatic dependency generator. all: $(OBJS) $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(CC) $(CFLAGS) -c $< -o $@ $(OBJ_DIR)/Trace.o: $(DEPS)
预处理器正在寻找StdCUtil/split.h
-
./
(即/root/Core/
, 包含#include语句的目录 )。 所以./
+StdCUtil/split.h
=./StdCUtil/split.h
并且文件丢失了
并在
-
$INC_DIR
(即../StdCUtil/
=/root/Core/../StdCUtil/
=/root/StdCUtil/
)。 所以../StdCUtil/
+StdCUtil/split.h
=../StdCUtil/StdCUtil/split.h
并且文件丢失了
您可以修复更改$INC_DIR
变量的错误(最佳解决方案):
$INC_DIR = ../
或include指令:
#include "split.h"
但是这样你就失去了“路径语法”,这使得头文件所属的命名空间或模块非常清楚。
参考:
- C ++ #include语义
编辑/ UPDATE
它也应该是
CXX = g++ CXXFLAGS = -c -Wall -I$(INC_DIR) ... %.o: %.cpp $(DEPS) $(CXX) -o $@ $< $(CXXFLAGS)
这不是关于make的问题,而是关于#include
指令的语义的问题。
问题是,路径“../StdCUtil/StdCUtil/split.h”中没有文件。 这是编译器将包含路径“../StdCUtil”与#include
指令“StdCUtil / split.h”的相对路径组合在一起时产生的路径。
要解决此问题,只需使用-I..
而不是-I../StdCUtil
。
尝试INC_DIR=../ ../StdCUtil
。
然后,设置CCFLAGS=-c -Wall $(addprefix -I,$(INC_DIR))
编辑:另外,修改#include
为#include
以便编译器知道使用-I而不是.cpp的本地路径使用#include
。