我里面存放了2个Dirs和3个头文件,如下:
目录 A:包含头文件 A 和 C Dir B : 包含头文件 B
目录 A 和目录 B 是名为 Apps 的目录(该目录是其他一些目录的子目录)的子目录。
基本上,问题发生在类似的情况下,我从中隔离了问题。因此,下面显示的 C++ 源文件很简单:
头文件A.h:
#ifndef A_H
#define A_H
class A
{
};
#endif /// A_H
头文件C.h:
#ifndef C_H
#define C_H
#include "B.h"
class C
{
};
A.h 的测试器,即。测试A.cpp:
/** TestA.cpp */
#include "A.h"
/// ...
int main()
{
}
C.h 测试仪,即。测试C.cpp:
/** TestC.cpp */
#include "C.h"
/// ...
int main()
{
}
目录 B 包含 1 个 C++ 头文件 B.h 及其测试程序 TestB.cpp,两者都很简单:
头文件B.h:
#ifndef B_H
#define B_H
#include "A.h"
class B
{
};
#endif /// B_H
B.h 的测试器,即。测试B.cpp:
/** TestB.cpp */
#include "B.h"
/// ...
int main()
{
}
3个测试者TestA.cpp、TestB.cpp和TestC.cpp分别有3个makefile:MakeA、MakeB和MakeC。正如预期的那样,MakeA 和 MakeC 在目录 A 中,而 MakeB 在目录 B 中。
我没有展示 MakeA 和 MakeB,因为它们工作正常。
MakeC中出现的错误:
CPP = g++
OFLAG = -o
CFLAG = -std=c++11 -c
PROG1 = TestC
HC = C
HB = B
HA = A
HBDIR = ../B/
HADIR = ./
IHBDIR = -I$(HBDIR)
IHADIR = -I$(HADIR)
all : $(PROG1).o $(PROG1).exe run1
$(PROG1).o : $(PROG1).cpp $(HADIR)$(HC).h $(HBDIR)$(HB).h $(HADIR)$(HA).h
$(CPP) $(CFLAG) $(IHADIR) $(IHBDIR) $<
$(PROG1).exe : $(PROG1).o
$(CPP) $(OFLAG) $@ $^
run1:
$(PROG1)
这个 make 文件无法找到头文件 A(它被头文件 B #included)并给出以下错误:
In file ...
../B/B.h fatal error: A.h : no such file or directory
#include "A.h"
compilation terminated
显然,make 正在 B.h 的目录中搜索 A.h(因为 B.h #includes A.h)。但是,我已经定义了符号 HADIR(如 ./),这应该会导致 make 在默认目录(即目录 A)中进行搜索。
请注意:
1) 头文件引用简单且线性:A.h 由 B.h #included,B.h #included 由 C.h。
2) 我不想在源文件中硬编码目录路径。它们必须仅存储在 makefile 中,因为这是 makefile 的目的之一。
3) 据我所知,该问题有两种解决方案: a) 将 C.h、它的测试器和 makefile 重新定位到目录 C。但是,我不想这样做,因为 A.h 和 C.h 在语义上是相关的。 b) 在 MakeC 中,将 HADIR 定义为 ../A,而不是 ./但我不明白为什么我应该这样做。
以MakeC为输入makefile调用make工具的BAT文件如下:
cd /f/Files/C/SW/Applications/Samples/C++Samples/Introductory/
Classes/Apps/A/
make -f MakeC
谢谢。
最佳答案
参见 this link有关哪些路径包含搜索的信息。假设您使用了 include "file"
的形式(带引号,不是 #include <file>
,略有不同):
By default, the preprocessor looks for header files included by the quote form of the directive #include "file" first relative to the directory of the current file, and then in a preconfigured list of standard system directories. For example, if /usr/include/sys/stat.h contains #include "types.h", GCC looks for types.h first in /usr/include/sys, then in its usual search path.
...
There are a number of command-line options you can use to add additional directories to the search path. The most commonly-used option is -Idir, which causes dir to be searched after the current directory (for the quote form of the directive) and ahead of the standard system directories. You can specify multiple -I options on the command line, in which case the directories are searched in left-to-right order.
注意
directory of the current file
指的是调用 gcc 的目录,而不是源文件的目录(不是最好的措辞)。因此,如果您从 .c 文件的目录中调用 gcc,您需要添加一个 -IA -IB
。标记您的编译器选项,然后不要在 #include
中包含路径指令(假设从 .c 文件的目录调用 gcc)。
如果您确实想要包含路径,它们必须是相对于从中调用 gcc 的目录,或者由 -I
指定的其他包含路径之一。选项。
----编辑-----
好的,我刚刚阅读了您的更新,似乎 TestC.c 在目录 A 中,我没有从您的原始帖子中获得这意味着您是从目录 A 编译的。在这种情况下,我无法重现您的问题(至少在我的 linux 系统上没有):
[157]~/tmp/tmp9/A> find .. -type f -exec echo "------ " {} " ------" \; -exec more {} \;
------ ../A/A.h ------
#pragma message "A.h"
// blank
------ ../A/C.h ------
#pragma message "C.h"
#include "B.h"
------ ../A/testC.c ------
#pragma "message file.c"
#include "C.h"
int main() {}
------ ../B/B.h ------
#pragma message B.H
#include "A.h"
[157]~/tmp/tmp9/A> gcc -I. -I../B testC.c
In file included from testC.c:2:
C.h:1: note: #pragma message: C.h
In file included from C.h:2,
from testC.c:2:
../B/B.h:1: warning: expected a string after ‘#pragma message’
In file included from ../B/B.h:2,
from C.h:2,
from testC.c:2:
./A.h:1: note: #pragma message: A.h
[157]~/tmp/tmp9/A>
您的 make 命令应该与用于构建测试程序的命令相呼应——将该输出附加到问题上。
关于c++ - 2个目录,3个头文件的makefile错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47828034/