Question

J'ai une solution avec de nombreux projets Visual C ++, tous utilisant PCH, mais certains ont des commutateurs de compilateur particuliers activés pour des besoins spécifiques à un projet.

La plupart de ces projets partagent le même ensemble d’en-têtes dans leurs fichiers stdafx.h respectifs (STL, boost, etc.). Je me demande s’il est possible de partager PCH d’un projet à l’autre, de manière à ce que, au lieu de compiler chaque PCH par projet, je puisse avoir un PCH commun que la plupart des projets de la solution pourraient simplement utiliser.

Il semble possible de spécifier l'emplacement de PCH en tant qu'emplacement partagé dans les paramètres du projet, afin que je sache que cela pourrait fonctionner. Je suppose également que tous les fichiers source de tous les projets utilisant un PCH partagé doivent avoir les mêmes paramètres de compilateur, sinon le compilateur se plaindrait des incohérences entre PCH et le fichier source en cours de compilation.

Quelqu'un a-t-il essayé cela? Ça marche?

Une question connexe: un tel fragment PCH devrait-il être trop inclusif, ou est-ce que cela nuirait au temps de construction? Par exemple, un PCH partagé peut inclure de nombreux en-têtes STL largement utilisés, mais certains projets peuvent ne nécessiter que <string> et <vector>. Le temps gagné en utilisant un PCH partagé devra-t-il être remboursé à un stade ultérieur du processus de construction, lorsque l'optimiseur devra supprimer tous les éléments inutilisés apportés dans le projet par le PCH?

Était-ce utile?

La solution

Oui, c'est possible et je peux vous assurer que les gains de temps sont considérables. Lorsque vous compilez votre PCH, vous devez copier les fichiers .pdb et .idb du projet créant le fichier PCH. Dans mon cas, j'ai un simple projet de deux fichiers qui crée un fichier PCH. L'en-tête sera votre en-tête PCH et il sera dit à la source de créer PCH sous les paramètres du projet - ceci est similaire à ce que vous feriez normalement dans n'importe quel projet. Comme vous l'avez mentionné, vous devez disposer des mêmes paramètres de compilation pour chaque configuration, sinon une différence apparaîtra et le compilateur se plaindra.

Copier les fichiers mentionnés ci-dessus chaque fois qu'il y a une reconstruction ou chaque fois que PCH est recompilé sera une tâche ardue, nous allons donc l'automatiser. Pour automatiser la copie, effectuez un événement de pré-génération dans lequel les fichiers susmentionnés sont copiés dans le répertoire approprié. Par exemple, si vous compilez des versions Debug et Release de votre PCH, copiez les fichiers de /-Y de votre projet PCH dans le projet <=> de votre projet dépendant. Donc, une commande de copie ressemblerait à ceci

  

copier PchPath \ Debug * .pdb Debug \ / -Y

Notez le <=> à la fin. Après la première génération, chaque génération suivante est compilée de manière incrémentielle. Par conséquent, si vous remplacez à nouveau les fichiers, Visual Studio se plaindra des symboles endommagés. S'ils sont corrompus, vous pouvez toujours effectuer une reconstruction qui copiera à nouveau les fichiers (cette fois, ils ne seront pas ignorés car ils n'existent plus - le nettoyage supprime les fichiers).

J'espère que cela aide. Cela m'a pris un certain temps pour pouvoir faire cela, mais ça valait le coup. J'ai plusieurs projets qui dépendent d'un grand cadre, et PCH n'a besoin d'être compilé qu'une seule fois. Tous les projets dépendants se compilent maintenant très rapidement.

  

EDIT: J'ai testé cela sous VS2010 avec plusieurs autres personnes.   et VS2012 et cela semble fonctionner correctement.

Autres conseils

Bien qu'il s'agisse d'une vieille question, je souhaite donner une nouvelle réponse qui fonctionne dans Visual Studio 2017 et n'implique aucune copie. Seul inconvénient: Editer et continuer ne fonctionne plus.

En gros, vous devez créer un nouveau projet pour l'en-tête précompilé et laisser tous les autres projets en dépendre. Voici ce que j'ai fait:

Pas à pas:

  1. Créez un nouveau projet dans votre solution comprenant l’en-tête (appelé pch.h à partir d’ici) et un fichier cpp à une ligne incluant pch.h. Le projet devrait créer une bibliothèque statique. Configurez le nouveau projet pour créer un en-tête précompilé. Le fichier de sortie doit être accessible à tous les projets. pour moi, cela est relatif à IntDir, mais pour les paramètres par défaut, il pourrait être relatif à $ (SolutionDir). Le projet pch ne doit définir que tous les autres projets.

     paramètres de projet pch

  2. Tous les autres projets dépendent de ce nouveau projet. Sinon, l'ordre de fabrication risque d'être incorrect.

     références de projet

  3. Configurez tous les autres projets pour qu'ils utilisent pch.h. Voir comment les paramètres du fichier de sortie sont les mêmes que dans le projet pch. Les répertoires d'inclusion supplémentaires doivent également pointer vers le répertoire pch.h. Facultativement, vous pouvez forcer l'inclusion du fichier pch dans chaque cpp (ou vous l'incluez manuellement dans la première ligne de chaque fichier cpp).

     pch inclure inclure

    1. Configurez tous les projets (y compris le projet pch) pour qu'ils utilisent le même fichier de symboles du compilateur (le fichier de symboles de l'éditeur de liens n'est pas affecté). Encore une fois, dans mon exemple, il s'agit de OutDir mais dans votre solution, cela peut varier. Il doit pointer sur le même fichier sur le disque. Le format des informations de débogage doit être défini sur C7 (voir capture d'écran ci-dessus), sinon Visual Studio ne pourra pas compiler des projets en parallèle. pdb

J'espère n'avoir rien oublié. Pour ma solution (130k loc, 160 projets), cela a abouti à un temps de compilation de ~ 2h30, au lieu de 3h30.

Cela semble impossible, car chaque fichier source doit être compilé avec le même PDB que celui utilisé par PCH. sacrément.

La réponse de Samaursa a fonctionné pour moi.

J'ai également vu ce lien qui fonctionne (recherchez la réponse de Reginald vers le bas).

Celui-ci utilise copy tandis que Reginald utilise xcopy (je préfère <=>). Quoi qu'il en soit, merci - cela a considérablement accéléré ma construction.

Cela ressemble à un cas de " rendements décroissants " pour moi. Supposons que l'inclusion des en-têtes communs gaspille 1 seconde par fichier .cpp et que chaque cible (DLL / EXE) possède 10 fichiers .cpp. En utilisant un fichier .pch par cible, vous économisez 10 secondes par cible. Si votre projet comporte 10 objectifs, vous gagnez 1,5 minute sur toute la construction, ce qui est bien.

Mais en le réduisant à un .pch pour l'ensemble du projet, vous ne perdriez que 9 secondes supplémentaires. Est-ce que ça vaut le coup? L’effort supplémentaire (qui peut être beaucoup plus fastidieux à configurer, étant une configuration non standard non prise en charge par les assistants VS) ne produit qu’un dixième de l’économie.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top