簡體   English   中英

帶有 GCC 的預編譯頭文件

[英]Precompiled headers with GCC

任何人都成功獲得與 GCC 一起使用的預編譯頭文件? 我的嘗試沒有運氣,也沒有看到很多關於如何設置它的好例子。 我已經嘗試過 cygwin gcc 3.4.4 並在 Ubuntu 上使用 4.0。

我肯定取得了成功。 首先,我使用了以下代碼:


#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 的一個問候世界(請參閱下面的鏈接)。 首先,我在 gcc 中使用-H選項進行編譯。 它顯示了它使用的大量標題列表。 然后,我查看了我的 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再次編譯了原始代碼,得到了這個 output:

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

這。 意味着編譯器能夠使用預編譯的 header。 x 表示它無法使用它。 使用適當的編譯器標志至關重要。 我取下 -H 並進行了一些速度測試。 預編譯的 header 從 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

首先,請參閱此處的文檔

您像任何其他文件一樣編譯頭文件,但您將 output 放在后綴為.gch的文件中。

因此,例如,如果您預編譯 stdafx.h,您將擁有一個預編譯的 header,只要您包含stdafx.h ,就會自動搜索名為stdafx.h.gch

例子:

stdafx.h:

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

一個.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,您的編譯也將正常工作。

過去我曾設法讓預編譯的頭文件在 gcc 下工作,我記得當時也有問題。 需要記住的是,如果不滿足某些條件,gcc 將忽略文件(header.h.gch 或類似文件),可以在gcc 預編譯文檔頁面上找到其列表 Z099FB995346F31C7549F6E40DEDB0Z3

通常,最安全的做法是讓您的構建系統首先編譯 .gch 文件,使用與源代碼的 rest 相同的命令行選項和可執行文件。 這可以確保文件是最新的並且沒有細微的差異。

首先讓它與一個人為的示例一起工作可能也是一個好主意,只是為了消除您的問題特定於項目中的源代碼的可能性。

調用 gcc 的方式與為源文件調用它的方式相同,但使用 header 文件。

例如

g++ $(CPPFLAGS) test.h

這會生成一個名為 test.h.gch 的文件

每次 gcc 搜索 test.h 時,它都會首先查找 test.h.gch,如果找到它會自動使用它。

更多信息可以在GCC 預編譯頭文件下找到

C++ 預編譯頭文件的-x說明符是-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所在的目錄執行上述命令。

確保-include your_header.h

這就是我預編譯和使用bits/stdc++.h集合的方式。

代碼

#include <bits/stdc++.h>

然后我通過使用 -H 編譯我的文件並查看 output 來找到 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文件而不是帶有-include bits/stdc++.h.h這對我來說很關鍵。 要記住的另一件事是,您必須使用與編譯*.cpp幾乎相同的參數來編譯*.h header 文件。 當我沒有包含-O3-pthread時,它忽略了*.gch預編譯的 header。

要檢查一切是否正確,您可以通過比較結果來測量時差

time g++ sol.cpp ...

或運行

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

再次尋找 header 路徑,如果你現在得到! 例如,在庫路徑之前

! ./bits/stdc++.h.gch
....

關於文件擴展名的一個微妙提示讓我感到困惑,因為我沒有給予足夠的關注: .gch擴展名被添加到預編譯文件的全名中,它不會替換.h 如果你弄錯了,編譯器將找不到它並且默默地不起作用。

precomp.h => 預壓縮。 h.gch

不是:

precomp.h => 預壓縮。 gch

使用 gcc -H檢查它是否正在查找/使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM