GCC ile önceden derlenmiş başlıklar


91

GCC ile çalışan önceden derlenmiş başlıkları elde eden herhangi bir başarı elde eden var mı? Girişimlerimde hiç şansım olmadı ve nasıl kurulacağına dair pek çok iyi örnek görmedim. Cygwin gcc 3.4.4 üzerinde ve Ubuntu üzerinde 4.0 kullanmayı denedim.


Bunu denedim ve önceden derlenmiş üstbilgiler için optimum kullanım durumu elde ettim çünkü c kaynağım derleyici oluşturuldu ve kullanıcı tarafından yazılmadı. Sun Studio ve özellikle Visual Studio, derleme süresini çok geliştirdi. Gcc'de önceden derlenmiş başlıklar olmadan daha da kötüye gidiyordu. Bu, 3.4 ile 4.x ile test etmedi, ancak hız ve gcc birbirini dışlıyor.
Lothar

@Lothar kodu neydi? G ++ 'ı son zamanlarda kullanılan Visual Studio derleyicilerinden yaklaşık 10 kat daha hızlı buluyorum, bazı ağır şablonlara sahip kodlarda.
domuz

C ++ kodumda şablon kullanmıyorum. Sadece C + istisna işleme + güzel C ++ uzantıları. Bu sorudan 6 yıl sonra bile VS2010 çok daha hızlı. Ama bu arada 16 çekirdeğim var, böylece onunla yaşayabilirim.
Lothar

Yanıtlar:


59

Kesinlikle başarılı oldum. İlk önce aşağıdaki kodu kullandım:


#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;
}

Bu, Boost Xpressive'den sadece merhaba bir dünyaydı (bağlantı için aşağıya bakın). Öncelikle -Hgcc'deki seçenekle derledim . Kullandığı muazzam bir başlık listesi gösterdi. Sonra, IDE'min (kod :: blokları) ürettiği derleme bayraklarına bir göz attım ve şöyle bir şey gördüm:

g++ -Wall -fexceptions -g -c main.cpp -o obj/Debug/main.o

Bu yüzden Xpressive.hpp dosyasını aynı bayraklarla derlemek için bir komut yazdım:

sudo g++ -Wall -fexceptions -g /usr/local/include/boost/xpressive/xpressive.hpp

Orijinal kodu ile tekrar derledim -Hve şu çıktıyı aldım:

g ++ -Wall -fexceptions -H -g -c main.cpp -o obj / Debug / main.o
! /usr/local/include/boost/xpressive/xpressive.hpp.gch
main.cpp
. /usr/include/c++/4.4/iostream
.. /usr/include/c++/4.4/x86_64-linux-gnu/bits/c++config.h
.. /usr/include/c++/4.4/ostream
.. /usr/include/c++/4.4/istream
main.cpp

! derleyicinin önceden derlenmiş başlığı kullanabildiği anlamına gelir. Bir x, onu kullanamadığı anlamına gelir. Uygun derleyici bayraklarını kullanmak çok önemlidir. -H'yi çıkardım ve bazı hız testleri yaptım. Önceden derlenmiş başlık 14 saniyeden 11 saniyeye çıktı. Fena değil ama harika değil.

Not: Burada örnek bağlantısı şudur: http://www.boost.org/doc/libs/1_43_0/doc/html/xpressive/user_s_guide.html#boost_xpressive.user_s_guide.examples Ben iş için alamadım İleti.

BTW: Şu g ++ kullanıyorum

g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3


20
-Winvalid-pch eklenmesi, PCH'nin kullanımında herhangi bir şeyin yanlış gidip gitmediğini ve neden hata ayıklamanıza yardımcı olacaktır.
lefticus

"fena değil ama harika değil" önceden derlenmiş başlıklar, birbirini yeniden bağlayan çok sayıda başlığa sahip olduğunuzda kullanışlıdır, bu nedenle büyük kitaplıklar veya çok sayıda kitaplık kullanan çok büyük projelerde derleme süresini kısaltacaktır.
jokoon

4
"fena değil ama harika değil": gcc 4.4.7, 136 .cpp dosyaları 35.5 Mb toplam boyut, 148 .h dosya 5.5 Mb toplam boyut, .gch dosyası 48 Mb, Debug oluşturma 2'20 "(vs 2 '14 "pch olmayan), -O2 optimize edilmiş derleme 4'30" alır (5'33 "pch olmayanlara karşı) Etkisi, hata ayıklama derlemelerinin yakınında beklenir, ancak ön derlemeden kazanç sağlayan yalnızca optimize edilmiş derlemedir .... Emin değilim neden. Ön derleme, Windows'ta çok daha dramatiktir!
Andreas Vergison

1
(devamı) İlgili pch / pch olmayan çıktı dosyaları tam olarak aynı bayt boyutuna sahip, bu iyi. Yukarıdaki zamanlamalar, derlemeleri tekrarlarken değişiyor gibi görünüyor, örneğin -O2 non-pch 3'45 "ve 5'33" arasında değişiyor, bu yüzden belki de VMware'de çalıştığı için kesin bir bilim değil. Her neyse, gcc pch benim durumumda hiç faydalı görünmüyor. Bunu Windows VS2012'deki aynı kod tabanıyla karşılaştırın (x64, tek iş parçacıklı derleme): hata ayıklama 46 "pch, 2'50" non-pch, sürüm 2'13 "pch, 5'02" non-pch. Ve elbette çoklu işlemciyi etkinleştirirken çok daha hızlı ...
Andreas Vergison

@AndreasVergison - -Winvalid-pchÖnceden derlenmiş üstbilginin düzgün şekilde kullanıldığından emin olmak için kullanmayı denediniz mi? Hata ayıklama yapılarımız için pch kullanımında büyük bir gelişme olduğunu fark ettik, bu yüzden kurulumunuzda bir sorun olup olmadığını merak ediyorum.
Josh Kelley

52

Öncelikle buradaki belgelere bakın .

Başlıkları tıpkı diğer dosyalar gibi derlersiniz, ancak çıktıyı bir dosyanın içine koyarsınız .gch.

Örneğin, stdafx.h dosyasını önceden derlerseniz, her eklediğinizde çağrılmak üzere otomatik olarak aranacak önceden derlenmiş bir başlığa sahip stdafx.h.gcholursunuz.stdafx.h

Misal:

stdafx.h:

#include <string>
#include <stdio.h>

a.cpp:

#include "stdafx.h"
int main(int argc, char**argv)
{
  std::string s = "Hi";
  return 0;
}

Ardından şu şekilde derleyin:

> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out

1. adımdan sonra stdafx.h dosyasını kaldırsanız bile derlemeniz çalışacaktır.


8

-xC ++ için belirteci başlıkları olduğunu precompiled -x c++-headerdeğil -x c++. PCH'nin örnek kullanımı aşağıdadır.

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.

PCH'yi şu şekilde oluşturun:

$ g++ -x c++-header -o pch.h.gch -c pch.h

, Kullanılabilmesi pch.h.gchiçin ile aynı dizinde olmalıdır pch.h, bu nedenle yukarıdaki komutu olduğu dizinden çalıştırdığınızdan emin olun pch.h.


3
Bu olmalı -c pch.h, değil -c pch.cppmi?
MM

7

Geçmişte bir kez gcc altında çalışan önceden derlenmiş başlıkları almayı başardım ve o zamanlar da sorun yaşadığımı hatırlıyorum. Unutulmaması gereken şey, gcc'nin belirli koşullar yerine getirilmediği takdirde dosyayı (header.h.gch veya benzeri) yok sayacağıdır, bunların bir listesi gcc önceden derlenmiş başlık dokümantasyon sayfasında bulunabilir .

Genellikle, derleme sisteminizin .gch dosyasını ilk adım olarak, aynı komut satırı seçenekleriyle ve kaynağınızın geri kalanıyla çalıştırılabilir şekilde derlemesini sağlamak en güvenlisidir. Bu, dosyanın güncel olmasını ve küçük farklar olmamasını sağlar.

Problemlerinizin projenizdeki kaynak koda özgü olma olasılığını ortadan kaldırmak için, ilk önce bunun uydurulmuş bir örnekle çalışmasını sağlamak muhtemelen iyi bir fikirdir.


7

Gcc'yi kaynak dosyanız için çağırdığınız şekilde, ancak bir başlık dosyasıyla çağırın.

Örneğin

g++ $(CPPFLAGS) test.h

bu, test.h.gch adlı bir dosya oluşturur

Gcc test.h'yi her aradığında önce test.h.gch dosyasını arar ve bulursa otomatik olarak kullanır.

Daha fazla bilgi GCC Önceden Derlenmiş Başlıkları altında bulunabilir.


Gcc 3.4 kullanıyorum ve g ++ stdafx.h satırı derlenmeyecek, "g ++: istenen başlık dosyasının derlenmesi" hatası alıyorsunuz, ancak bu derlenecek, yine de istediğim şeyin bu olup olmadığından emin değilim: "g ++ -c -x c ++ stdafx.h -o stdafx.h.pch "
stefanB

1

Emin ol -include your_header.h

bits/stdc++.hKoleksiyonu böyle önceden derledim ve kullandım .

Kod

#include <bits/stdc++.h>

Sonra dosyamı -H ile derleyip çıktıya bakarak lib'yi buldum

g++ sol.cpp -H -O3 -pthread -lm -std=c++14 -o executable

nerede gördüm

. /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h

Bu yüzden bitsmevcut dizinin içinde yeni bir dizin oluşturdum ve stdc++.horadan kopyaladım .

Sonra koştum

g++ bits/stdc++.h -O3 -std=c++14  -pthread

hangi üretti bits/stdc++.gch

Normalde kodumu şu yolla derledim:

g++ sol.cpp -O3 -pthread -lm -std=c++14 -o executable

ama bunu değiştirmek zorunda kaldım

g++ sol.cpp -include bits/stdc++.h -O3 -pthread -lm -std=c++14 -o executable

sadece karar olarak .gchyerine dosyaya .hsahip -include bits/stdc++.h Bu benim için anahtar oldu. Akılda tutulması gereken diğer bir şey de *.hbaşlık dosyasını *.cpp. Önceden derlenmiş başlığı eklemediğimde -O3veya -pthreadyok *.gchsaydığımda.

Her şeyin doğru olup olmadığını kontrol etmek için, sonucunu karşılaştırarak zaman farkını ölçebilirsiniz.

time g++ sol.cpp ...

veya koş

g++ sol.cpp -H -O3 -pthread -lm -std=c++14 -o executable

tekrar ve başlık yollarını arayın ve şimdi !kitaplık yolundan önce gelirseniz , örneğin

! ./bits/stdc++.h.gch
....
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.