[英]Makefile: How to correctly include header file and its directory?
I have the following 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
This makefile and all three source files Lock.cpp
, DBC.cpp
, Trace.cpp
are located in the current directory called Core
.这个 makefile 和所有三个源文件Lock.cpp
、 DBC.cpp
、 Trace.cpp
都位于名为Core
的当前目录中。 One of the source file Trace.cpp
contains a line that includes a header file outside the current directory:其中一个源文件Trace.cpp
包含一行,其中包含当前目录之外的头文件:
//in Trace.cpp
#include "StdCUtil/split.h"
The header file split.h
is located at one level above the current directory and then in the subdirectory called StdCUtil
.头文件split.h
位于当前目录的上一级,然后位于名为StdCUtil
的子目录中。 So that's why I added INC_DIR = ../StdCUtil
in the makefile.所以这就是我在 makefile 中添加INC_DIR = ../StdCUtil
的原因。 The overall directory structure looks like the following:整体目录结构如下所示:
root
|___Core
| |
| |____Makefile
| |____DBC.cpp
| |____Lock.cpp
| |____Trace.cpp
|
|___StdCUtil
|___split.h
But when I make it, it gives me the error:但是当我成功时,它给了我错误:
Trace.cpp:8:28: fatal error: StdCUtil/split.h: No such file or directory
#include "StdCUtil/split.h"
^
compilation terminated.
<builtin>: recipe for target 'Trace.o' failed
Why this doesn't find the header file split.h
even if I specify the INC_DIR
in the makefile?为什么即使我在 makefile 中指定了INC_DIR
也找不到头文件split.h
? How to correct this?如何纠正这个?
These lines in your makefile,生成文件中的这些行,
INC_DIR = ../StdCUtil
CFLAGS=-c -Wall -I$(INC_DIR)
DEPS = split.h
and this line in your .cpp file,和你的 .cpp 文件中的这一行,
#include "StdCUtil/split.h"
are in conflict.处于冲突中。
With your makefile in your source directory and with that -I
option you should be using #include "split.h"
in your source file, and your dependency should be ../StdCUtil/split.h
.使用源目录中的 makefile 和-I
选项,您应该在源文件中使用#include "split.h"
,并且您的依赖项应该是../StdCUtil/split.h
。
Another option:另外一个选项:
INC_DIR = ../StdCUtil
CFLAGS=-c -Wall -I$(INC_DIR)/.. # Ugly!
DEPS = $(INC_DIR)/split.h
With this your #include
directive would remain as #include "StdCUtil/split.h"
.有了这个,您的#include
指令将保留为#include "StdCUtil/split.h"
。
Yet another option is to place your makefile in the parent directory:另一种选择是将您的 makefile 放在父目录中:
root
|____Makefile
|
|___Core
| |____DBC.cpp
| |____Lock.cpp
| |____Trace.cpp
|
|___StdCUtil
|___split.h
With this layout it is common to put the object files (and possibly the executable) in a subdirectory that is parallel to your Core
and StdCUtil
directories.使用这种布局,通常将目标文件(可能还有可执行文件)放在与Core
和StdCUtil
目录平行的子目录中。 Object
, for example. Object
,例如。 With this, your makefile becomes:有了这个,你的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)
The preprocessor is looking for StdCUtil/split.h
in预处理器正在寻找StdCUtil/split.h
./
(ie /root/Core/
, the directory that contains the #include statement ). ./
(即/root/Core/
,包含 #include 语句的目录)。 So ./
+ StdCUtil/split.h
= ./StdCUtil/split.h
and the file is missing所以./
+ StdCUtil/split.h
= ./StdCUtil/split.h
并且文件丢失and in并在
$INC_DIR
(ie ../StdCUtil/
= /root/Core/../StdCUtil/
= /root/StdCUtil/
). $INC_DIR
(即../StdCUtil/
= /root/Core/../StdCUtil/
= /root/StdCUtil/
)。 So ../StdCUtil/
+ StdCUtil/split.h
= ../StdCUtil/StdCUtil/split.h
and the file is missing所以../StdCUtil/
+ StdCUtil/split.h
= ../StdCUtil/StdCUtil/split.h
文件丢失You can fix the error changing the $INC_DIR
variable (best solution):您可以修复更改$INC_DIR
变量的错误(最佳解决方案):
$INC_DIR = ../
or the include directive:或包含指令:
#include "split.h"
but in this way you lost the "path syntax" that makes it very clear what namespace or module the header file belongs to.但是通过这种方式,您丢失了“路径语法”,这使得头文件所属的命名空间或模块非常清楚。
Reference:参考:
EDIT/UPDATE编辑/更新
It should also be也应该是
CXX = g++
CXXFLAGS = -c -Wall -I$(INC_DIR)
...
%.o: %.cpp $(DEPS)
$(CXX) -o $@ $< $(CXXFLAGS)
This is not a question about make, it is a question about the semantic of the #include
directive.这不是关于 make 的问题,而是关于#include
指令的语义的问题。
The problem is, that there is no file at the path "../StdCUtil/StdCUtil/split.h".问题是,路径“../StdCUtil/StdCUtil/split.h”中没有文件。 This is the path that results when the compiler combines the include path "../StdCUtil" with the relative path from the #include
directive "StdCUtil/split.h".这是编译器将包含路径“../StdCUtil”与来自#include
指令“StdCUtil/split.h”的相对路径组合在一起时产生的路径。
To fix this, just use -I..
instead of -I../StdCUtil
.要解决此问题,只需使用-I..
而不是-I../StdCUtil
。
Try INC_DIR=../ ../StdCUtil
.尝试INC_DIR=../ ../StdCUtil
。
Then, set CCFLAGS=-c -Wall $(addprefix -I,$(INC_DIR))
然后,设置CCFLAGS=-c -Wall $(addprefix -I,$(INC_DIR))
EDIT: Also, modify your #include
to be #include <StdCUtil/split.h>
so that the compiler knows to use -I rather than local path of the .cpp using the #include
.编辑:另外,将您的#include
修改为#include <StdCUtil/split.h>
以便编译器知道使用 -I 而不是使用#include
的 .cpp 的本地路径。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.