Czy ktoś odniósł sukces w uzyskaniu prekompilowanych nagłówków przy współpracy z GCC? Nie miałem szczęścia w moich próbach i nie widziałem wielu dobrych przykładów, jak to skonfigurować. Próbowałem na cygwin gcc 3.4.4 i używam 4.0 na Ubuntu.
c++
gcc
precompiled-headers
Lee Baldwin
źródło
źródło
Odpowiedzi:
Zdecydowanie odniosłem sukces. Najpierw użyłem następującego kodu:
#include <boost/xpressive/xpressive.hpp> #include <iostream> using namespace std; using namespace boost::xpressive; //A simple regex test int main() { std::string hello( "hello world!" ); sregex rex = sregex::compile( "(\\w+) (\\w+)!" ); smatch what; if( regex_match( hello, what, rex ) ) { std::cout << what[0] << '\n'; // whole match std::cout << what[1] << '\n'; // first capture std::cout << what[2] << '\n'; // second capture } return 0; }
To był po prostu świat powitania Boost Xpressive (link poniżej). Najpierw skompilowałem z
-H
opcją w gcc. Pokazał ogromną listę używanych przez siebie nagłówków. Następnie przyjrzałem się flagom kompilacji, które tworzyło moje IDE (code :: blocks) i zobaczyłem coś takiego:g++ -Wall -fexceptions -g -c main.cpp -o obj/Debug/main.o
Napisałem więc polecenie skompilowania pliku Xpressive.hpp z dokładnie tymi samymi flagami:
sudo g++ -Wall -fexceptions -g /usr/local/include/boost/xpressive/xpressive.hpp
Ponownie skompilowałem oryginalny kod
-H
i otrzymałem następujące dane wyjściowe:The! oznacza, że kompilator mógł użyć prekompilowanego nagłówka. Znak x oznacza, że nie mógł go użyć. Używanie odpowiednich flag kompilatora jest kluczowe. Zdjąłem -H i przeprowadziłem kilka testów szybkości. Wstępnie skompilowany nagłówek miał poprawę z 14 do 11 sekund. Nieźle, ale nie świetnie.
Uwaga: Oto link do przykładu: http://www.boost.org/doc/libs/1_43_0/doc/html/xpressive/user_s_guide.html#boost_xpressive.user_s_guide.examples Nie udało mi się go uruchomić w Poczta.
BTW: używam następującego g ++
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
źródło
-Winvalid-pch
aby upewnić się, że prekompilowany nagłówek jest prawidłowo używany? Zauważamy dużą poprawę w używaniu pch do naszych kompilacji debugowania, więc zastanawiam się, czy jest problem z twoją konfiguracją.Po pierwsze, zapoznaj się z dokumentacją tutaj .
Kompilujesz nagłówki jak każdy inny plik, ale umieszczasz wynik wewnątrz pliku z przyrostkiem
.gch
.Na przykład, jeśli prekompilujesz stdafx.h, będziesz miał prekompilowany nagłówek, który będzie automatycznie wyszukiwany za
stdafx.h.gch
każdym razem, gdy dołączyszstdafx.h
Przykład:
stdafx.h:
#include <string> #include <stdio.h>
a.cpp:
#include "stdafx.h" int main(int argc, char**argv) { std::string s = "Hi"; return 0; }
Następnie skompiluj jako:
Twoja kompilacja będzie działać, nawet jeśli usuniesz stdafx.h po kroku 1.
źródło
Specyfikatorem
-x
prekompilowanych nagłówków C ++-x c++-header
nie jest-x c++
. Poniżej przedstawiono przykładowe użycie PCH.pch.h
:// Put your common include files here: Boost, STL as well as your project's headers.
main.cpp
:#include "pch.h" // Use the PCH here.
Wygeneruj PCH w ten sposób:
pch.h.gch
Musi być w tym samym katalogu copch.h
żeby być używany, więc upewnij się, że wykonanie powyższego polecenia z katalogu, w którympch.h
jest.źródło
-c pch.h
, nie-c pch.cpp
?W przeszłości udało mi się uzyskać prekompilowane nagłówki działające pod gcc i pamiętam, że wtedy też miałem problemy. Należy pamiętać, że gcc zignoruje plik (header.h.gch lub podobny), jeśli nie zostaną spełnione określone warunki, których listę można znaleźć na stronie dokumentacji prekompilowanego nagłówka gcc .
Ogólnie najbezpieczniej jest, aby system kompilacji kompilował plik .gch jako pierwszy krok, z tymi samymi opcjami wiersza poleceń i plikiem wykonywalnym, co reszta źródła. Dzięki temu plik jest aktualny i nie ma żadnych subtelnych różnic.
Prawdopodobnie dobrym pomysłem jest również uruchomienie go najpierw z wymyślonym przykładem, aby usunąć możliwość, że twoje problemy są specyficzne dla kodu źródłowego w twoim projekcie.
źródło
Wywołaj gcc tak samo, jak wywołujesz go dla pliku źródłowego, ale z plikiem nagłówkowym.
na przykład
generuje to plik o nazwie test.h.gch
Za każdym razem, gdy gcc szuka test.h, najpierw szuka test.h.gch i jeśli je znajdzie, używa go automatycznie.
Więcej informacji można znaleźć w sekcji Prekompilowane nagłówki GCC
źródło
Upewnij się
-include your_header.h
W ten sposób wstępnie skompilowałem i użyłem
bits/stdc++.h
kolekcji.Kod
#include <bits/stdc++.h>
Następnie zlokalizowałem bibliotekę, kompilując mój plik z -H i patrząc na wyjście
g++ sol.cpp -H -O3 -pthread -lm -std=c++14 -o executable
gdzie widziałem
. /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h
Więc utworzyłem nowy katalog
bits
wewnątrz obecnego i skopiowałemstdc++.h
stamtąd.Potem uciekłem
g++ bits/stdc++.h -O3 -std=c++14 -pthread
który wygenerował
bits/stdc++.gch
Zwykle skompilowałem swój kod za pośrednictwem
g++ sol.cpp -O3 -pthread -lm -std=c++14 -o executable
, ale musiałem to zmienić na
g++ sol.cpp -include bits/stdc++.h -O3 -pthread -lm -std=c++14 -o executable
ponieważ zdecydowano się tylko
.gch
złożyć plik zamiast.h
z-include bits/stdc++.h
To było dla mnie kluczowe. Inną rzeczą, o której musisz pamiętać, jest to, że musisz skompilować*.h
plik nagłówkowy z prawie takimi samymi parametrami, jak kompilujesz plik*.cpp
. Kiedy nie uwzględniłem-O3
lub-pthread
zignorowałem*.gch
prekompilowany nagłówek.Aby sprawdzić, czy wszystko jest w porządku, możesz zmierzyć różnicę czasu, porównując wynik
time g++ sol.cpp ...
lub biegnij
g++ sol.cpp -H -O3 -pthread -lm -std=c++14 -o executable
ponownie i poszukaj ścieżek nagłówka, a jeśli masz teraz
!
na przykład ścieżkę do bibliotekiźródło