GCCでプリコンパイルされたヘッダー


91

誰もがGCCで動作するプリコンパイル済みヘッダーの取得に成功しましたか?私は私の試みで運がなかったし、それを設定する方法の多くの良い例を見たことがありません。私はcygwin gcc 3.4.4を試し、Ubuntuで4.0を使用しました。


私が試してみたところ、プリコンパイル済みヘッダーの最適な使用例がありました。私のcソースはコンパイラー生成であり、ユーザーが作成したものではないためです。Sun Studio、特にVisual Studioは、ビルド時間を大幅に改善しました。gccでは、プリコンパイル済みヘッダーがない場合よりもさらに悪化していました。これは3.4でのことで、4.xでテストされていませんが、速度とgccは相互に排他的です。
Lothar

@Lotharコードは何でしたか?一部の非常にテンプレート化されたコードでは、g ++は最近のVisual Studioコンパイラーよりも約10倍高速です。
2014年

C ++コードでテンプレートを使用していません。C +例外処理+素晴らしいC ++拡張です。この質問から6年経った今でも、VS2010ははるかに高速です。しかし、その間、私は16コアを持っているので、それと共存できます。
Lothar

回答:


58

私は間違いなく成功しました。まず、次のコードを使用しました。


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

これは、Boost XpressiveからのHello Worldにすぎません(リンクについては以下を参照)。まず、-Hgcc のオプションを使用してコンパイルしました。使用したヘッダーの膨大なリストが表示されました。次に、私のIDE(code :: blocks)が生成しているコンパイルフラグを見て、次のようなものを見ました。

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

そこで、まったく同じフラグを使用してXpressive.hppファイルをコンパイルするコマンドを作成しました。

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

で元のコードを再度コンパイルし、-H次の出力を取得しました。

g ++-壁-例外-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

!コンパイラがプリコンパイル済みヘッダーを使用できたことを意味します。xは、使用できなかったことを意味します。適切なコンパイラフラグを使用することが重要です。-Hを外して速度テストを実行しました。プリコンパイル済みヘッダーは14秒から11秒に改善されました。悪くはないが、素晴らしいとは言えない。

注:ここでは例へのリンクがあります: http://www.boost.org/doc/libs/1_43_0/doc/html/xpressive/user_s_guide.html#boost_xpressive.user_s_guide.examples私はそれで動作するように得ることができませんでした役職。

ところで、私は次のg ++​​を使用しています

g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3


20
-Winvalid-pchを追加すると、PCHの使用法で問題が発生した場合に、その理由をデバッグできます。
lefticus 2012年

「悪くないが、あまり良くない」プリコンパイル済みヘッダーは、相互に再リンクするヘッダーが多数ある場合に役立ちます。そのため、大きなライブラリまたは多くのライブラリを使用する非常に大きなプロジェクトでのコンパイル時間が短縮されます。
jokoon 2013

4
「悪くないが素晴らしい」:gcc 4.4.7、136の.cppファイルを使用して合計35.5 Mbのファイル、148の.hファイルを合計5.5 Mbのサイズ、.gchファイルは48 Mb、デバッグビルドは2'20 "(vs 2 '14 "non-pch)、-O2最適化ビルドには4'30"(vs 5'33 "non-pch)かかりますデバッグビルドの近くで効果が期待されますが、プリコンパイルから利益を得るのは最適化ビルドだけです...なぜだかわかりません。Windowsでは、プリコンパイルははるかに劇的です。
Andreas Vergison 14

1
(続き)対応するpch / pch以外の出力ファイルのバイトサイズはまったく同じです。上記のタイミングは、ビルドを繰り返すと変化するようです。たとえば、-O2 non-pchは3'45 "と5'33"の間で変化するため、おそらくVMwareで実行しているため、正確ではありません。とにかく、gcc pchは私の場合、まったく有益に見えません。Windows VS2012の同じコードベース(x64、シングルスレッドコンパイル)と比較してください。デバッグ46 "pch、2'50"非pch、リリース2'13 "pch、5'02"非pch。そしてもちろん、マルチプロセッサを有効にするとさらに高速になります...
Andreas Vergison

@AndreasVergison- -Winvalid-pchプリコンパイル済みヘッダーが適切に使用されていることを確認するために使用してみましたか?デバッグビルドにpchを使用することで大きな改善が見られたので、セットアップに問題があるのではないかと思います。
Josh Kelley 14

52

まず、こちらのドキュメントをご覧ください

ヘッダーは他のファイルと同じようにコンパイルしますが、出力をファイルのサフィックスが付いたファイル内に配置します.gch

したがって、たとえばstdafx.hをプリコンパイルした場合、プリコンパイル済みヘッダーがあり、これstdafx.h.gchを含めるといつでも自動的に呼び出されて呼び出されますstdafx.h

例:

stdafx.h:

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

a.cpp:

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

次に、次のようにコンパイルします。

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

手順1の後でstdafx.hを削除しても、コンパイルは機能します。


8

-xC ++のプリコンパイル済みヘッダーの指定子は-x c++-header、ではなく-x c++です。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.

次のようにPCHを生成します。

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

を使用pch.h.gchするには、がと同じディレクトリにある必要があるpch.hため、上記のコマンドをが存在するディレクトリから実行してくださいpch.h


3
これはそう-c pch.hであるべき-c pch.cppですか?
MM

7

過去に一度、gccでプリコンパイル済みヘッダーを機能させることができましたが、そのときに問題があったことも思い出します。覚えておくべきことは、特定の条件が満たされない場合、gccはファイル(header.h.gchまたは同様のもの)を無視するということです。そのリストは、gccプリコンパイル済みヘッダードキュメントページにあります

一般に、ビルドシステムで最初のステップとして.gchファイルをコンパイルするのが最も安全です。他のソースと同じコマンドラインオプションと実行可能ファイルを使用します。これにより、ファイルが最新であり、微妙な違いがないことが保証されます。

問題がプロジェクトのソースコードに固有である可能性を排除するために、最初に人為的な例を使用して動作させることもおそらく良い考えです。


7

ソースファイルに対して呼び出すのと同じ方法でgccを呼び出しますが、ヘッダーファイルを使用します。

例えば

g++ $(CPPFLAGS) test.h

これにより、test.h.gchというファイルが生成されます

gccはtest.hを検索するたびに、最初にtest.h.gchを探し、見つかった場合は自動的に使用します。

詳細については、GCCプリコンパイル済みヘッダーをご覧ください。


私はgcc 3.4を使用していますが、g ++ stdafx.hの行がコンパイルされず、「g ++:ヘッダーファイルのコンパイルが要求されました」というエラーが表示されますが、これはコンパイルされます。 c ++ stdafx.h -o stdafx.h.pch "
stefanB 2009年

0

必ず -include your_header.h

これは私がプリコンパイルして使用した方法です bits/stdc++.hコレクションです。

コード

#include <bits/stdc++.h>

次に、-Hを使用してファイルをコンパイルし、出力を確認して、libを見つけました

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

私が見たところ

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

そこでbits、現在のディレクトリ内に新しいディレクトリを作成しstdc++.h、そこからコピーしました。

それから私は走った

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

生成された bits/stdc++.gch

通常、私はコードをコンパイルしました

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

、しかし私はそれを

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

それは.gchファイルの代わりにファイルに解決されるだけだったので.h-include bits/stdc++.hそれは私にとって重要でした。覚えておくべき他のことはあなたがあなたのをコンパイルするの*.hとほとんど同じパラメータでヘッダファイルをコンパイルしなければならないということです*.cpp。含めなかった場合、-O3またはプリコンパイル済みヘッダーが-pthread無視された*.gch場合。

すべてが正しいかどうかを確認するには、結果を比較して時間差を測定できます

time g++ sol.cpp ...

または実行

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

もう一度、ヘッダーパスを探します。!たとえば、ライブラリパスの前にいる場合は、たとえば

! ./bits/stdc++.h.gch
....
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.