Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does gcc have a -include option?

Tags:

gcc

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

#include "file"

What are some good uses for this option?

like image 343
andrewdski Avatar asked May 22 '11 16:05

andrewdski


2 Answers

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).

like image 145
CesarB Avatar answered Oct 05 '22 22:10

CesarB


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.

like image 42
Paul R Avatar answered Oct 05 '22 22:10

Paul R