2011-05-22 19 views
10

veo que gcc tiene una opción -include archivo que se comporta (más o menos) como la primera línea del archivo era¿Por qué gcc tiene una opción -incluir?

#include "file" 

¿Cuáles son algunos buenos usos para esta opción?

+0

GCC tiene un montón de opciones de bichos raros. Tal es la maravilla del software de código abierto. –

+1

Seguí adelante y reformulé la pregunta. Afortunadamente, ya no golpeará a la gente como "subjetiva y argumentativa". Esa no era mi intención. – andrewdski

+1

Creo que es una pregunta razonable. Pero incluso usar la palabra "bueno" aquí puede ocasionarte problemas en estos días. –

Respuesta

1

Es útil para cosas como los archivos de encabezado de prefijo que van a #incluidos en todos los archivos de un proyecto, algo así como el temido StdAfx.h en Windows o los archivos .prefix.h en Mac OS.

6

Un uso real de la opción -include se encuentra en el sistema de compilación del kernel de Linux.

Al compilar el kernel de Linux, puede ejecutar un gran menú de opciones de configuración para personalizar el kernel generado. Por ejemplo, aquí está la opción de configuración para si desea apoyar núcleo de más de una CPU en la arquitectura x86, para el núcleo Linux 3.0:

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

Dentro del código fuente, esta opción aparece como un símbolo de preprocesador, CONFIG_SMP. El código fuente dentro del kernel y los controladores puede hacer un #ifdef CONFIG_SMP cuando se necesita un código diferente para más de un procesador. (También se puede usar dentro de un Makefile, con una sintaxis diferente, para elegir si compilar o no un archivo o subdirectorio .c).

¿Cómo se definen estos símbolos de preprocesador? No están definidos en la línea de comandos del compilador, ya que sería ridículamente largo (hay literalmente miles de estos símbolos en un núcleo de distribución típico, cuento más de 4000 para el kernel que se ejecuta en esta máquina). En su lugar, se genera automáticamente un archivo de encabezado mágico con todas estas opciones. Este archivo de encabezado se incluye automáticamente en todos los archivos compilados, a través de una opción -include include/generated/autoconf.h.

Dado que los símbolos del preprocesador CONFIG_ deben estar disponibles en todos los archivos de código fuente del kernel, usar -include (que implícitamente lo incluye antes de la primera línea del archivo) es una buena idea. Sin ella, se tendría que hacer una de las siguientes:

  • incluyen explícitamente como el primer archivo de inclusión en cada uno de los miles de archivos de código fuente del kernel, y espero que nadie se olvida incluirlo o añade algo antes el incluir.
  • Incluyéndolo explícitamente en un encabezado de uso común (como kernel.h), y espero que nada que dependa de un símbolo CONFIG_ aparezca antes de la primera inclusión directa o indirecta de ese encabezado.

Cualquiera de estas opciones es claramente inferior a -include.

Hay otro uso de -include en el kernel de Linux, pero es más esotérico. Partes del kernel (en particular, las primeras partes del código de arranque) deben ejecutarse en modo real. En lugar de escribirse completamente en ensamblaje, como en el pasado, estas partes del kernel usan un hack donde el ensamblador recibe instrucciones de emitir código de 32 bits en modo real (.code16gcc). Esto debe hacerse como la primera cosa en el código fuente, antes que cualquier otra cosa, lo que lo hace una gran coincidencia con -include (el encabezado incluido esta vez tiene solo una declaración asm(".code16gcc");).

1

Se puede utilizar en tiempo de compilación de forma similar a la precarga de la biblioteca en tiempo de ejecución: para anular temporalmente ciertas cosas en un archivo de origen. Por ejemplo, puede usarlo para incluir un encabezado que anule el control de versiones predeterminado del símbolo glibc si desea admitir una versión anterior de glibc que la de su sistema.

0

Mis dos centavos al respecto: He utilizado la directiva -include con encabezados "tiempo de compilación" generados automáticamente. De esta forma su código puede funcionar en los valores predeterminados y no mancha su código con archivos que pueden existir o no (por ejemplo, el cálculo de dependencias se quejará), pero puede modificar el comportamiento del código según la configuración externa.

Cuestiones relacionadas