Bagikan melalui


File header yang telah dikompilasi sebelumnya

Saat Anda membuat proyek baru di Visual Studio, file header yang telah dikommpilasikan sebelumnya bernama pch.h ditambahkan ke proyek. (Di Visual Studio 2017 dan yang lebih lama, file disebut stdafx.h.) Tujuan file adalah untuk mempercepat proses build. File header stabil apa pun, misalnya header Pustaka Standar seperti <vector>, harus disertakan di sini. Header yang telah dikompilasi dikompilasi hanya ketika, atau file apa pun yang disertakannya, dimodifikasi. Jika Anda hanya membuat perubahan dalam kode sumber proyek, build akan melewati kompilasi untuk header yang telah dikompilasi sebelumnya.

Opsi kompilator untuk header yang telah dikompilasi sebelumnya adalah /Y. Di halaman properti proyek, opsi terletak di bawah Properti>Konfigurasi C/C++>Header yang Telah Dikommpilasikan. Anda dapat memilih untuk tidak menggunakan header yang telah dikompilasi sebelumnya, dan Anda dapat menentukan nama file header dan nama dan jalur file output.

Kode kustom yang telah dikompilasi sebelumnya

Untuk proyek besar yang membutuhkan waktu signifikan untuk dibuat, Anda mungkin ingin mempertimbangkan untuk membuat file kustom yang telah dikommpilasikan. Pengkompilasi Microsoft C dan C++ menyediakan opsi untuk melakukan prakompilasi kode C atau C++, termasuk kode sebaris. Dengan menggunakan fitur performa ini, Anda dapat mengompilasi isi kode yang stabil, menyimpan status kode yang dikompilasi dalam file, dan, selama kompilasi berikutnya, menggabungkan kode yang telah dikompilasi sebelumnya dengan kode yang masih dalam pengembangan. Setiap kompilasi nanti lebih cepat karena kode stabil tidak perlu dikompilasi ulang.

Kapan harus melakukan prakompilasi kode sumber

Kode yang telah dikompilasi berguna selama siklus pengembangan untuk mengurangi waktu kompilasi, terutama jika:

  • Anda selalu menggunakan isi kode besar yang jarang berubah.

  • Program Anda terdiri dari beberapa modul, yang semuanya menggunakan set standar sertakan file dan opsi kompilasi yang sama. Dalam hal ini, semua file yang disertakan dapat dikommpilasikan sebelumnya ke dalam satu header yang telah dikompreilasi. Untuk informasi selengkapnya tentang cara yang lebih baru untuk menangani menyertakan file, lihat Membandingkan unit header, modul, dan header yang telah dikommpilasikan sebelumnya.

Kompilasi pertama (yang membuat file header yang telah dikommpilasikan sebelumnya) membutuhkan waktu sedikit lebih lama daripada kompilasi berikutnya. Kompilasi berikutnya dapat dilanjutkan dengan lebih cepat dengan menyertakan kode yang telah dikompilasi sebelumnya.

Anda dapat melakukan prakompeksi program C dan C++. Dalam pemrograman C++, adalah praktik umum untuk memisahkan informasi antarmuka kelas ke dalam file header. File header ini nantinya dapat disertakan dalam program yang menggunakan kelas . Dengan melakukan prakompilasi header ini, Anda dapat mengurangi waktu yang diperlukan program untuk dikompilasi.

Catatan

Meskipun Anda hanya dapat menggunakan satu file header (.pch) yang telah dikommpilasikan sebelumnya per file sumber, Anda dapat menggunakan beberapa .pch file dalam proyek.

Dua pilihan untuk kode prakompilasi

Anda dapat melakukan prakompilasi kode C atau C++; Anda tidak terbatas hanya pada file header yang telah dikommpilasi sebelumnya.

Prakompilasi memerlukan perencanaan, tetapi menawarkan kompilasi yang jauh lebih cepat jika Anda melakukan prakompilasi kode sumber selain file header sederhana.

Kode prakompilasi saat Anda tahu bahwa file sumber Anda menggunakan sekumpulan file header umum, atau saat Anda ingin menyertakan kode sumber dalam prakompilasi Anda.

Opsi header yang telah dikommpilasikan sebelumnya adalah /Yc (Buat File Header yang Telah Dikommpilasikan sebelumnya) dan /Yu (Gunakan File Header yang Telah Dikompresi). Gunakan /Yc untuk membuat header yang telah dikommpilasikan sebelumnya. Saat digunakan dengan pragma opsional hdrstop , /Yc memungkinkan Anda melakukan prakompilasi file header dan kode sumber. Pilih /Yu untuk menggunakan header yang telah dikompilasi sebelumnya di kompilasi yang ada. Anda juga dapat menggunakan /Fp dengan /Yc opsi dan /Yu untuk memberikan nama alternatif untuk header yang telah dikompilasi sebelumnya.

Artikel referensi opsi kompilator untuk /Yu dan /Yc membahas cara mengakses fungsionalitas ini di lingkungan pengembangan.

Aturan konsistensi header yang telah dikompresi

Karena file PCH berisi informasi tentang lingkungan mesin dan informasi alamat memori tentang program, Anda hanya boleh menggunakan file PCH pada komputer tempat file dibuat.

Aturan konsistensi untuk penggunaan per file header yang telah dikommpilasikan sebelumnya

Opsi /Yu pengkompilasi memungkinkan Anda menentukan file PCH mana yang akan digunakan.

Saat Anda menggunakan file PCH, pengkompilasi mengasumsikan lingkungan kompilasi yang sama yang berlaku saat Anda membuat file PCH, kecuali Anda menentukan sebaliknya. Lingkungan kompilasi mencakup opsi kompilator, pragmas, dan sebagainya. Jika kompilator mendeteksi ketidakkonsistensian, kompilator mengeluarkan peringatan dan mengidentifikasi inkonsistensi jika memungkinkan. Peringatan tersebut tidak selalu menunjukkan masalah dengan file PCH; mereka hanya memperingatkan Anda tentang kemungkinan konflik. Persyaratan konsistensi untuk file PCH dijelaskan di bagian berikut.

Konsistensi opsi pengkompilasi

Opsi kompilator berikut dapat memicu peringatan inkonsistensi saat menggunakan file PCH:

  • Makro yang dibuat menggunakan opsi Preprocessor (/D) harus sama antara kompilasi yang membuat file PCH dan kompilasi saat ini. Status konstanta yang ditentukan tidak diperiksa, tetapi hasil yang tidak dapat diprediksi dapat terjadi jika makro ini berubah.

  • File PCH tidak berfungsi dengan /E opsi dan /EP .

  • File PCH harus dibuat menggunakan opsi Hasilkan Info Telusur (/FR) atau opsi Kecualikan Variabel Lokal (/Fr) sebelum kompilasi berikutnya yang menggunakan file PCH dapat menggunakan opsi ini.

Kompatibel dengan C 7.0 (/Z7)

Jika opsi ini berlaku saat file PCH dibuat, kompilasi nanti yang menggunakan file PCH dapat menggunakan informasi penelusuran kesalahan.

Jika opsi C 7.0-Compatible (/Z7) tidak berlaku saat file PCH dibuat, kompilasi selanjutnya yang menggunakan file PCH dan /Z7 memicu peringatan. Informasi penelusuran kesalahan ditempatkan dalam file saat ini .obj , dan simbol lokal yang ditentukan dalam file PCH tidak tersedia untuk debugger.

Sertakan konsistensi jalur

File PCH tidak berisi informasi tentang header menyertakan jalur yang berlaku saat dibuat. Saat Anda menggunakan file PCH, pengkompilasi selalu menggunakan jalur menyertakan header yang ditentukan dalam kompilasi saat ini.

Konsistensi file sumber

Saat Anda menentukan opsi Gunakan File Header Yang Telah Dikompilasi Sebelumnya (/Yu), pengkompilasi mengabaikan semua arahan praprosem (termasuk pragma) yang muncul dalam kode sumber yang akan dikompilasi sebelumnya. Kompilasi yang ditentukan oleh direktif pra-prosesor tersebut harus sama dengan kompilasi yang digunakan untuk opsi Buat File/Yc Header () yang Telah Dikompilasi sebelumnya.

Konsistensi Pragma

Pragmas yang diproses selama pembuatan file PCH biasanya memengaruhi file tempat file PCH digunakan nanti. comment Pragma dan message tidak mempengaruhi sisa kompilasi.

Pragma ini hanya memengaruhi kode dalam file PCH; mereka tidak memengaruhi kode yang nantinya menggunakan file PCH:

comment
linesize

message
page

pagesize
skip

subtitle
title

Pragma ini dipertahankan sebagai bagian dari header yang telah dikommpilasikan sebelumnya, dan memengaruhi sisa kompilasi yang menggunakan header yang telah dikompeksi sebelumnya:

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

Aturan konsistensi untuk /Yc dan /Yu

Saat Anda menggunakan header yang telah dikompilasi yang dibuat menggunakan /Yc atau /Yu, pengkompilasi membandingkan lingkungan kompilasi saat ini dengan yang ada saat Anda membuat file PCH. Pastikan untuk menentukan lingkungan yang konsisten dengan yang sebelumnya (menggunakan opsi kompilator yang konsisten, pragma, dan sebagainya) untuk kompilasi saat ini. Jika kompilator mendeteksi ketidakkonsistensian, kompilator mengeluarkan peringatan dan mengidentifikasi inkonsistensi jika memungkinkan. Peringatan tersebut tidak selalu menunjukkan masalah dengan file PCH; mereka hanya memperingatkan Anda tentang kemungkinan konflik. Bagian berikut menjelaskan persyaratan konsistensi untuk header yang telah dikommpilasikan sebelumnya.

Konsistensi opsi pengkompilasi

Tabel ini mencantumkan opsi pengkompilasi yang mungkin memicu peringatan inkonsistensi saat menggunakan header yang telah dikompilasi sebelumnya:

Opsi Nama Aturan
/D Menentukan konstanta dan makro Harus sama antara kompilasi yang membuat header yang telah dikommpilasikan sebelumnya dan kompilasi saat ini. Status konstanta yang ditentukan tidak diperiksa. Namun, hasil yang tidak dapat diprediksi dapat terjadi jika file Anda bergantung pada nilai konstanta yang diubah.
/E atau /EP Salin output prapemrossor ke output standar Header yang telah dikompresi tidak berfungsi dengan /E opsi atau /EP .
/Fr atau /FR Hasilkan informasi Browser Sumber Microsoft /Fr Agar opsi dan /FR valid dengan /Yu opsi , opsi tersebut juga harus berlaku ketika header yang telah dikommpilasikan dibuat. Kompilasi berikutnya yang menggunakan header yang telah dikommpilasikan sebelumnya juga menghasilkan informasi Browser Sumber. Informasi browser ditempatkan dalam satu .sbr file dan dirujuk oleh file lain dengan cara yang sama seperti informasi CodeView. Anda tidak dapat mengambil alih penempatan informasi Browser Sumber.
/GA, /GD, /GE, /Gw, atau /GW Opsi protokol Windows Harus sama antara kompilasi yang membuat header yang telah dikommpilasikan sebelumnya dan kompilasi saat ini. Pengkompilasi memancarkan peringatan jika opsi ini berbeda.
/Zi Hasilkan informasi penelusuran kesalahan lengkap Jika opsi ini berlaku saat header yang telah dikommpilasikan dibuat, kompilasi berikutnya yang menggunakan prakompeksi dapat menggunakan informasi penelusuran kesalahan tersebut. Jika /Zi tidak berlaku saat header yang telah dikompilasi dibuat, kompilasi berikutnya yang menggunakan prakompilasi dan /Zi opsi memicu peringatan. Informasi penelusuran kesalahan ditempatkan dalam file objek saat ini, dan simbol lokal yang ditentukan dalam header yang telah dikompilasi sebelumnya tidak tersedia untuk debugger.

Catatan

Fasilitas header yang telah dikommpilasikan dimaksudkan untuk digunakan hanya dalam file sumber C dan C++.

Menggunakan header yang telah dikompresi dalam proyek

Bagian sebelumnya menyajikan gambaran umum header yang telah dikompilasi sebelumnya: /Yc dan /Yu, opsi /Fp, dan hdrstop pragma. Bagian ini menjelaskan metode untuk menggunakan opsi header manual yang telah dikommpilasikan sebelumnya dalam proyek; ini diakhir dengan contoh makefile dan kode yang dikelolanya.

Untuk pendekatan lain menggunakan opsi header prakompilasi manual dalam proyek, pelajari salah satu makefiles yang terletak di MFC\SRC direktori yang dibuat selama penyiapan default Visual Studio. Makefiles ini mengambil pendekatan serupa dengan yang disajikan di bagian ini. Mereka memanfaatkan makro Microsoft Program Maintenance Utility (NMAKE) yang lebih besar, dan menawarkan kontrol yang lebih besar terhadap proses build.

File PCH dalam proses build

Basis kode proyek perangkat lunak sering kali terkandung dalam beberapa file sumber C atau C++, file objek, pustaka, dan file header. Biasanya, makefile mengoordinasikan kombinasi elemen-elemen ini ke dalam file yang dapat dieksekusi. Gambar berikut menunjukkan struktur makefile yang menggunakan file header yang telah dikombinasikan sebelumnya. Nama makro NMAKE dan nama file dalam diagram ini konsisten dengan kode contoh yang ditemukan dalam Contoh makefile untuk PCH dan Contoh kode untuk PCH.

Gambar menggunakan tiga perangkat diagrammatik untuk menunjukkan alur proses build. Persegi panjang bernama mewakili setiap file atau makro; ketiga makro mewakili satu atau beberapa file. Area berteduh mewakili setiap tindakan kompilasi atau tautan. Panah memperlihatkan file dan makro mana yang digabungkan selama proses kompilasi atau penautan.

 The diagram is described in the text following the diagram.
Struktur makefile yang menggunakan file header yang telah dikommpilasikan sebelumnya:

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

Diagram menunjukkan '$(STABLEHDRS)' dan '$(BOUNDRY)' mengumpan ke cl /c /W3 /Yc$(BOUNDRY) applib.cpp myapp.cpp. Outputnya adalah $(STABLE. PCH). Kemudian, applib.cpp dan $(UNSTABLEHDRS) dan $(STABLE. PCH) masuk ke CL /c /w3 /Yu $(BOUNDRY) applib.cpp, yang menghasilkan applib.obj. myapp.cpp, $(UNSTABLEHDR), dan $(STABLE. PCH) masuk ke CL /c /w3 /Yu $(BOUNDRY) myapp.cpp, yang menghasilkan myapp.obj. Terakhir, applib.obj dan myapp.obj digabungkan oleh LINK /NOD ONERROR:NOEXE $(OBJS), myapp, NUL, $(LIBS), NUL untuk menghasilkan myapp.exe.

Dimulai di bagian atas diagram, baik STABLEHDRS dan BOUNDRY makro NMAKE tempat Anda mencantumkan file tidak mungkin memerlukan kompilasi ulang. File-file ini dikompilasi oleh string perintah

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

hanya jika file header yang telah dikombinasikan sebelumnya (STABLE.pch) tidak ada atau jika Anda membuat perubahan pada file yang tercantum dalam dua makro. Dalam kedua kasus, file header yang telah dikompilasi sebelumnya hanya akan berisi kode dari file yang tercantum dalam STABLEHDRS makro. Cantumkan file terakhir yang ingin Anda kompilasi sebelumnya BOUNDRY dalam makro.

File yang Anda cantumkan dalam makro ini dapat berupa file header atau file sumber C atau C++. (Satu file PCH tidak dapat digunakan dengan sumber C dan C++.) Anda dapat menggunakan hdrstop makro untuk menghentikan kompilasi di beberapa titik dalam BOUNDRY file. Untuk informasi selengkapnya, lihat hdrstop .

Selanjutnya dalam diagram, APPLIB.obj mewakili kode dukungan yang digunakan dalam aplikasi akhir Anda. Ini dibuat dari APPLIB.cpp, file yang tercantum dalam UNSTABLEHDRS makro, dan kode yang telah dikompilasi sebelumnya dari header yang telah dikompilasi sebelumnya.

MYAPP.obj mewakili aplikasi akhir Anda. Ini dibuat dari MYAPP.cpp, file yang tercantum dalam UNSTABLEHDRS makro, dan kode yang telah dikompilasi sebelumnya dari header yang telah dikompilasi sebelumnya.

Terakhir, file yang dapat dieksekusi (MYAPP.EXE) dibuat dengan menautkan file yang tercantum dalam OBJS makro (APPLIB.obj dan MYAPP.obj).

Contoh makefile untuk PCH

Makefile berikut menggunakan makro dan !IFstruktur perintah alur kontrol , !ELSE, !ENDIF untuk menyederhanakan adaptasinya dengan proyek Anda.

# 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

Selain STABLEHDRSmakro , , BOUNDRYdan UNSTABLEHDRS yang ditunjukkan pada gambar "Struktur Makefile yang Menggunakan File Header yang Telah Dikommpilasikan" dalam file PCH dalam proses build, makefile ini menyediakan CLFLAGS makro dan LINKFLAGS makro. Anda harus menggunakan makro ini untuk mencantumkan opsi pengkompilasi dan pengtaut yang berlaku apakah Anda membuat debug atau versi akhir file aplikasi yang dapat dieksekusi. Ada juga makro tempat Anda mencantumkan pustaka yang LIBS diperlukan proyek Anda.

Makefile juga menggunakan !IF, !ELSE, !ENDIF untuk mendeteksi apakah Anda menentukan DEBUG simbol pada baris perintah NMAKE:

NMAKE DEBUG=[1|0]

Fitur ini memungkinkan Anda untuk menggunakan makefile yang sama selama pengembangan dan untuk versi akhir program Anda. Gunakan DEBUG=0 untuk versi akhir. Baris perintah berikut ini setara:

NMAKE
NMAKE DEBUG=0

Untuk informasi selengkapnya tentang makefiles, lihat referensi NMAKE. Lihat juga opsi pengkompilasi MSVC dan opsi linker MSVC.

Contoh kode untuk PCH

File sumber berikut digunakan dalam makefile yang dijelaskan dalam file PCH dalam proses build dan Contoh makefile untuk PCH. Komentar berisi informasi penting.

File sumber 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

File sumber 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

File sumber 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

File sumber 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";
    }

File sumber 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();
}

Baca juga

Membandingkan unit header, modul, dan header yang telah dikommpilasikan sebelumnya
Referensi bangunan C/C++
Opsi pengkompilasiMSVC Gambaran Umum modul di C++
Tutorial: Mengimpor pustaka standar C++ menggunakan modul
Panduan: Membangun dan mengimpor unit header di proyek Visual C++ Anda
Panduan: Mengimpor pustaka STL sebagai unit header