Usar cabeceras precompiladas |
 |
Los compiladores de C y C++ actualmente pasan la mayoría
de su tiempo compilando una y otra vez cabeceras mucho más
grandes que el código fuente del fichero .c o .cpp en
sí.
El compilador gcc de
GNU a partir de la versión 3.3 incluye la posibilidad
de usar cabeceras precompiladas, lo cual
acelera mucho la compilación de programas C y C++.
En este truco se explica cómo aprovechar esta nueva
característica
Durante la explicación de este truco vamos a suponer
que nuestros ficheros fuente incluyen en su mayoría
el fichero
<iostream> con
las operaciones
típicas de
entrada/salida C++, y el fichero <math.h> con
las operaciones matemáticas más normales.
En consecuencia hemos decidido crear un fichero precompilado
con estos ficheros de cabecera con el fin de acelerar la
compilación de nuestro proyecto.
El fichero de cabecera en general deberá incluir sólo
ficheros de cabecera que cambien poco, preferiblemente sólo
los que vienen con el compilador (los que se invluyen de la
forma #include <...>),
y no los ficheros de cabecera de nuestro programa (que se
incluyen de la forma #include "..."),
ya que si no tendría que recompilarse el fichero de
caberera cada vez que modificáramos uno de nuestros
ficheros .h
Los ficheros de cabecera precompilados tienen el mismo nombre
que el fichero
.h correspondiente, pero
con el sufijo .gch Por
ejemplo si creamos el fichero precompiled.h con
las cabeceras comunes que incluye nuestro proyecto el fichero
de cabecera
precompilado se llamará precompiled.h.gch
El fichero que nosotros hemos creado como ejemplo es el
siguiente:
$ cat precompiled.h
#include <iostream>
#include <math.h>
using namespace std;
Lo siguiente que tenemos que hacer es precompilar este fichero
para lo cual ejecutamos:
$ g++ -c precompiled.h -o precompiled.h.gch
Lo cual nos crea el fichero precompiled.h.gch con todos
los ficheros incluidos por precompiled.h precompilados.
Ahora si, por ejemplo, el fichero encuadre.cpp incluye
el fichero precompiled.h cuando
ejecutemos:
$ g++ -c encuadre.cpp -o encuadre.o
El compilador de GNU buscará primero en el directorio
actual un fichero llamado precompiled.h.gch,
si lo encuentra lo usará, y sólo si no lo encuentra
incluirá precompiled.h
Aquí conviene hacer varias apreciaciones: La primera
es que para que el compilador de GNU use el fichero .gch que
encuentre, éste deberá estar compilando exactamente
con las mismas opciones con las que hemos lanzado la compilación
de encuadre.cpp, es decir basta con que hubiéramos
usado:
$ g++ -O1 -c encuadre.cpp
-o encuadre.o
Para que no nos acepte el fichero precompilado
y use el sin precompilar.
La segunda es que el compilador de GNU requiere un fichero
precompilado para cada dialecto de C (C, C++, Objective-C),
si quisiésemos que un fichero precompilado se usase
por distintos dialectos de C necesitaríamos crear
uno distinto para cada
dialecto (usando la opción -x
c-header, -x c++-header y -x
objective-c-header). En este caso la forma de proceder
es crear un directorio con el nombre precompiled.h.gch y
dentro de el meter todos los ficheros precompilados para
todos los
dialectos que estemos usando (da lo mismo el nombre que demos
a estos ficheros, gcc examina
todos los ficheros del directorio en busca del que necesite).
La tercera apreciación es que si vamos a usar ficheros
precompilados en un fichero Makefile conviene
crear una regla que actualice los ficheros de cabecera como
la siguiente:
encuadre.o: encuadre.cpp encuadre.h Matriz.h Punto.h precompiled.h.gch
precompiled.h.gch: precompiled.h
$(CXX) $^ $(CXXFLAGS) -o $@
Desgraciadamente actualmente make no
soporta el uso de reglas
implícitas para los ficheros
precompilados.

Por último conviene comentar que Xcode también
soporta el designar a un fichero como fichero que actúe
como cabecera
precompilada, para ello debemos de activar dos opciones del
proyecto o del target que son:
- Prefix Header (GCC_PRIFIX_HEADER)
Que indica que fichero de cabecera es el que debe precompilarse
(en principio
sólo soporta uno por proyecto que de hecho es lo
normal). Por ejemplo aquí pondríamos precompiled.h.
Esta opción no aparece por defecto en las opciones
de Xcode con lo que debemos de usar el botón
de añadir
nueva opción y añadir la opción con
clave GCC_PREFIX_HEADER y
con valor precompiled.h
- Precompile Prefix Header (GCC_PRECOMPILE_PREFIX_HEADER)
Debemos de activar esta opción para que funcionen
las cabeceras precompiladas dentro del proyecto
o del target.
|