2009-07-27 8 views
49

Ho un programma basato su Visual Studio C++ che utilizza intestazioni precompilate (stdafx.h). Ora stiamo eseguendo il porting dell'applicazione su Linux usando gcc 4.x.Gestione di stdafx.h nel codice multipiattaforma

La domanda è come gestire l'intestazione precompilata in entrambi gli ambienti. Ho cercato su Google ma non riesco a concludere.

Ovviamente voglio lasciare stdafx.h in Visual Studio poiché la base di codice è piuttosto grande e le intestazioni precompilate aumentano il tempo di compilazione.

Ma la domanda è cosa fare in Linux. Questo è quello che ho trovato:

  1. Lasciare il stdafx.h così com'è. gcc compila il codice considerevolmente più veloce di VC++ (o è solo la mia macchina Linux è più forte ... :)), quindi forse sono felice con questa opzione.
  2. Usa approccio da here - rendono stdafx.h assomigliare (impostato USE_PRECOMPILED_HEADER solo per VS):

    #ifdef USE_PRECOMPILED_HEADER 
    ... my stuff 
    #endif 
    
  3. utilizzare l'approccio da here - compilare VC++ con /FI per implicitamente includono stdafx.h in ogni file cpp. Pertanto in VS il tuo codice può essere cambiato facilmente per essere compilato senza intestazioni precompilate e nessun codice dovrà essere modificato.
    Personalmente non mi piacciono le dipendenze e il pasticcio stdafx.h sta spingendo una grande base di codici verso. Quindi l'opzione mi piace - su Linux non hai stdafx.h, mentre sei ancora in grado di attivare le intestazioni precompilate su VS solo da /FI.

  4. Su Linux compilare stdafx.h solo come un'intestazione precompilata (mimica Visual Studio)

vostra opinione? Esistono altri approcci per trattare il problema?

risposta

41

È meglio utilizzare ancora intestazioni precompilate per la compilazione più rapida.

È possibile utilizzare anche le intestazioni precompilate in gcc. See here.

L'intestazione precompilata compilata avrà un'estensione aggiunta come .gch anziché .pch.

Così, per esempio, se si precompilare stdafx.h si avrà un'intestazione precompilata che verrà automaticamente ricercata chiamato stdafx.h.gch in qualsiasi momento si include stdafx.h

Esempio:

stdafx.h:

#include <string> 
#include <stdio.h> 

a.cpp:

#include "stdafx.h" 
int main(int argc, char**argv) 
{ 
    std::string s = "Hi"; 
    return 0; 
} 

Poi compilare come:

> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out

tua compilation funzionerà anche se si rimuove stdafx.h dopo la fase 1.

+0

rimuovere stdafx.h da dove? – dimba

+3

Ho significava solo che dopo aver eseguito g ++ -c stdafx.h -o stdafx.h.gch, è possibile rimuovere stdafx.he compilation sarebbe ancora lavorare (g a.cpp ++). In realtà non lo faresti, ma l'ho menzionato come prova che sta usando l'intestazione precompilata. –

+0

@ Brian Forse mi sbaglio, ma questo sembra l'opzione 4 ho elencato :) Ho provato a rimuovere stdafx.h da a.cpp e non ha compilato - intestazione precompilata verrà cercato solo se il file corrispondente di intestazione è incluso. L'ho confermato con strace :)). – dimba

3

Ho usato option 3 l'ultima volta che avevo bisogno di fare la stessa cosa. Il mio progetto era piuttosto piccolo ma questo ha funzionato meravigliosamente.

0

Ho eseguito entrambe le opzioni 2 (#ifdef) e l'opzione 4 (PCH per gcc) per il codice multipiattaforma senza problemi.

Trovo che gcc compili molto più velocemente di VS, quindi le intestazioni precompilate in genere non sono così importanti, a meno che non si faccia riferimento a un enorme file di intestazione.

2

Avrei scelto l'opzione 4 o l'opzione 2. Ho sperimentato le intestazioni precompilate su entrambe le versioni VS e GCC su Linux (post di blog su questo here e here). Nella mia esperienza, VS è molto più sensibile alla lunghezza dei percorsi di inclusione, al numero di directory nel percorso di inclusione e al numero di file di inclusione rispetto a G ++. Quando ho misurato i tempi di compilazione correttamente, le intestazioni precompilate avrebbero fatto una grande differenza per il tempo di compilazione sotto VS, mentre G ++ non ne era affatto impressionato.

In realtà, in base a quanto sopra ho fatto l'ultima volta che ho lavorato a un progetto in cui questo era necessario per contenere il tempo di compilazione era precompilare l'equivalente di stdafx.h in Windows dove aveva senso e semplicemente lo usava come un normale file sotto Linux.

1

E 'semplice, in realtà:

Progetto-> Progetto Impostazioni (Alt + F7)

Progetto-Impostazioni-Dialog:
C++ -> Categoria: intestazioni precompilate -> pulsanti di opzione intestazioni precompilate - > disabilita

1

Dato che stdafx.h è per impostazione predefinita tutto il materiale specifico di Windows, ho messo un vuoto stdafx.h sulla mia altra piattaforma. In questo modo il tuo codice sorgente rimane identico, mentre disabilita efficacemente stdafx su Linux senza dover rimuovere tutte le linee #include "stdafx.h" dal tuo codice.

2

Soluzione molto semplice. Aggiungere una voce di file fittizio per "stdafx.h" in ambiente Linux.

1

Userei solo l'opzione 1 in un grande team di sviluppatori. Le opzioni 2, 3 e 4 interromperanno spesso la produttività degli altri membri della tua squadra, quindi è possibile risparmiare alcuni minuti al giorno in fase di compilazione per.

Ecco perché:

Supponiamo che la metà dei vostri sviluppatori di utilizzare VS e mezzo uso gcc. Ogni tanto uno sviluppatore VS dimentica di includere un'intestazione in un file .cpp. Non lo noterà, perché lo stdafx.h lo include implicitamente.Quindi, spinge le sue modifiche nel controllo della versione, e quindi alcuni altri membri del team gcc riceveranno errori del compilatore. Quindi, ogni 5 minuti al giorno si guadagna usando le intestazioni precompilate, altre 5 persone sprecano aggiustando le intestazioni mancanti.

Se non si condivide lo stesso codice in tutti i tuoi compilatori, si incorrere in problemi del genere ogni giorno. Se costringi i tuoi sviluppatori VS a controllare la compilazione su gcc prima di spingere le modifiche, eliminerai tutti i guadagni di produttività dall'uso di intestazioni precompilate.

Opzione 4 sembra allettante, ma se si vuole usare un altro compilatore ad un certo punto nel tempo? L'opzione 4 funziona solo se si usano solo VS e gcc.

Si noti che l'opzione 1 può rendere la compilazione gcc soffrire pochi secondi. Anche se potrebbe non essere evidente.

1

Se si utilizza CMake nel progetto, poi ci sono moduli che automatizzano per voi, molto conveniente, ad esempio vedono cmake-precompilata-headerhere. Per usarlo basta includere il modulo e chiamare:

include(cmake-precompiled-header/PrecompiledHeader.cmake) 
add_precompiled_header(${target} ${header} FORCEINCLUDE SOURCE_CXX ${source}) 

Un altro modulo chiamato Cotire crea il file di intestazione deve essere precompilato (non c'è bisogno di scrivere manualmente StdAfx.h) e accelera costruisce in altri modi - vedi here .

Problemi correlati