Skip navigation

Fordítási optimalizáció gyanánt a projektjeimet átírtam, hogy precompiled header-eket használjanak. Az átírás eredményesnek bizonyult, a szükséges idő nagyjából a harmadára csökkent. Cserébe Visual Studio-s debugolás közben nem voltak szimbólumaim, rengeteg változónak csak a címe látszódott.

A precompiled header lényege, hogy van egy közös gyűjtő file az összes projekten belüli header include-olására, általában stdafx.h. Ezt kell ügyesen jó sorrendben felépíteni, hogy le tudjon fordulni az az stdafx.cpp, ami semmi mást nem csinál csak ezt a header-t includeolja. Ha ez megvan, akkor minden más include-ot írtsunk ki a kódból és az összes source (.cpp) file-unk legelején (legelső nem comment sor) include-oljuk az stdafx.h-t. Ha mindent jól csinálunk, a projektünknek még most is le kell fordulnia. Eztuán a projekt beállításainál (Configuration Properties->C/C++->Precompiled Headers) állítsuk be a Precompiled Header opciót Use-ra (/Yu) és adjuk be a gyűjtő header nevét, ha nem az alapértelmezettet használnánk. Szükség van még a generálás beállítására is, ezt az stdafx.cpp file beállításainál kell megtennünk, ugyanezen opció Create (/Yc)-re állításával. Készen is vagyunk, a buildelés ezután úgy működik, hogy elsőként az stdafx.cpp fog lefordulni és generálódik egy pch file, amit a Precompiled Header Output File opciónál állíthatunk át. A további file-ok fordulásánál már semmilyen include-olásra nincs azonban szükség, egyszerűen ez a pch file adódik hozzá, mint már lefordult header, jelentősen csökkentve ezek fordítási idejét.

Ha szükséges, lehetőség van adott file-okra kikapcsolni a Precompiled Header használatát (/Y), például ha saját projektbe fordítunk bele 3rd party kódot direktben. Az is megoldható, ha a projekt két nagy különálló részre bontható, hogy két precompiled header-t hozunk létre, a saját header file-okkal, és minden forrásfile-nál a megfelelőt include-oljuk, de erre általában nincs szükség. Gyakori megoldás még, hogy az stdafx.h, mivel projekt specifikus beállításokat is tartalmaz általában, csak egy header-t include-ol, általában a projekt nevével megegyezőt, amiben a szükséges header-ek vannak összegyűjtve. Az eredmény így ugyanaz lesz, viszont lehetőség van, hogy ha más projekt is épít ránk, oda csak ezt a header-t húzzuk be és ne a teljes stdafx.h-t amiben esetleg csomó mindenre nincs is szükségünk.

Miután a fent leírt dolgokat én is szépen megcsináltam, a probléma az volt, hogy a solution 2 projektből állt, az egyik a másikat mint library használta és mindkettő precompiled header-t használt a gyorsabb fordulás érdekében. A fordító azonban a lib precompiled header-jébe nem fordítja bele annak debug infoit, ha azok nincsenek referálva az adott projekten belül. Ez egy olyan optimalizáció, ami szerintem csak gondot okoz, előnye viszont semmi nincs, legalábbis én fordításbeli sebességkülönbséget nem tapasztaltam. Miután az összes visual studio-s kapcsolót végigböngésztem, a neten bukkantam némi háttér információra a dologgal kapcsolatban.

A megolás az, hogy a precompiled source (stdafx.cpp) fordítási beállításainál (Configuration Properties->C/C++->Command Line->Additional Options) kézzel be kell állítani egy plusz kapcsolót: /Ylsymbol, ahol symbol helyére tetszőleges dolgot írhatunk, szerintem érdemes a projekt nevét egyébként. Ez azt fogja eredményezni, hogy a precompiled header-be egy új szimbólum generálódik, amire minden egyes file ami ezzel fordul referál és így annak debug infoi nála is meg fognak jelenni.

A probléma feloldás egyszerű, kár hogy nincs rá külön kapcsoló a VS-ben és a neten is nehéz volt rábukkanni.

Referencia:
MSDN