我有一个小构建,我想在其中只包含来自不同目录的单个头文件(和源文件)。我知道如何使用-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"
如何在不包含整个目录的情况下包含此文件?
答案 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
指定的目录并且回到标准库。系统范围内安装的标头可能会发生冲突,只要您没有输入错误的文件名,它就会起作用,但人们会混淆使用大多数项目中使用的众所周知的标题名称。