gcc为什么有一个“-include”选项?

13

我看到gcc有一个 -include file 选项,它的行为类似于文件的第一行。

#include "file"

这个选项有哪些好的用途?


1
GCC 有一堆奇怪的选项。这就是开源软件的奇妙之处。 - user2100815
1
我已经重新措辞了这个问题。希望现在它不再被认为是“主观和争论性”的了。那不是我的本意。 - andrewdski
1
我认为这是一个合理的问题。但即使在今天,使用“好”的词语也可能会让你陷入麻烦。 - user2100815
1
@andrewdski 欢迎来到Stackoverflow,在这里所有问题都被视为主观性的、离题的或重复的。 - Krythic
4个回答

11

-include选项的一个实际用途是在Linux内核构建系统中。

在构建Linux内核时,您可以运行大量的配置选项菜单来自定义构建的内核。例如,以下是Linux 3.0内核中是否支持x86架构上的多个CPU核心的配置选项:

config SMP
        bool "Symmetric multi-processing support"
        ---help---
          This enables support for systems with more than one CPU. If you have
          a system with only one CPU, like most personal computers, say N. If
          you have a system with more than one CPU, say Y.
          [...]

在源代码中,这个选项被表示为预处理器符号CONFIG_SMP。当需要不同的代码来适应多处理器时,内核和驱动程序中的源代码可以使用#ifdef CONFIG_SMP。(还可以在Makefile中使用不同的语法,选择是否编译.c文件或子目录。)

这些预处理器符号如何定义?它们不是在编译器命令行上定义的,因为那样将变得非常冗长(在典型的发行版内核中有数千个这些符号;我在这台机器上运行的内核中计算出超过4000个)。相反,会自动生成一个神奇的头文件,其中包含了所有这些选项。然后,通过-include include/generated/autoconf.h选项,在所有编译的文件中自动包含此头文件。

由于CONFIG_预处理器符号应该在所有内核源代码文件的任何地方都可用,所以使用-include(在文件的第一行之前隐式地包含它)是一件好事情。否则,您将不得不执行以下任一操作:

  • 在每个数千个内核源代码文件中明确地包含它作为第一个包含文件,并希望没有人忘记包含它或在包含之前添加其他内容。
  • 在常用的头文件(如kernel.h)中明确包含它,并希望在第一个直接或间接包含该头文件之前不会出现任何依赖于CONFIG_符号的内容。

这两个选项都明显劣于-include

Linux内核中还有另一种使用-include的方法,但它更为深奥。内核的某些部分(特别是启动代码的早期部分)必须在实模式下运行。与过去完全用汇编语言编写的方式不同,内核的这些部分使用了一种技巧,在这种技巧中,汇编器被指示发出32位实模式代码(.code16gcc)。这必须在任何其他事物之前作为源代码的第一件事情完成,这使其非常适合使用-include(此时包含的头文件仅具有一个asm(".code16gcc");语句)。


2

这对于像是前缀头文件的东西非常有用,这些文件将在项目中的所有文件中被 #include - 有点像 Windows 中可怕的 StdAfx.h 或 Mac OS 上的 .prefix.h 文件。


1

它可以在编译时使用,类似于运行时的库预加载:临时覆盖源文件中的某些内容。例如,您可以使用它来包含一个头文件,覆盖默认的 glibc 符号版本,如果您想支持比系统上的版本旧的 glibc 版本。


0
我的观点是: 我曾经使用过“包括指示符”和“编译时”自动生成的头文件。 这样,您的代码可以在默认情况下工作,并且不会将可能存在或不存在(例如依赖关系计算会发出警告)的文件污染您的代码,但您可以根据外部配置修改代码行为。

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