我有一个小型构建,其中我只想包含来自不同目录的单个头文件(和源文件)。我知道如何使用 -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
Run Code Online (Sandbox Code Playgroud)
当我尝试让它抱怨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"
Run Code Online (Sandbox Code Playgroud)
如何包含此文件而不包含整个目录?
\n\n\n我知道如何使用 -I 参数,但不想包含整个目录,只包含单个文件。
\n
-I\xe2\x80\x9c 不包含目录 \xe2\x80\x9d,它只是将该目录放在搜索路径上。该目录包含您不想要的其他文件也没关系。编译器将读取的唯一文件是名称位于指令中的文件#include。所以如果你有的话../../shared/src/string.h你可以使用以下编译命令:
c99 -ggdb -I ../../shared/src -c ui.c\nRun Code Online (Sandbox Code Playgroud)\n\n在 的情况下string.,标头与源文件位于同一目录中。-I这是编译器首先查看的地方,所以你根本不需要。
c99 -ggdb -c ../../shared/src/string.c -o ./jcstring.o\nRun Code Online (Sandbox Code Playgroud)\n\n添加选项可能会造成伤害的唯一情况-I是不同目录中存在同名的头文件。例如,如果以下所有四个文件都存在:
one/foo.h\none/bar.h\ntwo/foo.h\ntwo/bar.h\nRun Code Online (Sandbox Code Playgroud)\n\n并且您想要编译包含以下内容的代码
\n\n#include "foo.h" /* must refer to one/foo.h */\n#include "bar.h" /* must refer to two/bar.h */\nRun Code Online (Sandbox Code Playgroud)\n\n那么你不能只用-I指令来做到这一点。要么您放在第一位-I one并将#include "bar.h"包含one/bar.h,要么您放在第一位-I two并将#include "foo.h"包括two/foo.h。明智的解决方案是不要遇到这个问题。同一项目内的标头应具有唯一的名称。如果您要包含来自不同项目的标头,那么您应该在 include 指令中包含项目名称。
#include "one/foo.h"\n#include "two/bar.h"\nRun Code Online (Sandbox Code Playgroud)\n\n原则上,您可以将其中一个头文件复制到一个单独的目录并将其包含在内,但在这种情况下,考虑到典型的命名约定,您可能会遇到项目之间的名称冲突。
\n\n另请注意,这string.h对于标头来说不是一个好名称,因为它是标准库标头的名称。在您的情况下,编译器不会混淆两者:#include "string.h"如果存在,则在当前目录中查找头文件,而#include <string.h>仅在 指定的目录中查找-I并回退到标准库。与系统范围内安装的标头的冲突可能会发生,只要您没有错误输入文件名,它就可以工作,但是使用大多数项目中使用的非常知名的标头名称会让人们感到困惑。