c++ - GCC y encabezados precompilados
dependencies precompiled-headers (1)
El GCC actual (es decir, 4.7) y versiones anteriores funcionan muy bien con los encabezados precompilados solo cuando tienes un único encabezado común para tu aplicación, y cuando ese solo encabezado (que incluye a su vez todos los del sistema, y los específicos de la biblioteca, requieren por la aplicación) es #include
-d (como el primer lexema sin comentarios de sus fuentes) por cada fuente de su aplicación.
Por lo tanto, debe tener un solo yourapp.h
y tener cada archivo fuente (es decir, cada unidad de compilación) de yourapp
comenzando con #include "yourapp.h"
con las mismas opciones de preprocesamiento (es decir, -D
o -I
o -U
) en el comando línea. Ese archivo de encabezado youapp.h
generalmente youapp.h
#include
-ing muchos otros, por ejemplo, encabezados de sistema (o GTK o Qt) como <stdlib.h>
o <sys/poll.h>
o [en C ++] <algorithm>
o <gtk/gtk.h>
o <QtGui>
etc.
Recuerde que -H
es una opción útil para que gcc
le gcc
qué está incluido.
Sus archivos de origen pueden tener #include
adicional después de #include "yourapp.h"
si así lo desea.
Después de que GCC haya incluido un encabezado precompilado [único], es posible, por supuesto, #define
macros, #include
un encabezado no precompilado, compilar condicionalmente con #ifdef
, etc. Pero ese preprocesamiento no será "precompilado". !
Esto puede no ajustarse a tus necesidades o hábitos.
Algunas personas (especialmente de Google, especialmente Diego Novillo) están trabajando en la sucursal PreParsed Header (pph) para mejorar la situación, pero el tronco actual de GCC aún no ha conseguido ese trabajo.
La explicación sobre ese comportamiento de GCC es que un encabezado preprocesado es esencialmente un punto de control serializado persistente de todo el montón de GCC (relacionado con la administración de memoria dentro de GCC a través de Ggc y GTY y gengtype
). Ese montón con punto de control solo se puede cargar cuando gcc
está en su estado vacío inicial. Tan pronto como se sepa algo de gcc
(en realidad cc1
o cc1plus
) ya no podrá cargar ningún archivo de encabezado precompilado *.h.gch
y volverá a analizar el archivo de encabezado textual *.h
.
adenda (noviembre de 2014)
Incluso GCC 4.9 quiere un único encabezado precompilado. El esfuerzo del encabezado pre-analizado por Diego Novillo et al. ha sido abandonado.
Las versiones futuras (posteriores a C ++ 14 ) del estándar C ++ podrían definir un mecanismo de módulo. Ver, por ejemplo, la propuesta n4047 .
(adiciones adicionales, diciembre de 2015) Esto todavía se aplica a GCC-5 y al futuro GCC-6.
Después de leer este bonito artículo (El cuidado y la alimentación de los encabezados precompilados), tengo algunas dudas con respecto a cómo pueden funcionar realmente en la vida real. Más específicamente, ¿cómo puedo saber que necesito activar la reconstrucción del encabezado precompilado en los siguientes escenarios:
- Decido # definir algo en uno de mis archivos .cpp que altera la forma en que el pre-procesador interpreta algunos encabezados que ya están incluidos en mi encabezado precompilado
- Incluyo otro encabezado en uno de mis archivos .cpp que
#define
una directiva de preprocesador específica que altera la forma en que el preprocesador interpreta un encabezado ya incluido en el encabezado precompilado - Peor aún, el problema anterior puede ocurrir recursivamente, cuando ciertos encabezados
#include
otros encabezados
¿Debería el uso de encabezados precompilados imponer un cierto estilo de codificación restrictivo como limitar el número de encabezados incluidos en los archivos .cpp a uno y nunca #define
definir cosas en un archivo .cpp?
Si bien el compilador de Microsoft probablemente hace un trabajo decente con encabezados precompilados (aplicando algo de vudú específico de MS) porque, hasta donde yo sé, proporciona las opciones /Yc
y /Yu
que se supone que deben hacer todas las cañerías, para GCC parece que esta funcionalidad requiere mucho trabajo manual y creatividad en el archivo Makefile y no pude encontrar una plantilla que supuestamente solucione todos los inconvenientes del uso de encabezados precompilados.
Por ejemplo, si tengo un proyecto que construye varias bibliotecas, para no reconstruir todas ellas después de cada cambio, tengo que usar algunos trucos de sed
realmente lindos en el Makefile para detectar si uno de los encabezados #include
d por el actual la biblioteca fue modificada (o es #include
un encabezado modificado). Me temo incluso pensar en las complicaciones que implicarían los encabezados preconstruidos para que el script de compilación los reconstruya cada vez que sea necesario.