-I dir和-isystem dir的区别

44
如果我想要包含用于搜索头文件的目录,哪种方法更好?为什么?

包括还是排除主机标准C库? - Tim Post
既不是一个,也不是另一个。只是在GCC手册中阅读有关预处理选项的内容时,偶然发现了这两个选项。 - helpermethod
1
使用 -isystem 而不是 -I 的一个重要用途是可以忽略 -isystem 中的警告。如果您想使用 -Wall -Werror 进行编译,但又不想在 -isystem 目录中出现错误,则这非常有用。 - Eyal
5个回答

42

一种处理方法是使用可控制的头文件-I,以及无法控制的(来自系统或第三方库)头文件-isystem。在启用警告时,实际区别在于来自-isystem头文件的警告信息将被屏蔽。


13

来自gcc的-I选项文档:

将目录dir添加到要搜索头文件的目录列表的头部。可以用它来覆盖系统头文件,替换成您自己的版本,因为这些目录在系统头文件目录之前搜索。但是,不应将此选项用于添加包含供应商提供的系统头文件的目录(使用 -isystem)。如果使用多个 -I 选项,则按从左到右的顺序扫描这些目录;标准系统目录在后面。

如果使用 -I 指定了标准系统包含目录或使用 -isystem 指定的目录,则将忽略 -I 选项。目录仍将被搜索,但作为系统目录位于系统包含链中的正常位置。这是为了确保GCC修复有错误的系统头文件和包含下一个指令的顺序的过程不会被意外更改。如果确实需要更改系统目录的搜索顺序,请使用 -nostdinc 和/或 -isystem 选项。

因此,除了特殊情况(如供应商提供的系统头文件)外,-I 可能是指定头文件位置的首选选项。


2

您应该使用-I来指定头文件的位置。

使用-isystem指定的文件将在处理完-I后进行搜索,并且会受到gcc(与标准系统头文件相同)的特殊处理。


2

我通过一些实验发现以下区别。想象一下以下设置:

my_std_lib/stdio.h

#ifndef _CUSTOM_STDIO_H

void test() {}

#endif

#include_next <stdio.h>
#include_next <custom.h>

my_user_lib/custom.h

#ifndef _CUSTOM_HEADER_H

void custom_func() {}

#endif

main.cpp

#include "stdio.h"

int main() {
  test();
  custom_func();
  printf("Hello world!");
  return 0;
}

如果您使用g++ -isystem my_std_lib -isystem my_user_lib main.cpp进行编译,一切都会正常工作。
然而,g++ -isystem my_std_lib -I my_user_lib main.cpp会导致错误。
In file included from main.cpp:1:
my_std_lib/stdio.h:10:15: fatal error: 'custom.h' file not found
#include_next <custom.h>
              ^~~~~~~~~~
1 error generated.

那么发生了什么呢?
据我理解,当我写 #include "stdio.h" 时,GCC会开始遍历可用的头文件列表,直到找到 my_std_lib/stdio.h。在该文件末尾的指令 #include_next 告诉编译器通过遍历从其当前位置开始的包含目录来查找 custom.h。
当我使用 -I 标志将 my_user_lib 添加到目录列表中时,它出现在所有系统目录之前。因此,它在目录列表中出现在 my_std_lib 目录之前,导致 #include_next 失败。
如果我使用 g++ -isystem my_user_lib -isystem my_std_lib main.cpp 进行编译,则会发生同样的情况。显然,目录按照指定标记的顺序添加到列表中,因此 my_user_lib 将出现在 my_std_lib 之前。
简而言之,-I 和 -isystem 在它们将目标添加到包含目录列表的方式上有所不同。

-1

当您使用-I包含头文件"Myheader.h"时,编译器生成搜索顺序:"Myheader.h","system/headers"。因此,如果在"MyHeader.h"中找不到某些内容,则会回退到"system/headers"。但是,当您使用-isystem时,基本上是在告诉编译器用我提供的内容替换"system/headers"。因此,就没有了回退到"system/headers"的情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接