【问题标题】:Include a single header from a different directory包含来自不同目录的单个标头
【发布时间】:2017-12-21 22:53:51
【问题描述】:

我有一个小型构建,我只想包含来自不同目录的单个头文件(和源文件)。我知道如何使用 -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"

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

【问题讨论】:

  • 在“make”文件的早期生成源文件列表,可能通过 ``SRC := $( wildcard *.c )` 和目标文件列表,可能通过OBJ := $(SRC:.c=.o)
  • 更改默认头文件搜索路径(环境中的一个条目)以包含所需文件的目录路径。另请注意,您的“make”文件会更好,因为它包含为每个源文件生成“依赖”文件的必要语句然后生成string.o的配方(最好不要在中途更改根名称)看起来类似于: %.o : %.c %d 紧跟在下一行类似于: c99 -ggdb -c $ifneq "$(MAKECMDGOALS)" "clean" -include $(DEP) endif
  • 在“make”文件的开头包含类似于:CCFLAGS := -Wall -Wextra -Wconversion -pedantic -std=gnu99 的语句
  • 注意:$(DEP) 宏的生成类似于:DEP := $(SRC:.c=.d)

标签: c gcc makefile


【解决方案1】:

我知道如何使用 -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 "one/foo.h"
#include "two/bar.h"

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

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

【讨论】:

    猜你喜欢
    • 2020-03-21
    • 1970-01-01
    • 2020-12-15
    • 2011-11-26
    • 2012-01-27
    • 2018-06-18
    • 1970-01-01
    • 2014-01-05
    • 1970-01-01
    相关资源
    最近更新 更多