这里是我的目录结构的示例:
TopDir
|-Makefile
|-Dir1
|- A.c
|- A.h
|- Config.h
|-Dir2
|- B.c
|- B.h
|- Config.h
这是我的直接代码(每个子目录都遵循相同的模式):
In file Config.h
# SomeConfig
in file A.h
#include "Config.h"
in file A.c
#include "A.h"
这是我的Makefile:
CC = gcc
INC_DIR = -IDir1 \
-IDir2
CFLAGS = -Wall -Wextra -pedantic $(INC_DIR)
AExe: A.c
$(CC) $(CFLAGS) -o $@ $
BExe: A.c B.c
$(CC) $(CFLAGS) -o $@ $
当我编译时,我只是打电话:
$make AExe
或
$make BExe
我的问题是,由于-I规则,我无法包含/构建特定于其自己目录的Config,因为它只是盲目地选择它找到的第一个Config.h。 AExe构建良好,包括其自己的Config。但是,BExe首先在Dir1中找到Config.h,而在Dir2中忽略Config.h。如果我先反转INC_DIR顺序以包含Dir2,则B.h将获得正确的Config。就我而言,我有更多具有相似结构的目录,它们都可能仅依赖于其他目录头文件。配置是针对特定目录的。如何在Makefile中指示A.h使用其自己的Config.h和B.h使用其自己的Config.h。
在这种情况下,类似
#include "Dir1/Config.h"
可能有意义。但是,如果您想保持源文件(包括头文件)的原样,就必须调整makefile。
BExe
由A.c
和B.c
组成。我们可以看到A.c
包含一个Config.h
,大概B.c
包含另一个#include "Config.h"
语句,因此我们将有两个A.o: A.c
...
B.o: B.c
...
AExe: A.o
$(CC) $(CFLAGS) -o $@ $^
BExe: A.o B.o
$(CC) $(CFLAGS) -o $@ $^
语句引用不同的文件,因此我们无法使用一个命令来处理它们并希望保留它们直行。我们必须分别编译它们,然后链接目标文件:
...
现在为A.c
。您必须告诉Make如何找到源文件B.c
和Config.h
,但是一旦完成,它将在包含源文件的目录中搜索包含文件(例如Dir1/Config.h
)。因此,在编译Dir/A.c
时将使用Dir2/Config.h
,在编译Dir2/B.c
时将使用A.c
。
[剩下的唯一一件事就是告诉Make在哪里可以找到B.c
和A.o: Dir1/A.c
...
B.o: Dir2/B.c
...
。您可以明确地执行此操作:
the vpath
directive
或使用类似vpath
的内容:
vpath %.c Dir1 Dir2
A.o: A.c
...
B.o: B.c
...
一种解决方案是更改:
INC_DIR=-I$(CURDIR)
然后,如果您需要包含其他目录的标头,请执行以下操作:
#include <AnotherDir/Header.h>
要包含来自同一目录的标头,请执行以下操作:
#include "Header.h"
首先在同一目录中寻找Header.h
。
因此,如果:
// Dir1/A.h
#include "Config.h"
然后:
// Dir2/B.h
#include <Dir1/A.h>
[B.h
包含预期的<Dir1/A.h>
和<Dir1/Config.h>
。