为什么gcc有-include选项?

时间:2011-05-22 16:42:15

标签: gcc

我看到gcc有一个-include file 选项,其行为(类似)就像文件的第一行一样

#include "file"

此选项有哪些好的用途?

4 个答案:

答案 0 :(得分:7)

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

构建Linux内核时,您可以运行大量配置选项来自定义构建的内核。例如,以下是关于是否要在x86架构上为Linux 3.0内核支持多个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(在文件的第一行之前隐式包含它)是一件好事。没有它,您将不得不执行以下操作之一:

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

这两个选项中的任何一个都明显不如-include

Linux内核上还有-include的另一种用法,但它更为深奥。内核的一部分(特别是启动代码的早期部分)必须以实模式运行。内核的这些部分不是像过去那样完全在汇编中编写,而是使用hack,其中汇编程序被指示发出32位实模式代码(.code16gcc)。这必须作为源代码中的第一件事,在其他任何事情之前完成,这使得它与-include非常匹配(这次包含的标题只有asm(".code16gcc");语句。)

答案 1 :(得分:1)

对于像项目中所有文件中的#included一样的前缀头文件这样的东西很有用 - 有点像Windows中可怕的StdAfx.h或Mac OS上的.prefix.h文件。

答案 2 :(得分:1)

它可以在编译时以类似于运行时库预加载的方式使用:暂时覆盖源文件中的某些内容。例如,如果要支持比系统上的glibc更旧版本的glibc,可以使用它来覆盖覆盖默认glibc符号版本控制的标题。

答案 3 :(得分:0)

我的两分钱: 我碰巧使用-include指令和"编译时间"自动生成标题。 这样,您的代码可以在默认情况下工作,并且您不会使用可能存在或可能不存在的文件来污染代码(例如,依赖关系计算会抱怨),但您可以根据外部配置修改代码行为。