包含来自不同目录的单个标头

时间:2017-12-21 22:53:52

标签: c gcc makefile

我有一个小构建,我想在其中只包含来自不同目录的单个头文件(和源文件)。我知道如何使用-I参数,但不想包含整个目录,只包括单个文件。

我的makefile如下所示:

myproj: ui.o data.o string.o
    c99 -ggdb -o myproj ui.o data.o string.o
    ctags *

ui.o : ui.c data.h
    c99 -ggdb -c ui.c

data.o : data.c data.h
    c99 -ggdb -c data.c

string.o : ../../shared/src/string.c ../../shared/src/string.h
    c99 -ggdb -c ../../shared/src/string.c ../../shared/src/string.h -o ./jcstring.o

当我试图让它抱怨找不到string.h时:

c99 -ggdb -c ui.c ../../shared/src/string.h
In file included from ui.c:7:0:
data.h:1:22: fatal error: string.h: No such file or directory
 #include "string.h"

如何在不包含整个目录的情况下包含此文件?

1 个答案:

答案 0 :(得分:3)

  

我知道如何使用-I参数,但不想包含整个目录,只包含单个文件。

-I不包含“目录”,只是将目录放在搜索路径上。目录包含您不想要的其他文件并不重要。编译器将读取的唯一文件是名称在#include指令中的文件。因此,如果您有../../shared/src/string.h,则可以使用以下编译命令:

c99 -ggdb -I ../../shared/src -c ui.c

string.的情况下,标题与源文件位于同一目录中。这是编译器首先查看的位置,因此您根本不需要-I

c99 -ggdb -c ../../shared/src/string.c -o ./jcstring.o

添加-I选项可能会受到影响的唯一情况是,在不同目录中是否存在具有相同名称的头文件。例如,如果存在以下所有四个文件:

one/foo.h
one/bar.h
two/foo.h
two/bar.h

并且您想要编译包含

的代码
#include "foo.h" /* must refer to one/foo.h */
#include "bar.h" /* must refer to two/bar.h */

然后你不能只使用-I指令。您先放-I one#include "bar.h"one/bar.h,或先放-I two#include "foo.h"two/foo.h。理智的解决方案是不要遇到这个问题。同一项目中的标题应具有唯一的名称。如果您要包含来自不同项目的标题,那么您应该在include指令中包含项目名称。

#include "one/foo.h"
#include "two/bar.h"

原则上,您可以将其中一个头文件复制到一个单独的目录中并包含该目录,但在这种情况下,根据典型的命名约定,您可能会遇到项目之间的名称冲突。

另请注意,string.h不是标题的好名称,因为它是标准库标题的名称。在您的情况下,编译器不会混淆两者:#include "string.h"查找当前目录中的头文件(如果有),而#include <string.h>仅查找使用-I指定的目录并且回到标准库。系统范围内安装的标头可能会发生冲突,只要您没有输入错误的文件名,它就会起作用,但人们会混淆使用大多数项目中使用的众所周知的标题名称。

相关问题