我看到gcc有一个-include file 选项,其行为(类似)就像文件的第一行一样
#include "file"
此选项有哪些好的用途?
答案 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
(在文件的第一行之前隐式包含它)是一件好事。没有它,您将不得不执行以下操作之一:
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指令和"编译时间"自动生成标题。 这样,您的代码可以在默认情况下工作,并且您不会使用可能存在或可能不存在的文件来污染代码(例如,依赖关系计算会抱怨),但您可以根据外部配置修改代码行为。