Zysk jest całkiem spory, różnica 36 sekund, czyli około 20 %.
A teraz jak uzyskać pre kompilowane nagłówki pod Eclipsem ?
Eclispe z CDT nie posiada narzędzi do obsługi tej techniki, więc zapomnijcie o magicznym przełączniku. Wszystko trzeba zrobić samemu.
Na szczęście GCC automatycznie wykorzystuje pch, o ile one istnieją. Sami budujemy nagłówek i umieszczamy pch w odpowiednim miejscu, a kompilator go znajdzie i wykorzysta.
Jak zrobić nagłówek?
Tworzymy zwykły plik .h i włączamy w nim wszystkie potrzebne pliki nagłówkowe.
Przykład:
#ifndef STD_H_
#define STD_H_
#include <string>
#include <fstream>
#include <sstream>
#include <map>
#include <deque>
#include <vector>
#endif /* STD_H_ */
Jak zbudować nagłówek ?
Do zbudowania nagłówka wywołujemy z linii komend "g++ -opcje -xc++-header -otest.h.gch test.h". W efekcie powinniśmy otrzymać plik test.h.gch.
- test.h to rzecz jasna nazwa pliku
- teoretycznie flaga -x nie jest potrzebna, bo gcc zna rozszerzenie .h, ale jakoś nie za bardzo bez niej chciało działać
- opcje powinny być takie same jak projektu korzystającego z nagłówka
Jak z nagłówka skorzystać ?
- pch zostanie wykorzystany automatycznie
- gcc wykorzysta ten plik, który znajdzie pierwszy, przy czym najpierw sprawdza czy w danym katalogu jest pch, dopiero potem czy jest zwykły plik. Najprościej oba pliki umieścić w tym samym katalogu
- projekt powinien mieć te same opcje co pch
- pch może być tylko jeden na raz
Co zrobić z błędem "calling fdopen: Bad file descriptor" ?
Pch może zostać użyte tylko raz podczas kompilacji. Jeżeli mamy sytuację w której plik pch zostanie włączony dwa razy, zobaczymy taki właśnie błąd. Przykładowo mamy:
foo.h włącza "std.h"
bar.h włącza "std.h"
foobar.cpp włącza "foo.h" i "bar.h"
Nie wiem jak to rozwiązują inni, ja po prostu opatrzyłem dyrektywę strażnikiem:
//Precompiled header
#ifndef STD_H_
#include "std.h"
#endif
Warto przeczytać: gcc/Precompiled-Headers
6 komentarzy:
Hah, cieekawe. Nie wiedziałem że GCC ma PCH ;> Thx za wpis ;>
Wow, pierwszy komentarz. Chyba opatrzę go w ramkę ;)
Pozdrawiam.
Nie jest prawidłowe włączanie prekompilowanego headera do plików nagłówkowych.
Powinien on się znaleźć na samym początku plików cpp - eliminuje to problem: "calling fdopen: Bad file descriptor" i jemu podobne.
Szczerze mówiąc sam popełniłem taki błąd.
Tylko potem trzeba w pliku .h deklarować:
namespace std {
class string;
class vector;
}
Zaraz, przecież to są template'y. ZARAZA, czy tak w ogóle można zrobić ?? Chyba jednak nie, trzeba teraz poszukać definicji klasy vector i przepisać co do literki. Przepisujemy, kompilujemy i sypią się błędy.
Co z tym fantem zrobić ?
Pytam poważnie, bo generalnie to się z Tobą zgadzam. Im mniejszy header tym lepiej.
Nie musisz pisać:
namespace std
{
class string;
class vector;
}
Rozważmy sytuację, gdy mamy klasę Foo w plikach foo.h i foo.cpp oraz, że klasa ta korzysta z klasy vector oraz prekompilowany header std.h (zakładamy, że std.h zawiera #include vector):
foo.h:
------
#ifndef FOO_H_
#define FOO_H_
class Foo
{
std::vector a;
}
#endif
foo.cpp:
-------
#include "std.h" //zawsze na początku
#include "foo.h"
Dzięki temu podczas kompilacji (kompilowane są pliki cpp, headery są tylko włączane) przed deklaracją klasy Foo znajdzie się dyrektywa #include vector (vector powinno być w nawiasach <>, ale edytor mi krzyczy)
I jeszcze jedna ważna kwestia, każdy plik cpp powinien się zaczynać od #include "std.h", bo jeżeli nawet ten plik cpp nie korzysta z czegokolwiek z std.h, to może inkludować np. foo.h, która już korzysta.
pzdr
raffimoni, wcześniej anonimowy
Chyba kiepski ze mnie blogger, nawet się nie zorientowałem, że ktoś mi zostawił komentarz :)
Rozwiązanie wydaje się rozsądne. Przetestuje i powiem co o tym myślę.
Prześlij komentarz