开发者

Why does gcc have a -include option?

开发者 https://www.devze.com 2023-03-07 11:11 出处:网络
I see that gcc has a -include file option that behaves (sort of) like the first line of the file was

I see that gcc has a -include file option that behaves (sort of) like the first line of the file was

#开发者_StackOverflowinclude "file"

What are some good uses for this option?


One real-life use of the -include option is in the Linux kernel build system.

When building the Linux kernel, you can run through a huge menu of configuration options to customize the built kernel. For instance, here is the configuration option for whether you want to support more than one CPU core on the x86 architecture, for the Linux 3.0 kernel:

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.
          [...]

Within the source code, this option appears as a preprocessor symbol, CONFIG_SMP. Source code within the kernel and drivers can do a #ifdef CONFIG_SMP when different code is needed for more than one processor. (It can also be used within a Makefile, with a different syntax, to chose whether or not to compile a .c file or subdirectory.)

How are these preprocessor symbols defined? They are not defined on the compiler command line, since it would then be ridiculously long (there are literally thousands of these symbols on a typical distribution kernel; I count over 4000 of them for the kernel running on this machine). Instead, a magic header file is automatically generated with all these options. This header file is then automatically included on all the compiled files, via an -include include/generated/autoconf.h option.

Since the CONFIG_ preprocessor symbols should be available everywhere on all the kernel source code files, using -include (which implicitly includes it before the first line of the file) is a good thing. Without it, you would have to do one of the following:

  • Explicitly include it as the first include file on every one of the thousands of kernel source code files, and hope nobody forgets to include it or adds something before the include.
  • Explicitly include it on a commonly used header (like kernel.h), and hope nothing which depends on a CONFIG_ symbol appears before the first direct or indirect inclusion of that header.

Either of these options is clearly inferior to -include.

There is another use of -include on the Linux kernel, but it is more esoteric. Parts of the kernel (in particular the early parts of the boot code) have to run in real mode. Instead of being written completely in assembly, as they were in the past, these parts of the kernel use a hack where the assembler is instructed to emit 32-bit real-mode code (.code16gcc). This must be done as the very first thing in the source code, before anything else, which makes it a great match to -include (the header included this time has only an asm(".code16gcc"); statement).


It's useful for things like prefix header files which are going to be #included in all files in a project - somewhat like the dreaded StdAfx.h in Windows or the .prefix.h files on Mac OS.


It can be used at compile time in a way similar to library pre-loading at run time: to temporarily override certain things in a source file. For example you can use it to include a header overriding the default glibc symbol versioning if you want to support an older version of glibc than the one on your system.


My two cents about this: I have happened to use the -include directive with "compile time" automatically generated headers. That way your code can work on defaults and you don't taint your code with files that may or may not exist (dependencies calculation will complain for example) but you can modify your code behavior based on external configuration.

0

精彩评论

暂无评论...
验证码 换一张
取 消