c++ - Manejo de stdafx.h en código multiplataforma
visual-studio gcc (9)
Como stdafx.h
es por defecto todo el material específico de Windows, he puesto un stdafx.h
vacío en mi otra plataforma. De esta manera, su código fuente se mantiene idéntico, al tiempo que desactiva eficazmente stdafx
en Linux sin tener que eliminar todas las líneas #include "stdafx.h"
de su código.
Tengo un programa basado en Visual Studio C ++ que utiliza encabezados precompilados ( stdafx.h
). Ahora estamos portando la aplicación a Linux usando gcc 4.x.
La pregunta es cómo manejar el encabezado precompilado en ambos entornos. He buscado en Google pero no puedo llegar a una conclusión.
Obviamente, quiero dejar stdafx.h
en Visual Studio, ya que la base de código es bastante grande y los encabezados precompilados aumentan el tiempo de compilación.
Pero la pregunta es qué hacer en Linux. Esto es lo que encontré:
- Deje el
stdafx.h
como está. gcc compila código considerablemente más rápido que VC ++ (o simplemente mi máquina Linux es más fuerte ... :)), así que tal vez me alegra esta opción. Utilice el método desde here : haga que
stdafx.h
vea como (configureUSE_PRECOMPILED_HEADER
para VS únicamente):#ifdef USE_PRECOMPILED_HEADER ... my stuff #endif
Utilice el método desde here : compile VC ++ con
/FI
para incluir implícitamentestdafx.h
en cada archivo cpp. Por lo tanto, en VS su código puede cambiarse fácilmente para compilarse sin encabezados precompilados y no será necesario cambiar el código.
Personalmente no me gustan las dependencias y el líostdafx.h
está impulsando una gran base de código hacia. Por lo tanto, la opción es atractiva para mí: en Linux no tienestdafx.h
, y aún puede activar encabezados precompilados en VS solo por/FI
.- En Linux compila
stdafx.h
solo como un encabezado precompilado (imita a Visual Studio)
¿Su opinión? ¿Hay otros enfoques para tratar el problema?
Es simple, realmente:
Proyecto-> Configuración del proyecto (Alt + F7)
Proyecto-Configuración-Diálogo:
C ++ -> Categoría: Encabezados precompilados -> Encabezados precompilados botones de radio -> deshabilitar
He hecho tanto la opción 2 (#ifdef) como la opción 4 (PCH para gcc) para el código multiplataforma sin problemas.
Creo que gcc se compila mucho más rápido que VS, por lo que los encabezados precompilados generalmente no son tan importantes, a menos que esté haciendo referencia a un gran archivo de encabezado.
Lo mejor es usar encabezados precompilados aún para la compilación más rápida.
También puedes usar encabezados precompilados en gcc. Mira aquí .
El encabezado precompilado compilado tendrá una extensión anexa como .gch
lugar de .pch
.
Por ejemplo, si precompila stdafx.h, tendrá un encabezado precompilado que se buscará automáticamente llamado stdafx.h.gch
cualquier momento que incluya stdafx.h
Ejemplo:
stdafx.h:
#include <string>
#include <stdio.h>
a.cpp:
#include "stdafx.h"
int main(int argc, char**argv)
{
std::string s = "Hi";
return 0;
}
Luego compila como:
> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out
Tu compilación funcionará incluso si eliminas stdafx.h después del paso 1.
Optaría por la opción 4 o la opción 2. He experimentado con encabezados precompilados en varias versiones VS y GCC en Linux (publicaciones de blog sobre esto here y here ). En mi experiencia, VS es mucho más sensible a la longitud de las rutas de inclusión, el número de directorios en la ruta de inclusión y el número de archivos de inclusión que G ++. Cuando medí los tiempos de compilación correctamente ordenados, los encabezados precompilados marcarían una gran diferencia en el tiempo de compilación bajo VS, mientras que G ++ no se impresionó mucho con esto.
En realidad, basado en lo anterior, lo que hice la última vez que trabajé en un proyecto donde esto era necesario para controlar el tiempo de compilación fue precompilar el equivalente de stdafx.h en Windows donde tenía sentido y simplemente lo usé como un archivo normal bajo Linux
Si está utilizando CMake en su proyecto, existen módulos que lo automatizan, muy conveniente, por ejemplo, consulte cmake-precompiled-header here . Para usarlo solo incluye el módulo y llama:
include( cmake-precompiled-header/PrecompiledHeader.cmake )
add_precompiled_header( ${target} ${header} FORCEINCLUDE SOURCE_CXX ${source} )
Otro módulo llamado Cotire crea el archivo de encabezado para ser precompilado (no es necesario escribir StdAfx.h manualmente) y acelera las construcciones de otras formas - ver here .
Solo usaría la opción 1 en un gran equipo de desarrolladores. Las opciones 2, 3 y 4 a menudo detendrán la productividad de otros miembros de su equipo, por lo que puede ahorrar unos minutos al día en tiempo de compilación.
Este es el por qué:
Supongamos que la mitad de tus desarrolladores usan VS y la mitad usan gcc. De vez en cuando, algunos desarrolladores VS se olvidan de incluir un encabezado en un archivo .cpp. Él no se dará cuenta, porque el stdafx.h lo incluye implícitamente. Entonces, él empuja sus cambios en el control de versiones, y luego algunos otros miembros del equipo de gcc obtendrán errores de compilación. Por lo tanto, por cada 5 minutos al día que gane mediante el uso de encabezados precompilados, otras 5 personas pierden al arreglar los encabezados que faltan.
Si no comparte el mismo código en todos sus compiladores, se encontrará con problemas así todos los días. Si fuerza a los desarrolladores de VS a verificar la compilación en gcc antes de realizar cambios, eliminará todas las ganancias de productividad del uso de encabezados precompilados.
La opción 4 suena atractiva, pero ¿qué ocurre si desea utilizar otro compilador en algún momento? La opción 4 solo funciona si solo usa VS y gcc.
Tenga en cuenta que la opción 1 puede hacer que la compilación gcc sufra algunos segundos. Aunque puede no ser notable.
Solución muy simple Agregue una entrada de archivo ficticio para "stdafx.h" en el entorno Linux.
Utilicé la here última vez que necesité hacer lo mismo. Mi proyecto era bastante pequeño pero funcionó maravillosamente.