为什么gcc有-include选项?

and*_*ski 11 gcc

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

#include "file"
Run Code Online (Sandbox Code Playgroud)

这个选项的一些好用途是什么?

Ces*_*arB 8

-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.
          [...]
Run Code Online (Sandbox Code Playgroud)

在源代码中,此选项显示为预处理器符号CONFIG_SMP.内核和驱动程序中的源代码可以#ifdef CONFIG_SMP在多个处理器需要不同代码时执行.(它也可以在a中使用Makefile,使用不同的语法来选择是否编译.c文件或子目录.)

这些预处理器符号是如何定义的?它们没有在编译器命令行中定义,因为它会非常长(在典型的分发内核上有数千个这样的符号;我为这台机器上运行的内核计算了4000多个符号).而是使用所有这些选项自动生成魔术头文件.然后,通过-include include/generated/autoconf.h选项将此头文件自动包含在所有已编译的文件中.

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

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

这些选择中的任何一个都明显不如-include.

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


Pau*_*l R 2

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