web-dev-qa-db-fra.com

Gestion de stdafx.h dans du code multiplateforme

J'ai un programme basé sur Visual Studio C++ qui utilise des en-têtes précompilés (stdafx.h). Nous portons maintenant l'application sur Linux à l'aide de gcc 4.x. 

La question est de savoir comment gérer l’en-tête pré-compilé dans les deux environnements ..__J'ai cherché sur Google mais je ne parviens pas à une conclusion. 

Évidemment, je veux laisser stdafx.h dans Visual Studio car la base de code est assez grosse et les en-têtes pré-compilés augmentent le temps de compilation.

Mais la question est de savoir quoi faire sous Linux. Voici ce que j'ai trouvé:

  1. Laissez le stdafx.h tel quel. gcc compile du code considérablement plus rapidement que VC++ (ou c’est juste que ma machine Linux est plus puissante ... :)), alors je suis peut-être content de cette option.
  2. Utilisez l’approche de ici - pour que stdafx.h ressemble à (définissez USE_PRECOMPILED_HEADER pour VS uniquement):

    #ifdef USE_PRECOMPILED_HEADER
    ... my stuff
    #endif 
    
  3. Utilisez l’approche de ici - compilez VC++ avec /FI en implicitement include stdafx.h dans chaque fichier cpp. Par conséquent, dans VS, votre code peut facilement être modifié pour être compilé sans en-têtes pré-compilés et aucun code ne doit être modifié.
    Personnellement, je n'aime pas les dépendances et le désordre stdafx.h pousse une base de code volumineuse vers. Par conséquent, cette option me plaît: sous Linux, vous n'avez pas stdafx.h, tout en pouvant activer les en-têtes précompilés sur VS uniquement par /FI.

  4. Sous Linux, compilez stdafx.h uniquement en tant qu'en-tête précompilé (imite Visual Studio)

Ton opinion? Existe-t-il d'autres approches pour traiter le problème?

53
dimba

Vous feriez mieux d'utiliser des en-têtes précompilés pour une compilation rapide.

Vous pouvez également utiliser des en-têtes précompilés dans gcc. Vois ici .

L'en-tête précompilé compilé aura une extension ajoutée en tant que .gch au lieu de .pch.

Ainsi, par exemple, si vous précompilez stdafx.h, vous aurez un en-tête précompilé qui sera automatiquement recherché par stdafx.h.gch chaque fois que vous incluez stdafx.h.

Exemple:

stdafx.h:

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

a.cpp:

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

Puis compiler en tant que:

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

Votre compilation fonctionnera même si vous supprimez stdafx.h après l’étape 1.

46
Brian R. Bondy

J'ai utilisé option 3 la dernière fois que j'ai eu besoin de faire la même chose. Mon projet était plutôt petit mais cela a fonctionné à merveille. 

3
Kredns

Solution très simple . Ajoutez une entrée de fichier factice pour "stdafx.h" dans l'environnement Linux.

2
Bikramjit singh

Je choisirais l'option 4 ou l'option 2. J'ai déjà expérimenté des en-têtes précompilés sur différentes versions de VS et GCC sous Linux (billets de blog sur ceci ici et ici ). D'après mon expérience, VS est beaucoup plus sensible à la longueur des chemins d'inclusion, au nombre de répertoires dans le chemin d'inclusion et au nombre de fichiers d'inclusion que G ++. Lorsque je mesurais les temps de construction, les en-têtes précompilés correctement agencés feraient une énorme différence en termes de temps de compilation sous VS, alors que G ++ n’était guère impressionné par cela.

En fait, sur la base de ce qui précède, ce que je faisais la dernière fois que je travaillais sur un projet où il était nécessaire de limiter le temps de compilation consistait à précompiler l’équivalent de stdafx.h sous Windows où cela avait un sens et l’utilisait simplement comme fichier normal sous Linux.

2
Timo Geusch

J'utiliserais uniquement l'option 1 dans une grande équipe de développeurs ... Les options 2, 3 et 4 arrêteront souvent la productivité des autres membres de votre équipe, de sorte que vous pouvez économiser quelques minutes par jour en compilation temps. 

Voici pourquoi:

Supposons que la moitié de vos développeurs utilisent VS et l'autre moitié gcc . De temps à autre, certains développeurs VS oublient d'inclure un en-tête dans un fichier .cpp . Il ne le remarquera pas, car stdafx.h l'inclut implicitement. Ainsi, il pousse ses modifications dans le contrôle de version, puis quelques autres membres de l’équipe de gcc vont avoir des erreurs de compilation . Ainsi, pour chaque gain de 5 minutes par jour en utilisant des en-têtes précompilés, 5 autres personnes gaspillent en réparant vos en-têtes manquants.

Si vous ne partagez pas le même code sur tous vos compilateurs, vous rencontrerez des problèmes de ce type tous les jours. Si vous forcez les développeurs de votre VS à vérifier la compilation sur gcc avant d’appliquer des modifications, vous perdrez tous vos gains de productivité en utilisant des en-têtes précompilés.

L'option 4 semble attrayante, mais qu'en est-il si vous voulez utiliser un autre compilateur à un moment donné? L'option 4 ne fonctionne que si vous utilisez uniquement VS et gcc.

Notez que l'option 1 peut faire en sorte que la compilation de gcc prenne quelques secondes. Bien que cela ne soit pas perceptible.

2
Grim Fandango

C'est simple, vraiment:

Projet-> Paramètres du projet (Alt + F7)

Projet-Paramètres-Dialogue:
C++ -> Catégorie: En-têtes précompilés -> Boutons radio des en-têtes précompilés -> Désactiver

1
Stefan Steiger

Si vous utilisez CMake dans votre projet, il existe des modules qui l’automatisent pour vous, très pratique, par exemple, voir cmake-precompiled-headerhere . Pour l'utiliser, il suffit d'inclure le module et d'appeler:

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

Un autre module appelé Cotire crée le fichier d’en-tête à pré-compiler (inutile d’écrire manuellement StdAfx.h) et accélère les générations d’une autre manière - voir ici .

1
Roman Kruglov

Puisque stdafx.h est par défaut tout le matériel spécifique à Windows, j'ai mis un stdafx.h vide sur mon autre plate-forme. Ainsi, votre code source reste identique tout en désactivant stdafx sous Linux sans avoir à supprimer toutes les lignes #include "stdafx.h" de votre code.

1
Jeff

J'ai utilisé l'option 2 (#ifdef) et l'option 4 (PCH pour gcc) pour un code multiplateforme sans problème. 

Je trouve que gcc compile beaucoup plus rapidement que VS, donc les en-têtes précompilés ne sont généralement pas très importants, sauf si vous faites référence à un fichier d'en-tête volumineux.

0
Soo Wei Tan

J'ai une situation où le n ° 2 en particulier ne fonctionnait pas pour moi (il existe de nombreuses configurations de construction de VS où un #ifdef autour de #include "stdafx.h" ne fonctionne pas). D'autres solutions n'étaient pas optimales, car les fichiers eux-mêmes étaient multi-projets et multi-plateformes. Je ne voulais pas forcer la définition de macros de préprocesseur, ni forcer les versions de Linux ou même de Windows à utiliser (ou non) pch, alors ...

Ce que j'ai fait, étant donné qu'un fichier nommé notificationEngine.cpp, par exemple, a été entièrement supprimée de la ligne #include stdafx.h, a créé un nouveau fichier dans le même répertoire appelé pchNotificationEngine.cpp avec le contenu suivant:

#include "stdafx.h"
#include "notificationEngine.cpp"

Tout projet donné peut simplement inclure la version correcte du fichier. Certes, ce n'est probablement pas la meilleure option pour les fichiers cpp qui ne sont utilisés que par un seul projet.

0
zzxyz