C++ Makefile:如何正确包含头文件及其目录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22545029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:07:04  来源:igfitidea点击:

Makefile: How to correctly include header file and its directory?

c++cmakefile

提问by tonga

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.cppare located in the current directory called Core. One of the source file Trace.cppcontains a line that includes a header file outside the current directory:

此生成的文件和所有三个源文件Lock.cppDBC.cppTrace.cpp位于被称为当前目录Core。其中一个源文件Trace.cpp包含一行,该行包含当前目录之外的头文件:

//in Trace.cpp
#include "StdCUtil/split.h"

The header file split.his located at one level above the current directory and then in the subdirectory called StdCUtil. So that's why I added INC_DIR = ../StdCUtilin the makefile. The overall directory structure looks like the following:

头文件split.h位于当前目录的上一级,然后位于名为StdCUtil. 所以这就是我INC_DIR = ../StdCUtil在makefile中添加的原因。整体目录结构如下所示:

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.heven if I specify the INC_DIRin the makefile? How to correct this?

为什么split.h即使我INC_DIR在 makefile 中指定了头文件也找不到头文件?如何纠正这个?

回答by David Hammen

These lines in your makefile,

你的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 -Ioption 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 #includedirective 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 Coreand StdCUtildirectories. Object, for example. With this, your makefile becomes:

使用这种布局,通常将目标文件(可能还有可执行文件)放在与您的CoreStdCUtil目录平行的子目录中。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)

回答by manlio

The preprocessor is looking for StdCUtil/split.hin

预处理器正在寻找StdCUtil/split.h

and in

并在

  • $INC_DIR(i.e. ../StdCUtil/= /root/Core/../StdCUtil/= /root/StdCUtil/). So ../StdCUtil/+ StdCUtil/split.h= ../StdCUtil/StdCUtil/split.hand the file is missing
  • $INC_DIR(即../StdCUtil/= /root/Core/../StdCUtil/= /root/StdCUtil/)。所以../StdCUtil/+ StdCUtil/split.h=../StdCUtil/StdCUtil/split.h并且文件丢失

You can fix the error changing the $INC_DIRvariable (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)

回答by Bill Perkins

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 #includeto 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 而不是使用 .cpp 的本地路径#include

回答by cmaster - reinstate monica

This is not a question about make, it is a question about the semantic of the #includedirective.

这不是关于 make 的问题,而是关于#include指令语义的问题。

The problem is, that there is no file at the path "../StdCUtil/StdCUtil/split.h". This is the path that results when the compiler combines the include path "../StdCUtil" with the relative path from the #includedirective "StdCUtil/split.h".

问题是,路径“../StdCUtil/StdCUtil/split.h”中没有文件。这是编译器将包含路径“../StdCUtil”与来自#include指令“StdCUtil/split.h”的相对路径组合在一起时产生的路径。

To fix this, just use -I..instead of -I../StdCUtil.

要解决此问题,只需使用-I..代替-I../StdCUtil