Sdílet prostřednictvím


Předkompilované soubory hlaviček

Když v sadě Visual Studio vytvoříte nový projekt, přidá se do projektu předkompilovaný hlavičkový soubor s názvem pch.h . (V sadě Visual Studio 2017 a starším byl soubor volána stdafx.h.) Účelem souboru je urychlit proces sestavení. Zde by měly být zahrnuty všechny stabilní soubory hlaviček, například hlavičky standardní knihovny, například <vector>hlavičky standardní knihovny. Předkompilovaná hlavička je zkompilována pouze tehdy, když se upraví nebo všechny soubory, které obsahuje. Pokud ve zdrojovém kódu projektu provedete změny, sestavení přeskočí kompilaci pro předkompilovanou hlavičku.

Možnosti kompilátoru pro předkompilované hlavičky jsou /Y. Nastránkáchch >> Můžete zvolit, že nebudete používat předkompilovaná záhlaví a můžete zadat název souboru záhlaví a název a cestu výstupního souboru.

Vlastní předkompilovaný kód

U velkých projektů, které zabírají značné množství času sestavení, můžete zvážit vytvoření vlastních předkompilovaných souborů. Kompilátory jazyka Microsoft C a C++ poskytují možnosti pro předkompilování libovolného kódu jazyka C nebo C++, včetně vloženého kódu. Pomocí této funkce výkonu můžete zkompilovat stabilní tělo kódu, uložit zkompilovaný stav kódu do souboru a během následných kompilací zkombinovat předkompilovaný kód s kódem, který je stále ve vývoji. Každá pozdější kompilace je rychlejší, protože stabilní kód nemusí být rekompilován.

Kdy předkompilovat zdrojový kód

Předkompilovaný kód je užitečný během vývojového cyklu, aby se zkrátila doba kompilace, zejména pokud:

  • Vždy používáte velké tělo kódu, které se mění zřídka.

  • Program obsahuje více modulů, z nichž všechny používají standardní sadu souborů include a stejné možnosti kompilace. V tomto případě je možné všechny zahrnuté soubory předkompilovat do jedné předkompilované hlavičky. Další informace o novějších způsobech zpracování souborů zahrnutí naleznete v tématu Porovnání jednotek hlaviček, modulů a předkompilovaných hlaviček.

První kompilace (ta, která vytvoří předkompilovaný soubor hlaviček) trvá o něco déle než následné kompilace. Následné kompilace můžou pokračovat rychleji zahrnutím předkompilovaného kódu.

Můžete předkompilovat programy jazyka C i C++. V programování V jazyce C++ je běžné oddělit informace o rozhraní třídy do souborů hlaviček. Tyto hlavičkové soubory lze později zahrnout do programů, které používají třídu. Předkompilováním těchto hlaviček můžete zkrátit dobu potřebnou ke kompilaci programu.

Poznámka:

I když pro každý zdrojový soubor můžete použít pouze jeden předkompilovaný soubor záhlaví (.pch), můžete v projektu použít více .pch souborů.

Dvě volby pro předkompilování kódu

Můžete předkompilovat jakýkoli kód jazyka C nebo C++; Nejste omezeni pouze na předkompilování pouze souborů hlaviček.

Předkompilování vyžaduje plánování, ale nabízí mnohem rychlejší kompilace, pokud předkompilujete jiný zdrojový kód než jednoduché hlavičkové soubory.

Předkompilní kód, když víte, že zdrojové soubory používají běžné sady hlaviček souborů nebo když chcete do předkompilace zahrnout zdrojový kód.

Možnosti předkompilovaného záhlaví jsou /Yc (vytvořit předkompilovaný hlavičkový soubor) a /Yu (použít předkompilovaný hlavičkový soubor).) Slouží /Yc k vytvoření předkompilované hlavičky. Při použití s volitelnou hdrstop direktivou pragma můžete předkompilovat jak soubory hlaviček, /Yc tak zdrojový kód. Vyberte /Yu , pokud chcete použít existující předkompilovanou hlavičku v existující kompilaci. Můžete také použít /Fp s možnostmi /Yc a /Yu zadat alternativní název předkompilované hlavičky.

Referenční články o možnostech kompilátoru a /Yu/Yc diskutují o tom, jak získat přístup k této funkci ve vývojovém prostředí.

Předkompilovaná pravidla konzistence hlaviček

Protože soubory PCH obsahují informace o prostředí počítače a informace o adrese paměti o programu, měli byste použít pouze soubor PCH na počítači, ve kterém byl vytvořen.

Pravidla konzistence pro použití předkompilovaných hlaviček pro jednotlivé soubory

Možnost /Yu kompilátoru umožňuje určit, který soubor PCH se má použít.

Při použití souboru PCH kompilátor předpokládá stejné prostředí kompilace, které se projevilo při vytváření souboru PCH, pokud nezadáte jinak. Prostředí kompilace zahrnuje možnosti kompilátoru, pragmy atd. Pokud kompilátor zjistí nekonzistence, vydá upozornění a zjistí nekonzistence, pokud je to možné. Taková upozornění nemusí nutně znamenat problém se souborem PCH; prostě vás varují před možnými konflikty. Požadavky na konzistenci pro soubory PCH jsou popsány v následujících částech.

Konzistence možností kompilátoru

Následující možnosti kompilátoru můžou aktivovat upozornění na konzistenci při použití souboru PCH:

  • Makra vytvořená pomocí možnosti Preprocesor (/D) musí být stejná mezi kompilací, která vytvořila soubor PCH a aktuální kompilaci. Stav definovaných konstant se nekontroluje, ale pokud se tato makra změní, může dojít k nepředvídatelným výsledkům.

  • Soubory PCH nefungují s možnostmi /E a /EP možnostmi.

  • Soubory PCH musí být vytvořeny buď pomocí možnosti Generovat informace o procházení (/FR) nebo možnost Vyloučit místní proměnné (/Fr) před následnými kompilacemi, které používají soubor PCH, mohou tyto možnosti použít.

Kompatibilní s C 7.0 (/Z7)

Pokud se tato možnost projeví při vytvoření souboru PCH, mohou později kompilace, které používají soubor PCH, použít informace o ladění.

Pokud při vytvoření souboru PCH není možnost kompatibilní s C 7.0 (/Z7), pozdější kompilace, které používají soubor PCH, a /Z7 aktivují upozornění. Informace o ladění se umístí do aktuálního .obj souboru a místní symboly definované v souboru PCH nejsou pro ladicí program k dispozici.

Zahrnout konzistenci cesty

Soubor PCH neobsahuje informace o cestě k zahrnutí hlavičky, která se projevila při jeho vytvoření. Pokud používáte soubor PCH, kompilátor vždy používá cestu k zahrnutí hlavičky zadanou v aktuální kompilaci.

Konzistence zdrojového souboru

Když zadáte možnost Use Precompiled Header File (/Yu), kompilátor ignoruje všechny direktivy preprocesoru (včetně pragmas), které se zobrazí ve zdrojovém kódu, které budou předkompilovány. Kompilace určená těmito direktivami preprocesoru musí být stejná jako kompilace použitá pro možnost Create Precompiled Header File (/Yc).

Konzistence direktivy Pragma

Pragmas zpracované během vytváření souboru PCH obvykle ovlivňují soubor, se kterým je později použit soubor PCH. Zbývající comment část kompilace nemá vliv na direktivy a message direktivy pragma.

Tyto direktivy mají vliv pouze na kód v souboru PCH; nemají vliv na kód, který později používá soubor PCH:

comment
linesize

message
page

pagesize
skip

subtitle
title

Tyto pragmas se zachovají jako součást předkompilované hlavičky a ovlivňují zbytek kompilace, která používá předkompilovanou hlavičku:

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

Pravidla konzistence pro /Yc a /Yu

Při použití předkompilované hlavičky vytvořené pomocí /Yc nebo /Yukompilátor porovná aktuální prostředí kompilace s prostředím, které existovalo při vytváření souboru PCH. Pro aktuální kompilaci nezapomeňte určit prostředí konzistentní s předchozím prostředím (pomocí konzistentních možností kompilátoru, pragmas atd.). Pokud kompilátor zjistí nekonzistence, vydá upozornění a zjistí nekonzistence, pokud je to možné. Taková upozornění nemusí nutně znamenat problém se souborem PCH; prostě vás varují před možnými konflikty. Následující části popisují požadavky na konzistenci pro předkompilované hlavičky.

Konzistence možností kompilátoru

Tato tabulka uvádí možnosti kompilátoru, které můžou aktivovat upozornění na konzistenci při použití předkompilované hlavičky:

Možnost Název Pravidlo
/D Definování konstant a maker Musí být stejná mezi kompilací, která vytvořila předkompilovanou hlavičku a aktuální kompilaci. Stav definovaných konstant se nekontroluje. Nepředvídatelné výsledky ale mohou nastat, pokud vaše soubory závisí na hodnotách změněných konstant.
/E nebo /EP Kopírování výstupu preprocesoru do standardního výstupu Předkompilované hlavičky nefungují s možností ani /EP s možností/E.
/Fr nebo /FR Generování informací o prohlížeči zdroje Microsoftu /Fr Aby byly možnosti platné /FR s /Yu možností, musí být platné i při vytvoření předkompilované hlavičky. Následné kompilace, které používají předkompilovanou hlavičku, také generují informace o zdrojovém prohlížeči. Informace o prohlížeči jsou umístěny do jednoho .sbr souboru a jsou odkazovány jinými soubory stejným způsobem jako CodeView informace. Umístění informací o zdrojovém prohlížeči nejde přepsat.
/GA, /GD, /GE, /Gwnebo /GW Možnosti protokolu Systému Windows Musí být stejná mezi kompilací, která vytvořila předkompilovanou hlavičku a aktuální kompilaci. Kompilátor vygeneruje upozornění, pokud se tyto možnosti liší.
/Zi Generování úplných informací o ladění Pokud se tato možnost projeví při vytvoření předkompilované hlavičky, můžou následné kompilace, které používají předkompilace, použít tyto informace o ladění. Pokud /Zi se při vytvoření předkompilované hlavičky neprojeví, následné kompilace, které používají předkompilace, a /Zi možnost aktivuje upozornění. Informace o ladění se umístí do aktuálního souboru objektu a místní symboly definované v předkompilované hlavičce nejsou pro ladicí program k dispozici.

Poznámka:

Předkompilovaná hlavička je určena pouze pro použití ve zdrojových souborech C a C++.

Použití předkompilovaných hlaviček v projektu

Předchozí části představují přehled předkompilovaných hlaviček: /Yc a /Yu, možnost /Fp a pragma hdrstop . Tato část popisuje metodu použití možností ručního předkompilovaného záhlaví v projektu; končí ukázkovým souborem pravidel a kódem, který spravuje.

Další přístup k použití možností ručního předkompilovaného záhlaví v projektu si prostudujte jeden ze souborů pravidel umístěných v MFC\SRC adresáři vytvořeném během výchozího nastavení sady Visual Studio. Tyto soubory pravidel používají podobný přístup jako soubor uvedený v této části. Využívají více maker programu Microsoft Program Maintenance Utility (NMAKE) a nabízejí větší kontrolu nad procesem sestavení.

Soubory PCH v procesu sestavení

Základ kódu softwarového projektu je často obsažen v několika zdrojových souborech C nebo C++, souborech objektů, knihovnách a hlavičkových souborech. Soubor pravidel obvykle koordinuje kombinaci těchto prvků do spustitelného souboru. Následující obrázek znázorňuje strukturu souboru pravidel, který používá předkompilovaný hlavičkový soubor. Názvy maker NMAKE a názvy souborů v tomto diagramu jsou konzistentní s ukázkovým kódem nalezeným v ukázkovém souboru pravidel pro PCH a ukázkový kód pro PCH.

Obrázek používá tři diagramová zařízení k zobrazení toku procesu sestavení. Pojmenované obdélníky představují každý soubor nebo makro; tři makra představují jeden nebo více souborů. Stínované oblasti představují každou akci kompilace nebo propojení. Šipky ukazují, které soubory a makra se během procesu kompilace nebo propojení zkombinují.

 The diagram is described in the text following the diagram.
Struktura souboru pravidel, který používá předkompilovaný soubor hlaviček:

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

Diagram znázorňuje "$(STABLEHDRS)" a '$(BOUNDRY)' krmení do CL /c /w3 /Yc$(BOUNDRY) applib.cpp myapp.cpp. Výstupem je $(STABLE). PCH). Pak applib.cpp a $(UNSTABLEHDRS) a $(STABLE. PCH) kanál do CL /c /w3 /Yu $(BOUNDRY) applib.cpp, který vytváří applib.obj. myapp.cpp, $(UNSTABLEHDR) a $(STABLE. PCH) kanál do CL /c /w3 /Yu $(BOUNDRY) myapp.cpp, který vytváří myapp.obj. A konečně, applib.obj a myapp.obj jsou kombinovány link /NOD ONERROR:NOEXE $(OBJS), myapp, NUL, $(LIBS), NUL k vytvoření myapp.exe.

Počínaje horní částí diagramu jsou makra STABLEHDRSBOUNDRY NMAKE, ve kterých pravděpodobně nebudete potřebovat překompilace souborů. Tyto soubory jsou kompilovány pomocí příkazového řetězce.

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

Pouze pokud předkompilovaný hlavičkový soubor (STABLE.pch) neexistuje nebo provedete změny souborů uvedených v těchto dvou makrech. V obou případech bude předkompilovaný soubor hlaviček obsahovat kód pouze ze souborů uvedených v STABLEHDRS makrech. Vypište poslední soubor, který chcete předkompilovat v BOUNDRY makrech.

Soubory, které v těchto makrech uvádíte, mohou být buď soubory hlaviček, nebo zdrojové soubory jazyka C nebo C++. (Jeden soubor PCH nelze použít se zdroji jazyka C i C++.) Makro můžete použít hdrstop k zastavení předkompilace v určitém okamžiku BOUNDRY v souboru. Další informace najdete na webu hdrstop.

Dále v diagramu APPLIB.obj představuje kód podpory použitý v konečné aplikaci. Vytvoří se z APPLIB.cpp, soubory uvedené v UNSTABLEHDRS makre a předkompilovaný kód z předkompilované hlavičky.

MYAPP.obj představuje konečnou aplikaci. Vytvoří se z MYAPP.cpp, soubory uvedené v UNSTABLEHDRS makre a předkompilovaný kód z předkompilované hlavičky.

Nakonec se vytvoří spustitelný soubor (MYAPP.EXE) propojením souborů uvedených v OBJS makrech (APPLIB.obj a MYAPP.obj).

Ukázkový soubor pravidel pro PCH

Následující soubor pravidel používá makra a !IF!ELSE!ENDIF strukturu příkazů toku řízení ke zjednodušení přizpůsobení projektu.

# 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

STABLEHDRSKromě , BOUNDRYa UNSTABLEHDRS makra zobrazená na obrázku "Struktura souboru pravidel, který používá předkompilovaný hlavičkový soubor" v souborech PCH v procesu sestavení, tento soubor pravidel poskytuje CLFLAGS makro a LINKFLAGS makro. Tato makra musíte použít k výpisu možností kompilátoru a linkeru, které se použijí bez ohledu na to, jestli sestavíte ladicí nebo konečnou verzi spustitelného souboru aplikace. K dispozici je také LIBS makro, ve kterém zobrazíte seznam knihoven, které projekt vyžaduje.

Soubor pravidel také používá !IF, !ELSEk detekci, !ENDIF zda definujete symbol na příkazovém DEBUG řádku NMAKE:

NMAKE DEBUG=[1|0]

Tato funkce umožňuje použít stejný soubor makefile během vývoje a pro konečné verze programu. Používá se DEBUG=0 pro konečné verze. Následující příkazové řádky jsou ekvivalentní:

NMAKE
NMAKE DEBUG=0

Další informace osouborch Viz také možnosti kompilátoru MSVC a možnosti linkeru MSVC.

Příklad kódu pro PCH

Následující zdrojové soubory se používají v souboru pravidel popsaném v souborech PCH v procesu sestavení a ukázkový soubor pravidel pro PCH. Komentáře obsahují důležité informace.

Zdrojový soubor 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

Zdrojový soubor 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

Zdrojový soubor 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

Zdrojový soubor 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";
    }

Zdrojový soubor 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();
}

Viz také

Porovnání jednotek záhlaví, modulů a předkompilovaných hlaviček
Referenční dokumentace k sestavení jazyka C/C++
Možnostikompilátoru MSVC – přehled modulů v jazyce C++
Kurz: Import standardní knihovny C++ pomocí modulů
Návod: Sestavení a import jednotek hlaviček v projektech Visual C++
Návod: Import knihoven STL jako jednotek hlaviček