c++builder - full - ¿Cuál es la mejor práctica para usar encabezados precompilados en una aplicación moderna de C++ Builder?
descargar embarcadero c++ builder 2010 full (2)
Actualmente estoy migrando un gran proyecto de RAD Studio 2010 a XE4. Como parte de esto, estoy recreando muchos de los archivos del proyecto. Me gustaría aprovechar la oportunidad para asegurarnos de que estamos utilizando el mejor mecanismo posible para los encabezados precompilados, ya que parece que hay algunas maneras de hacerlo.
En este momento estamos compilando solo para 32 bits, pero usaremos el compilador de 64 bits en el futuro.
Esto es lo que estamos haciendo actualmente en 2010, y por qué no estoy seguro de qué hacer en XE4:
En RAD Studio 2010
Tenemos un archivo PchApp.h
que incluye <vcl.h>
y una serie de otros archivos de encabezado de uso común, en su mayoría encabezados para varias clases de núcleo de uso común en el proyecto. Este encabezado se incluye en la parte superior de cada archivo CPP seguido de #pragma hdrstop
, así:
// Top of .cpp file
#include "PchApp.h"
#pragma hdrstop
// Normal includes here
#include "other.h"
#include "other2.h"
// etc
Luego tenemos las siguientes configuraciones en la sección Encabezados precompilados de las opciones del proyecto:
No es particularmente rápido de compilar (12 minutos para aproximadamente 350,000 líneas de código). No estoy seguro de:
- "Inyectar el archivo de encabezado precompilado": ¿debería esto inyectar PchApp.h?
- "Encabezados precompilados de la memoria caché (deben usarse con -H o -H" xxx ")": la opción -H es el "nombre de archivo PCH", así que lo estamos utilizando, pero seguramente el punto de un encabezado precompilado es que lo es " almacenado en caché "o creado previamente una vez por compilación. ¿Qué diferencia extra hace esto?
- ¿Deberíamos tener las dos líneas para incluir PchApp.h y pragma hdrstop en los archivos .cpp? ¿Hay una manera de hacer esto solo en las opciones del proyecto, y no duplicar estas dos líneas en cada archivo? ¿Son necesarios?
En otras palabras, no estoy seguro de que estos sean ajustes correctos u óptimos, pero al leer la documentación tampoco estoy seguro de qué sería mejor. Soy consciente de que no entiendo todas las opciones lo suficientemente bien, una de las razones de esta pregunta :)
En RAD Studio XE4
El diálogo de opciones del compilador de 32 bits de XE4 es el mismo, pero dos cosas me confunden y / o me hacen dudar de que el enfoque actual de 2010 sea el mejor.
1. comportamiento por defecto
Al crear un nuevo proyecto de formularios VCL, el IDE crea un encabezado denominado por defecto Project1PCH1.h, que pretende ser el encabezado precompilado del proyecto. Este encabezado incluye <vcl.h>
y <tchar.h>
, y se muestra como un nodo en el Administrador de proyectos. No está incluido en el Form1.cpp predeterminado, pero #include <vcl.h>
seguido de #pragma hdrstop
está en la parte superior de Form1.cpp, seguido de otros encabezados.
El cuadro de diálogo de configuración predeterminado de XE4 para un nuevo proyecto que usa este encabezado es:
Estoy (ingenuamente?) Trabajando en el supuesto de que los valores predeterminados son realmente la mejor / la configuración más óptima. Algunas cosas me desconciertan:
- El supuesto encabezado precompilado del proyecto
Project1PCH1.h
no se menciona en la configuración del encabezado precompilado en ninguna parte. - Los encabezados no están en caché
- El nombre de archivo PCH no está especificado (¿debería ser
Project1PCH1.h
?) - Los archivos .cpp tampoco incluyen
Project1PCH1.h
De hecho, no tengo ni idea de cómo el compilador o el IDE realmente saben que se supone que debe usar Project1PCH1.h
o para qué archivos .cpp se supone que deben usarlo, ya que no se menciona de ninguna manera que pueda encontrar.
Esta es la cosa más desconcertante para mí, y el estímulo para hacer esta pregunta y aclarar toda mi confusión sobre PCHes. Había planeado copiar / usar la configuración predeterminada del IDE, pero no quiero hacerlo hasta que entienda lo que están haciendo.
2. Asistente de PCH
Desde 2010, el IDE ha incluido un asistente de encabezado precompilado. Nunca he podido hacerlo funcionar. Lo estoy ejecutando de nuevo ahora mismo para obtener sus resultados y explicar que mi memoria de "no funciona", pero parece que toma varias horas, así que actualizaré esta pregunta luego.
Edición: se ejecuta, aunque toma varias horas y produjo una lista de (para mí, conociendo la base de origen) encabezados impares. Mi recuerdo de intentarlo hace varios años es que no se ejecutó en absoluto, una mejora definitiva.
Dado que existe, puede ser la mejor manera de configurar el uso de encabezados precompilados en un archivo de proyecto creado recientemente para actualizar el proyecto de 2010. ¿Cómo puedo hacerlo mejor? ¿Todos los archivos .cpp incluyendo PchApp.h lo confundirán?
Preguntas
Con eso como fondo, tengo las siguientes preguntas:
- Configuraciones existentes. Estoy creando un nuevo archivo de proyecto y agregando miles de archivos .cpp preexistentes, todos con "#include PchApp.h; #pragma hdrstop" en la parte superior. ¿Debo copiar los ajustes PCH RS2010 existentes? ¿Debo eliminar las dos líneas anteriores y reemplazarlas por otra cosa?
- Uso del asistente de PCH: ¿Crea esto, según su experiencia, una configuración óptima? ¿Incluye archivos que, si se modifican, harán que se reconstruyan grandes áreas del proyecto (probablemente no sea óptimo para la codificación)? ¿Es posible usarlo en un proyecto existente o es necesario eliminar elementos como nuestro "#include PchApp.h" antes de usarlo?
- Archivos / unidades de CPP y el correcto incluye. ¿Los archivos .cpp que usan encabezados precompilados no incluyen el encabezado precompilado, sino solo los encabezados que realmente necesita el .cpp, incluso si el PCH los incluye? ¿Qué sucede si tiene nuestra situación actual, donde el archivo PchApp.h incluye varios encabezados comunes y, por lo tanto, los archivos .cpp no incluyen esos mismos? Si elimina la inclusión de PchApp.h y la reemplaza con el subconjunto de encabezados en PchApp.h que necesitan los archivos .cpp específicos, ¿deberían estar por encima o por debajo del #pragma hdrstop? (Arriba, creo). ¿Qué pasa si luego incluye algo más arriba con ellos que no está incluido en el encabezado precompilado? ¿Cambiará el uso de PCH para esa unidad específica, hará que se reconstruya el PCH (problemas de rendimiento), etc.?
- Configuración predeterminada: Suponiendo que la configuración predeterminada para un nuevo proyecto sea óptima, ¿cuál es la mejor manera de migrar el sistema actual para usarlo?
- Configuración no predeterminada: si la configuración predeterminada no es óptima, ¿qué es? Esta, supongo, es la pregunta clave.
- 32 y 64 bits: Sabiendo que nos moveremos a 64 bits pronto, ¿qué deberíamos hacer para que los encabezados precompilados funcionen en 32 y 64 bits? ¿Debería todo el conocimiento de PCH estar en las opciones del proyecto en lugar de en los archivos .cpp, de modo que las diferentes configuraciones para la compilación de 32 y 64 bits?
Estoy buscando una respuesta clara, detallada, explicativa y de guía, que explique claramente la mejor práctica, las opciones de configuración, los elementos que se incluirán en los archivos .cpp, el encabezado y / o el archivo del proyecto, y demás, en otras palabras, algo Para aclarar mi por ahora (después de todo lo anterior!) Entendimiento bastante confuso. Una respuesta de alta calidad que pueda ser utilizada como referencia de PCH en el futuro por otros usuarios de C ++ Builder en el futuro sería excelente. Tengo la intención de agregar una recompensa en un par de días cuando pueda.
- Configuraciones existentes. En mi experiencia, por lo general he cambiado esta configuración, porque si tiene cientos de archivos, simplemente no parece ser el óptimo. En xCode es decir, es la configuración por defecto. No debe haber diferencia de rendimiento de compilación.
- Usando el asistente de PCH Honestamente, nunca lo he usado en un proyecto real, y no me ha impresionado, así que me olvidé de eso y usé la configuración manual.
- Archivos / unidades de CPP y el correcto incluye. Diferentes IDE tienen diferentes configuraciones predeterminadas para eso. Lo que usualmente uso es:
- Inyectar encabezados precompilados automáticamente (no se incluye el # manual en .cpp)
- Primero incluya el encabezado apropiado que coincida con .cpp si existe uno (myfile.cpp - luego incluya myfile.h)
- Después de eso, incluya todos los encabezados específicos que hacen un trabajo específico (encabezados específicos de biblioteca, etc.)
- En "myfile.h" incluye SOLO cosas que son obligatorias. Evita cualquier cosa que puedas evitar.
- Todo lo que incluya específicamente para un archivo .cpp en particular debe estar debajo de #pragma hdrstop. Todo lo que quieras ser precompilado debe estar arriba.
- Configuración predeterminada No creo que sea óptima. En lo que a mí respecta, es mucho más fácil migrar simplemente cambiando un par de opciones en la configuración.
- Configuración no predeterminada Como he mencionado anteriormente, en cuanto a mí, la configuración óptima es con la inyección automática del encabezado precompilado. Más detalles en el punto 3.
- 32 y 64 bits no han experimentado ningún problema con eso. Debe generar encabezados precompilados para cada configuración particular.
Esto es lo que hago (aunque no estoy seguro de si es una buena idea o no, pero parece funcionar)
- Asegúrese de que Project1PCH1.h existe (donde Project1 es el nombre del proyecto)
- Haz que contenga
#pragma hdrstop
y 2 nuevas líneas finales (recibí errores extraños cuando no tenía nuevas líneas finales, quizás un error del compilador) - En "Todas las configuraciones", coloque en "Inyectar el archivo de encabezado precompilado", luego nombre "Project1PCH1.h"
- No haga nada como
#include "PchApp.h"
ni#pragma hdrstop
en los otros archivos. - Verifique que todas las compilaciones se realicen correctamente (es decir, los archivos tienen el derecho de inclusión en su propio mérito, sin depender del PCH inyectado)
- Ponga algunos incluye en el Project1PCH1.h. Utilizo el asistente para hacer algunas sugerencias, pero también debes aplicar un poco de lógica humana para obtener una buena construcción.
Cuando funciona correctamente en modo de 32 bits, todo se compila a la velocidad de la luz; puedes saber si no has acertado correctamente si estás compilando tu proyecto y un archivo .cpp en particular toma mucho más tiempo que el resto. El asistente hace sugerencias basadas en cuántos archivos incluyen el encabezado dado, pero eso es algo falso; debe incluir en él cualquier encabezado de sistema (o encabezado de refuerzo, etc.) que se agregaría significativamente al tiempo de compilación si no fuera parte del PCH.
No me molesto en incluir mis propios encabezados de proyecto, solo encabezados de sistema y estándar. Eso puede diferir para usted dependiendo de su proyecto, IDK.
El PCH no funciona para archivos .c
, por lo que si tiene alguno de esos archivos, deberá hacer que Project1PCH1.h tenga guardas #ifdef __cplusplus
.
Además: a pesar de que bcc64 no es compatible con PCH (pero sí inyecta el archivo), si tiene su PCH configurado correctamente, parece que la compilación vaya un poco más rápido, no estoy seguro de por qué.
Cosas que todavía no entiendo sobre esto:
- ¿Por qué el Asistente para nuevo proyecto genera automáticamente Project1PCH1.h pero no lo establece en el campo "Inyectar encabezado precompilado" de las Propiedades del proyecto?
- A veces, la compilación falla diciendo que no puede abrir Project1PCH1.h pero si hago algunos cambios y los vuelvo a guardar, generalmente parece que esto se soluciona.