Partager via


Fichiers d’en-tête précompilés

Lorsque vous créez un projet dans Visual Studio, un fichier d’en-tête précompilé nommé pch.h est ajouté au projet. (Dans Visual Studio 2017 et versions antérieures, le fichier a été appelé stdafx.h.) L’objectif du fichier est d’accélérer le processus de génération. Tous les fichiers d’en-tête stables, par exemple les en-têtes de bibliothèque standard tels que <vector>, doivent être inclus ici. L’en-tête précompilé est compilé uniquement lorsqu’il ou tous les fichiers qu’il inclut sont modifiés. Si vous apportez uniquement des modifications dans le code source de votre projet, la build ignore la compilation de l’en-tête précompilé.

Les options du compilateur pour les en-têtes précompilés sont /Y. Dans les pages de propriétés du projet, les options se trouvent sous Propriétés>de configuration C/C++>En-têtes précompilés. Vous pouvez choisir de ne pas utiliser d’en-têtes précompilés, et vous pouvez spécifier le nom du fichier d’en-tête et le nom et le chemin d’accès du fichier de sortie.

Code précompilé personnalisé

Pour les projets volumineux qui prennent beaucoup de temps à générer, vous pouvez envisager de créer des fichiers précompilés personnalisés. Les compilateurs Microsoft C et C++ offrent des options pour la précompilation du code en C ou C++, y compris du code incorporé. À l’aide de cette fonctionnalité de performances, vous pouvez compiler un corps stable de code, stocker l’état compilé du code dans un fichier et, pendant les compilations suivantes, combiner le code précompilé avec du code toujours en cours de développement. Chaque compilation ultérieure est plus rapide, car le code stable n’a pas besoin d’être recompilé.

Quand précompiler le code source

Le code précompilé est utile pendant le cycle de développement pour réduire le temps de compilation, en particulier si :

  • Vous utilisez toujours un grand corps de code qui change rarement.

  • Votre programme comprend plusieurs modules, qui utilisent tous un ensemble standard de fichiers include et les mêmes options de compilation. Dans ce cas, tous les fichiers include peuvent être précompilés en un en-tête précompilé. Pour plus d’informations sur les nouvelles façons de gérer les fichiers include, consultez Comparer les unités d’en-tête, les modules et les en-têtes précompilés.

La première compilation (celle qui crée le fichier d’en-tête précompilé) prend un peu plus de temps que les compilations suivantes. Les compilations suivantes peuvent continuer plus rapidement en incluant le code précompilé.

Vous pouvez précompiler les programmes C et C++. Dans la programmation C++, il est courant de séparer les informations d’interface de classe dans les fichiers d’en-tête. Ces fichiers d’en-tête peuvent être inclus ultérieurement dans les programmes qui utilisent la classe. En précompilant ces en-têtes, vous pouvez réduire le temps nécessaire à la compilation d’un programme.

Remarque

Bien que vous ne puissiez utiliser qu’un seul fichier d’en-tête précompilé (.pch) par fichier source, vous pouvez utiliser plusieurs .pch fichiers dans un projet.

Deux choix pour le code de précompilation

Vous pouvez précompiler n’importe quel code C ou C++ ; vous n’êtes pas limité à précompiler uniquement les fichiers d’en-tête.

La précompilation nécessite une planification, mais elle offre des compilations beaucoup plus rapides si vous précompilez du code source autre que des fichiers d’en-tête simples.

Code précompilé lorsque vous savez que vos fichiers sources utilisent des ensembles courants de fichiers d’en-tête ou lorsque vous souhaitez inclure du code source dans votre précompilation.

Les options d’en-tête précompilées sont (Créer un fichier d’en-tête précompilé) et /Yu (Utiliser le fichier d’en-tête précompilé)./Yc Permet /Yc de créer un en-tête précompilé. Lorsqu’il est utilisé avec le pragma facultatif hdrstop , /Yc vous permet de précompiler les fichiers d’en-tête et le code source. Sélectionnez cette option /Yu pour utiliser un en-tête précompilé existant dans la compilation existante. Vous pouvez également utiliser /Fp avec les /Yc options et /Yu les options pour fournir un autre nom pour l’en-tête précompilé.

Les articles de référence de l’option du compilateur pour /Yu et /Yc expliquent comment accéder à cette fonctionnalité dans l’environnement de développement.

Règles de cohérence d’en-tête précompilées

Étant donné que les fichiers PCH contiennent des informations sur l’environnement de l’ordinateur et les informations d’adresse mémoire sur le programme, vous devez uniquement utiliser un fichier PCH sur l’ordinateur où il a été créé.

Règles de cohérence pour l’utilisation par fichier d’en-têtes précompilés

L’option /Yu du compilateur vous permet de spécifier le fichier PCH à utiliser.

Lorsque vous utilisez un fichier PCH, le compilateur part du principe que le même environnement de compilation qui était en vigueur lors de la création du fichier PCH, sauf indication contraire. L’environnement de compilation inclut les options du compilateur, les pragmas, et ainsi de suite. Si le compilateur détecte une incohérence, il émet un avertissement et identifie l’incohérence si possible. Ces avertissements n’indiquent pas nécessairement un problème avec le fichier PCH ; ils vous avertissent simplement des conflits possibles. Les exigences de cohérence pour les fichiers PCH sont décrites dans les sections suivantes.

Cohérence des options du compilateur

Les options de compilateur suivantes peuvent déclencher un avertissement d’incohérence lors de l’utilisation d’un fichier PCH :

  • Les macros créées à l’aide de l’option Préprocesseur (/D) doivent être identiques entre la compilation qui a créé le fichier PCH et la compilation actuelle. L’état des constantes définies n’est pas case activée ed, mais des résultats imprévisibles peuvent se produire si ces macros changent.

  • Les fichiers PCH ne fonctionnent pas avec les options et /EP les /E options.

  • Les fichiers PCH doivent être créés à l’aide de l’option Générer les informations de navigation (/FR) ou de l’option Exclure les variables locales (/Fr) avant les compilations suivantes qui utilisent le fichier PCH peuvent utiliser ces options.

Compatible C 7.0 (/Z7)

Si cette option est en vigueur lorsque le fichier PCH est créé, les compilations ultérieures qui utilisent le fichier PCH peuvent utiliser les informations de débogage.

Si l’option C 7.0 Compatible (/Z7) n’est pas en vigueur lorsque le fichier PCH est créé, les compilations ultérieures qui utilisent le fichier PCH et /Z7 déclenchent un avertissement. Les informations de débogage sont placées dans le fichier actif .obj et les symboles locaux définis dans le fichier PCH ne sont pas disponibles pour le débogueur.

Inclure la cohérence du chemin d’accès

Un fichier PCH ne contient pas d’informations sur l’en-tête include chemin d’accès qui était en vigueur lors de sa création. Lorsque vous utilisez un fichier PCH, le compilateur utilise toujours le chemin d’accès include de l’en-tête spécifié dans la compilation actuelle.

Cohérence des fichiers sources

Lorsque vous spécifiez l’option Utiliser le fichier d’en-tête précompilé (/Yu) , le compilateur ignore toutes les directives de préprocesseur (y compris pragmas) qui apparaissent dans le code source qui sera précompilé. La compilation spécifiée par ces directives de préprocesseur doit être identique à celle utilisée pour l’option Créer un fichier d’en-tête précompilé (/Yc).

Cohérence pragma

Les pragmas traités lors de la création d’un fichier PCH affectent généralement le fichier avec lequel le fichier PCH est utilisé ultérieurement. message Les comment pragmas n’affectent pas le reste de la compilation.

Ces pragmas affectent uniquement le code dans le fichier PCH ; ils n’affectent pas le code qui utilise ultérieurement le fichier PCH :

comment
linesize

message
page

pagesize
skip

subtitle
title

Ces pragmas sont conservés dans le cadre d’un en-tête précompilé et affectent le reste d’une compilation qui utilise l’en-tête précompilé :

alloc_text
auto_inline
check_stack
code_seg
data_seg

function
include_alias
init_seg
inline_depth

inline_recursion
intrinsic
optimize
pack

pointers_to_members
setlocale
vtordisp
warning

Règles de cohérence pour /Yc et /Yu

Lorsque vous utilisez un en-tête précompilé créé à l’aide /Yc ou /Yu, le compilateur compare l’environnement de compilation actuel à celui qui existait lors de la création du fichier PCH. Veillez à spécifier un environnement cohérent avec le précédent (à l’aide d’options de compilateur cohérentes, de pragmas, et ainsi de suite) pour la compilation actuelle. Si le compilateur détecte une incohérence, il émet un avertissement et identifie l’incohérence si possible. Ces avertissements n’indiquent pas nécessairement un problème avec le fichier PCH ; ils vous avertissent simplement des conflits possibles. Les sections suivantes décrivent les exigences de cohérence pour les en-têtes précompilés.

Cohérence des options du compilateur

Ce tableau répertorie les options du compilateur susceptibles de déclencher un avertissement d’incohérence lors de l’utilisation d’un en-tête précompilé :

Option Nom Règle
/D Définir des constantes et des macros Doit être identique entre la compilation qui a créé l’en-tête précompilé et la compilation actuelle. L’état des constantes définies n’est pas case activée ed. Toutefois, des résultats imprévisibles peuvent se produire si vos fichiers dépendent des valeurs des constantes modifiées.
/E ou /EP Copier la sortie du préprocesseur vers la sortie standard Les en-têtes précompilés ne fonctionnent pas avec l’option ou /EP l’option/E.
/Fr ou /FR Générer des informations sur le navigateur source Microsoft Pour que les /Fr options soient /FR valides avec l’option /Yu , elles doivent également avoir été appliquées lorsque l’en-tête précompilé a été créé. Les compilations suivantes qui utilisent l’en-tête précompilé génèrent également des informations sur le navigateur source. Les informations du navigateur sont placées dans un seul .sbr fichier et sont référencées par d’autres fichiers de la même manière que les informations CodeView. Vous ne pouvez pas remplacer l’emplacement des informations du navigateur source.
/GA, /GD, /GE, /Gw ou/GW Options de protocole Windows Doit être identique entre la compilation qui a créé l’en-tête précompilé et la compilation actuelle. Le compilateur émet un avertissement si ces options diffèrent.
/Zi Générer des informations de débogage complètes Si cette option est en vigueur lorsque l’en-tête précompilé est créé, les compilations suivantes qui utilisent la précompilation peuvent utiliser ces informations de débogage. Si /Zi ce n’est pas le cas lorsque l’en-tête précompilé est créé, les compilations suivantes qui utilisent la précompilation et l’option /Zi déclenchent un avertissement. Les informations de débogage sont placées dans le fichier objet actuel et les symboles locaux définis dans l’en-tête précompilé ne sont pas disponibles pour le débogueur.

Remarque

La fonctionnalité d’en-tête précompilée est destinée à être utilisée uniquement dans les fichiers sources C et C++.

Utilisation d’en-têtes précompilés dans un projet

Les sections précédentes présentent une vue d’ensemble des en-têtes précompilés : /Yc et /Yu, l’option /Fp et le pragma hdrstop . Cette section décrit une méthode d’utilisation des options d’en-tête précompilées manuelles dans un projet ; il se termine par un exemple makefile et le code qu’il gère.

Pour une autre approche de l’utilisation des options d’en-tête précompilées manuelles dans un projet, étudiez l’un des makefiles situés dans le MFC\SRC répertoire créé pendant la configuration par défaut de Visual Studio. Ces makefiles prennent une approche similaire à celle présentée dans cette section. Ils utilisent davantage les macros NMAKE (Microsoft Program Maintenance Utility) et offrent un meilleur contrôle du processus de génération.

Fichiers PCH dans le processus de génération

La base de code d’un projet logiciel est souvent contenue dans plusieurs fichiers sources C ou C++, des fichiers objet, des bibliothèques et des fichiers d’en-tête. En règle générale, un makefile coordonne la combinaison de ces éléments dans un fichier exécutable. La figure suivante montre la structure d’un makefile qui utilise un fichier d’en-tête précompilé. Les noms de macro NMAKE et les noms de fichiers de ce diagramme sont cohérents avec l’exemple de code trouvé dans l’exemple de makefile pour PCH et Exemple de code pour PCH.

La figure utilise trois appareils diagrammematiques pour afficher le flux du processus de génération. Les rectangles nommés représentent chaque fichier ou macro ; les trois macros représentent un ou plusieurs fichiers. Les zones ombrées représentent chaque action de compilation ou de lien. Les flèches indiquent quels fichiers et macros sont combinés pendant le processus de compilation ou de liaison.

 The diagram is described in the text following the diagram.
Structure d’un makefile qui utilise un fichier d’en-tête précompilé :

Diagram showing example inputs and outputs of a makefile that uses a precompiled header file.

Le diagramme montre « $(STABLEHDRS) » et « $(BOUNDRY) » qui alimentent l’application CL /c /C /W3 /Yc$(BOUNDRY) applib.cpp myapp.cpp. Sortie de $(STABLE). PCH). Ensuite, applib.cpp et $(UNSTABLEHDRS) et $(STABLE. Flux PCH) dans CL /c /w3 /Yu $(BOUNDRY) applib.cpp, qui produit applib.obj. myapp.cpp, $(UNSTABLEHDR) et $(STABLE. Flux PCH) dans CL /c /w3 /Yu $(BOUNDRY) myapp.cpp, qui produit myapp.obj. Enfin, applib.obj et myapp.obj sont combinés par LINK /NOD ONERROR :NOEXE $(OBJS), myapp, NUL, $(LIBS), NUL pour produire myapp.exe.

À partir du haut du diagramme, les STABLEHDRS deux sont BOUNDRY des macros NMAKE dans lesquelles vous répertoriez des fichiers qui n’ont probablement pas besoin de recompilation. Ces fichiers sont compilés par la chaîne de commande

CL /c /W3 /Yc$(BOUNDRY) applib.cpp myapp.cpp

uniquement si le fichier d’en-tête précompilé (STABLE.pch) n’existe pas ou si vous apportez des modifications aux fichiers répertoriés dans les deux macros. Dans les deux cas, le fichier d’en-tête précompilé contiendra du code uniquement à partir des fichiers répertoriés dans la STABLEHDRS macro. Répertoriez le dernier fichier que vous souhaitez précompiler dans la BOUNDRY macro.

Les fichiers que vous répertoriez dans ces macros peuvent être des fichiers d’en-tête ou des fichiers sources C ou C++. (Un seul fichier PCH ne peut pas être utilisé avec les sources C et C++.) Vous pouvez utiliser la macro pour arrêter la hdrstop précompilation à un moment donné dans le BOUNDRY fichier. Pour plus d’informations, consultez hdrstop.

Ensuite, dans le diagramme, APPLIB.obj représente le code de prise en charge utilisé dans votre application finale. Il est créé à partir des APPLIB.cppfichiers répertoriés dans la UNSTABLEHDRS macro et du code précompilé à partir de l’en-tête précompilé.

MYAPP.obj représente votre application finale. Il est créé à partir des MYAPP.cppfichiers répertoriés dans la UNSTABLEHDRS macro et du code précompilé à partir de l’en-tête précompilé.

Enfin, le fichier exécutable (MYAPP.EXE) est créé en liant les fichiers répertoriés dans la OBJS macro (APPLIB.obj et MYAPP.obj).

Exemple de makefile pour PCH

Le makefile suivant utilise des macros et une !IFstructure de commandes , !ELSE!ENDIF flow-of-control pour simplifier son adaptation à votre projet.

# Makefile : Illustrates the effective use of precompiled
#            headers in a project
# Usage:     NMAKE option
# option:    DEBUG=[0|1]
#            (DEBUG not defined is equivalent to DEBUG=0)
#
OBJS = myapp.obj applib.obj
# List all stable header files in the STABLEHDRS macro.
STABLEHDRS = stable.h another.h
# List the final header file to be precompiled here:
BOUNDRY = stable.h
# List header files under development here:
UNSTABLEHDRS = unstable.h
# List all compiler options common to both debug and final
# versions of your code here:
CLFLAGS = /c /W3
# List all linker options common to both debug and final
# versions of your code here:
LINKFLAGS = /nologo
!IF "$(DEBUG)" == "1"
CLFLAGS   = /D_DEBUG $(CLFLAGS) /Od /Zi
LINKFLAGS = $(LINKFLAGS) /COD
LIBS      = slibce
!ELSE
CLFLAGS   = $(CLFLAGS) /Oselg /Gs
LINKFLAGS = $(LINKFLAGS)
LIBS      = slibce
!ENDIF
myapp.exe: $(OBJS)
    link $(LINKFLAGS) @<<
$(OBJS), myapp, NUL, $(LIBS), NUL;
<<
# Compile myapp
myapp.obj  : myapp.cpp $(UNSTABLEHDRS)  stable.pch
    $(CPP) $(CLFLAGS) /Yu$(BOUNDRY)    myapp.cpp
# Compile applib
applib.obj : applib.cpp $(UNSTABLEHDRS) stable.pch
    $(CPP) $(CLFLAGS) /Yu$(BOUNDRY)    applib.cpp
# Compile headers
stable.pch : $(STABLEHDRS)
    $(CPP) $(CLFLAGS) /Yc$(BOUNDRY)    applib.cpp myapp.cpp

Outre les STABLEHDRSmacros et les UNSTABLEHDRSBOUNDRYmacros indiquées dans la figure « Structure d’un makefile qui utilise un fichier d’en-tête précompilé » dans les fichiers PCH du processus de génération, ce makefile fournit une CLFLAGS macro et une LINKFLAGS macro. Vous devez utiliser ces macros pour répertorier les options du compilateur et de l’éditeur de liens qui s’appliquent si vous générez une version de débogage ou finale du fichier exécutable de l’application. Il existe également une LIBS macro dans laquelle vous répertoriez les bibliothèques dont votre projet a besoin.

Le makefile utilise !IFégalement , !ELSE!ENDIF pour détecter si vous définissez un DEBUG symbole sur la ligne de commande NMAKE :

NMAKE DEBUG=[1|0]

Cette fonctionnalité vous permet d’utiliser le même makefile pendant le développement et pour les versions finales de votre programme. Utiliser DEBUG=0 pour les versions finales. Les lignes de commande suivantes sont équivalentes :

NMAKE
NMAKE DEBUG=0

Pour plus d’informations sur les makefiles, consultez la référence NMAKE. Consultez également les options du compilateur MSVC et les options de l’éditeur de liens MSVC.

Exemple de code pour PCH

Les fichiers sources suivants sont utilisés dans le makefile décrit dans les fichiers PCH dans le processus de génération et l’exemple de makefile pour PCH. Les commentaires contiennent des informations importantes.

Fichier source ANOTHER.H :

// ANOTHER.H : Contains the interface to code that is not
//             likely to change.
//
#ifndef __ANOTHER_H
#define __ANOTHER_H
#include<iostream>
void savemoretime( void );
#endif // __ANOTHER_H

Fichier source STABLE.H :

// STABLE.H : Contains the interface to code that is not likely
//            to change. List code that is likely to change
//            in the makefile's STABLEHDRS macro.
//
#ifndef __STABLE_H
#define __STABLE_H
#include<iostream>
void savetime( void );
#endif // __STABLE_H

Fichier source UNSTABLE.H :

// UNSTABLE.H : Contains the interface to code that is
//              likely to change. As the code in a header
//              file becomes stable, remove the header file
//              from the makefile's UNSTABLEHDR macro and list
//              it in the STABLEHDRS macro.
//
#ifndef __UNSTABLE_H
#define __UNSTABLE_H
#include<iostream>
void notstable( void );
#endif // __UNSTABLE_H

Fichier source APPLIB.CPP :

// APPLIB.CPP : This file contains the code that implements
//              the interface code declared in the header
//              files STABLE.H, ANOTHER.H, and UNSTABLE.H.
//
#include"another.h"
#include"stable.h"
#include"unstable.h"
using namespace std;
// The following code represents code that is deemed stable and
// not likely to change. The associated interface code is
// precompiled. In this example, the header files STABLE.H and
// ANOTHER.H are precompiled.
void savetime( void )
    { cout << "Why recompile stable code?\n"; }
void savemoretime( void )
    { cout << "Why, indeed?\n\n"; }
// The following code represents code that is still under
// development. The associated header file is not precompiled.
void notstable( void )
    { cout << "Unstable code requires"
            << " frequent recompilation.\n";
    }

Fichier source MYAPP.CPP :

// MYAPP.CPP : Sample application
//             All precompiled code other than the file listed
//             in the makefile's BOUNDRY macro (stable.h in
//             this example) must be included before the file
//             listed in the BOUNDRY macro. Unstable code must
//             be included after the precompiled code.
//
#include"another.h"
#include"stable.h"
#include"unstable.h"
int main( void )
{
    savetime();
    savemoretime();
    notstable();
}

Voir aussi

Comparer les unités d’en-tête, les modules et les en-têtes précompilés
Référence à la génération d’un programme C/C++
Vue d’ensemble des optionsdu compilateur MSVC des modules en C++
Tutoriel : Importer la bibliothèque standard C++ à l’aide de modules
Procédure pas à pas : Générer et importer des unités d’en-tête dans vos projets Visual C++
Procédure pas à pas : Importer des bibliothèques STL en tant qu’unités d’en-tête