[英]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.