"system headers" 对 GCC -MM 标志的确切含义
Exact meaning of "system headers" for the GCC -MM flag
根据 GCC 文档,-MM 标志将以这种方式生成依赖项:
Like -M but do not mention header files that are found in system
header directories, nor header files that are included, directly or
indirectly, from such a header.
我刚刚发现在我的项目中使用 -MM 标志不仅抑制了对系统头文件的依赖性,还抑制了对我本地安装在主目录中的第三方库头文件的依赖性。摆脱系统头文件的依赖对我来说通常很方便(因为我不编辑它们),但是我有时 edit/customize 第三方库,当然我需要在这样的编辑后重建我的代码。
那么,我的问题是 GCC 的 "system header" 是什么?假设您在您的主目录中安装了一个自定义版本的 libpng,并根据您的需要对其进行编辑...这是 GCC 的 "system header" 吗?
我只是暂时改用 -M 作为临时解决方法。
系统header目录
在 GCC 中,系统 headers 目录就是这样;系统 header 目录。确定什么是系统目录和什么不是系统目录 header 并没有什么魔力。 GCC 将您指定为系统 header 目录的目录视为系统 header 目录。
如果你在你的主目录中安装一个third-party库的headers,就像你的例子一样,然后继续用GCC编译一个需要这个库的项目,你的编译将由于缺少所述库而失败,或者它将使用系统安装的库版本。这是因为你没有指定你告诉 GCC 包含这个本地安装,GCC 不会神奇地为你做这件事。当您在搜索 header 时指定要包含的目录时,您还告诉 GCC 是否将这些目录视为系统 header 目录。
哪些目录成为系统 header 目录?
使用命令行选项 -iwithprefix
、-isystem
和 -idirafter
添加的目录被视为系统 header 目录。所有这三个选项的文档都很清楚,它们得到与实际系统相同的特殊处理 headers。此外,环境变量 C_INCLUDE_PATH
、CPLUS_INCLUDE_PATH
和 OBJC_INCLUDE_PATH
中的路径被视为使用 -isystem
选项传递,因此也被视为系统 headers.
很明显,实际的系统header,比如编译器自带的或者安装到系统中的,也被视为系统header。
哪些目录没有?
添加了 -iquote
、-iwithprefixbefore
和 -I
的目录不被视为系统 header 目录。这也包括来自 CPATH
环境变量的目录,它被视为通过 -I
选项传递。
执行此操作的源代码在哪里?
由于我花了一些时间在 GCC 源代码中搜索它是如何定义的,所以我会为任何感兴趣的人留下这个注释:什么是系统和什么不是系统的精确定义 header可以在gcc/incfile.c
中的add_path
函数中看到。这里,sysp
是non-zero意味着系统header。在同一个文件中,您还可以找到 register_include_chains
,它处理从特殊环境变量添加到目录中。最后,对于选项解析,从 gcc/c-family/c-opts.c
调用 add_path
以从各种选项添加目录。
根据 GCC 文档,-MM 标志将以这种方式生成依赖项:
Like -M but do not mention header files that are found in system header directories, nor header files that are included, directly or indirectly, from such a header.
我刚刚发现在我的项目中使用 -MM 标志不仅抑制了对系统头文件的依赖性,还抑制了对我本地安装在主目录中的第三方库头文件的依赖性。摆脱系统头文件的依赖对我来说通常很方便(因为我不编辑它们),但是我有时 edit/customize 第三方库,当然我需要在这样的编辑后重建我的代码。
那么,我的问题是 GCC 的 "system header" 是什么?假设您在您的主目录中安装了一个自定义版本的 libpng,并根据您的需要对其进行编辑...这是 GCC 的 "system header" 吗?
我只是暂时改用 -M 作为临时解决方法。
系统header目录
在 GCC 中,系统 headers 目录就是这样;系统 header 目录。确定什么是系统目录和什么不是系统目录 header 并没有什么魔力。 GCC 将您指定为系统 header 目录的目录视为系统 header 目录。
如果你在你的主目录中安装一个third-party库的headers,就像你的例子一样,然后继续用GCC编译一个需要这个库的项目,你的编译将由于缺少所述库而失败,或者它将使用系统安装的库版本。这是因为你没有指定你告诉 GCC 包含这个本地安装,GCC 不会神奇地为你做这件事。当您在搜索 header 时指定要包含的目录时,您还告诉 GCC 是否将这些目录视为系统 header 目录。
哪些目录成为系统 header 目录?
使用命令行选项 -iwithprefix
、-isystem
和 -idirafter
添加的目录被视为系统 header 目录。所有这三个选项的文档都很清楚,它们得到与实际系统相同的特殊处理 headers。此外,环境变量 C_INCLUDE_PATH
、CPLUS_INCLUDE_PATH
和 OBJC_INCLUDE_PATH
中的路径被视为使用 -isystem
选项传递,因此也被视为系统 headers.
很明显,实际的系统header,比如编译器自带的或者安装到系统中的,也被视为系统header。
哪些目录没有?
添加了 -iquote
、-iwithprefixbefore
和 -I
的目录不被视为系统 header 目录。这也包括来自 CPATH
环境变量的目录,它被视为通过 -I
选项传递。
执行此操作的源代码在哪里?
由于我花了一些时间在 GCC 源代码中搜索它是如何定义的,所以我会为任何感兴趣的人留下这个注释:什么是系统和什么不是系统的精确定义 header可以在gcc/incfile.c
中的add_path
函数中看到。这里,sysp
是non-zero意味着系统header。在同一个文件中,您还可以找到 register_include_chains
,它处理从特殊环境变量添加到目录中。最后,对于选项解析,从 gcc/c-family/c-opts.c
调用 add_path
以从各种选项添加目录。