2010-12-19 16 views
8

Uso gcc (ejecutándose como g++) y GNU make. Uso gcc para precompilar un archivo de encabezado precompiled.h, creando precompiled.h.gch; la línea siguiente en un Makefile hace:Creando varios archivos de encabezado precompilados utilizando GNU make

# MYCCFLAGS is a list of command-line parameters, e.g. -g -O2 -DNDEBUG 
precompiled.h.gch: precompiled.h 
    g++ $(MYCCFLAGS) -c $< -o [email protected] 

Todo fue bien hasta que tuve que correr g++ con diferentes parámetros de línea de comandos. En este caso, aunque existe precompiled.h.gch, no se puede usar y la compilación será mucho más lenta. En la documentación gcc He leído que para manejar esta situación, tengo que hacer un directorio llamado precompiled.h.gch y poner los archivos de encabezado precompilados allí, un archivo para cada conjunto de g++ parámetros de línea de comandos.

Así que ahora me pregunto cómo debería cambiar mi Makefile para contar g++ para crear los GCH-archivos de esta manera. Tal vez pueda ejecutar g++ solo para probar si puede usar cualquier archivo existente en el directorio precompiled.h.gch, y, de no ser así, generar un nuevo encabezado precompilado con un nombre de archivo único.

¿Tiene gcc compatibilidad para realizar dicha prueba?

Tal vez pueda implementar lo que quiero de otra manera?

+0

'-Winvalid-pch' le dará una advertencia. Usado con '-Werror' detendrá la compilación si gcc ve un .gch inválido. – bobbogo

+0

@bobbogo ¡Gracias, esto es exactamente lo que necesito! Me ahorrará algunos problemas. – anatolyg

Respuesta

5

Parece extraño responder a mi propia pregunta; de todos modos, aquí va.

para detectar si existe un archivo de encabezado precompilado adecuado, agrego un error deliberado a mi archivo de cabecera:

// precompiled.h 
#include <iostream> 
#include <vector> 
... 
#error Precompiled header file not found 

Esto funciona porque si gcc encuentra un encabezado precompilado, no va a leer el archivo .h, y no encontrará el error.

Para "compilar" un archivo de este tipo, i eliminar el error primero, colocando el resultado en un archivo temporal:

grep -v '#error' precompiled.h > precompiled.h.h 
g++ -c -x c++ $(MYCCFLAGS) precompiled.h.h -o MORE_HACKERY 

Aquí MORE_HACKERY no es sólo un nombre de archivo sin formato, pero contiene algo de código para hacer una archivo con nombre único (mktemp). Fue omitido por claridad.

0

Hay una manera más simple que introducir un #error en precompilado.h: nunca cree este archivo en absoluto. Ni G ++ ni Visual C++ (al menos hasta 2005) esperan que el archivo "real" esté allí, si hay una versión precompilada (y si obtienen los indicadores de compilación necesarios).

Digamos que la lista de #includes que queremos precompilar se llama "to_be_precompiled.cpp". La extensión de nombre de archivo no importa mucho, pero no me gusta llamarlo .h, ya que debe usarse de una manera diferente a los archivos de encabezado genuinos, y es más fácil en Visual C++ si se trata de un archivo .cpp . A continuación, elija un nombre diferente para referirse a él a lo largo del código, digamos "precompiled_stuff". De nuevo, no me gusta llamar a esto un archivo .h, porque no es un archivo en absoluto, es un nombre para referirse a datos precompilados.

Luego, en todos los demás archivos fuente, la instrucción #include "precompiled_stuff" no es una inclusión genuina, sino que simplemente carga datos precompilados. Depende de usted preparar los datos precompilados.

  • Para g ++, necesita una regla de construcción para crear "precompiled_stuff.gch" de un archivo de origen cuyo nombre no tiene importancia para el compilador (pero sería "to_be_precompiled.cpp" aquí).
  • En Visual C++, la cadena "precompiled_stuff" es igual al valor de/Yu y los datos precompilados cargados provienen de un archivo .pch con un nombre no relacionado, que también creó a partir de un archivo fuente no relacionado (nuevamente "to_be_precompiled". cpp "aquí).
  • Solo cuando se compila con un compilador sin soporte de encabezado precompilado, una regla de compilación necesita generar un archivo real llamado "precompiled_stuff", preferiblemente en el directorio de compilación, lejos de los archivos fuente reales. "precompiled_stuff" es una copia de "to_be_precompiled.cpp", un enlace fijo o simbólico, o un pequeño archivo que contiene #include "to_be_precompiled.cpp".

En otras palabras, usted toma el punto de vista de que cada compilador admite la precompilación, pero es una copia tonta para algunos compiladores.

+0

Tenga en cuenta que en Visual Studio, al contrario que el compilador de C++, [Intellisense necesita que el archivo de encabezado precompilado exista (al menos en 2015)] (http://stackoverflow.com/questions/31943634/visual-studio-2015-intellisense -errors-but-solution-compiles) – Stein

Cuestiones relacionadas