c++ - 2个目录,3个头文件的makefile错误

标签 c++ makefile gnu-make

我里面存放了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/

相关文章:

makefile - gnu 生成文件 : shell function execution order in a recipe

c++ - facet 的 get_time 不断失败

一个简短的例子没有分配被释放的c++指针

makefile - 使用 make,如何在程序集项目中使用 .c 文件防止这种行为?

mysql - 更改 makefile 后 C makefile 无法编译

c++ - GCC 版本/标志和 FAM

c++ [gamestate]函数不接受正确的参数错误

c++ - 在 POSIX 中正确使用消息队列

makefile - 如何在 makefile 中指定 RPATH?

windows - 有没有办法用/代替 Gnu Make 命令目标?