Makefile:如何正确地包含头文件和它的目录?

时间:2021-08-20 12:59:15

I have the following 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

This makefile and all three source files Lock.cpp, DBC.cpp, Trace.cpp are located in the current directory called Core. One of the source file Trace.cpp contains a line that includes a header file outside the current directory:

这个makefile和所有三个源文件锁定。cpp,DBC。cpp痕迹。cpp位于当前名为Core的目录中。一个源文件跟踪。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. So that's why I added INC_DIR = ../StdCUtil in the makefile. The overall directory structure looks like the following:

头文件分裂。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.h even if I specify the INC_DIR in the makefile? How to correct this?

为什么这没有发现头文件分割。即使我在makefile中指定了INC_DIR ?如何纠正呢?

4 个解决方案

#1


24  

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 -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”。“在您的源文件中,您的依赖项应该是./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. Object, for example. With this, your makefile becomes:

在这种布局中,通常将对象文件(可能是可执行文件)放在与您的核心和StdCUtil目录并行的子目录中。例如,对象。这样,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)

#2


4  

The preprocessor is looking for StdCUtil/split.h in

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

  • ./ (i.e. /root/Core/, the directory that contains the #include statement). So ./ + StdCUtil/split.h = ./StdCUtil/split.h and the file is missing
  • ./(也就是/(例如/根/ core/,包含#include语句的目录)。所以。/ + StdCUtil /分裂。h =。/ StdCUtil /分裂。文件不见了。

and in

而在

  • $INC_DIR (i.e. ../StdCUtil/ = /root/Core/../StdCUtil/ = /root/StdCUtil/). So ../StdCUtil/ + StdCUtil/split.h = ../StdCUtil/StdCUtil/split.h and the file is missing
  • 美元INC_DIR(即. ./ StdCUtil / = /root/Core/../ StdCUtil / = /root/StdCUtil/)。所以. ./ StdCUtil / + StdCUtil /分裂。h = . . / StdCUtil StdCUtil /分裂。文件不见了。

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)

#3


0  

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". 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/StdCUtil/split.h”。这是编译器组合包含路径时的结果。/StdCUtil“从#include指令的相对路径包括“StdCUtil/split.h”。

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

要解决这个问题,只需使用-I..而不是我. . / StdCUtil。

#4


0  

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包括

#1


24  

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 -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”。“在您的源文件中,您的依赖项应该是./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. Object, for example. With this, your makefile becomes:

在这种布局中,通常将对象文件(可能是可执行文件)放在与您的核心和StdCUtil目录并行的子目录中。例如,对象。这样,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)

#2


4  

The preprocessor is looking for StdCUtil/split.h in

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

  • ./ (i.e. /root/Core/, the directory that contains the #include statement). So ./ + StdCUtil/split.h = ./StdCUtil/split.h and the file is missing
  • ./(也就是/(例如/根/ core/,包含#include语句的目录)。所以。/ + StdCUtil /分裂。h =。/ StdCUtil /分裂。文件不见了。

and in

而在

  • $INC_DIR (i.e. ../StdCUtil/ = /root/Core/../StdCUtil/ = /root/StdCUtil/). So ../StdCUtil/ + StdCUtil/split.h = ../StdCUtil/StdCUtil/split.h and the file is missing
  • 美元INC_DIR(即. ./ StdCUtil / = /root/Core/../ StdCUtil / = /root/StdCUtil/)。所以. ./ StdCUtil / + StdCUtil /分裂。h = . . / StdCUtil StdCUtil /分裂。文件不见了。

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)

#3


0  

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". 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/StdCUtil/split.h”。这是编译器组合包含路径时的结果。/StdCUtil“从#include指令的相对路径包括“StdCUtil/split.h”。

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

要解决这个问题,只需使用-I..而不是我. . / StdCUtil。

#4


0  

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包括