C++ 使用 GCC 预编译头文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/58841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Precompiled headers with GCC
提问by Lee Baldwin
Anyone had any success getting precompiled headers working with GCC? I have had no luck in my attempts and I haven't seen many good examples for how to set it up. I've tried on cygwin gcc 3.4.4 and using 4.0 on Ubuntu.
任何人都成功地获得了与 GCC 一起使用的预编译头文件?我的尝试没有运气,我没有看到很多关于如何设置它的好例子。我试过 cygwin gcc 3.4.4 并在 Ubuntu 上使用 4.0。
回答by User1
I have definitely had success. First, I used the following code:
我肯定取得了成功。首先,我使用了以下代码:
#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;
}
This was just a hello world from Boost Xpressive (see below for link). First, I compiled with the -H
option in gcc. It showed an enormous list of headers that it used. Then, I took a look at the compile flags my IDE (code::blocks) was producing and saw something like this:
这只是 Boost Xpressive 的一个 hello world(链接见下文)。首先,我用-H
gcc 中的选项编译。它显示了它使用的大量标题列表。然后,我查看了我的 IDE (code::blocks) 生成的编译标志,看到了如下内容:
g++ -Wall -fexceptions -g -c main.cpp -o obj/Debug/main.o
g++ -Wall -fexceptions -g -c main.cpp -o obj/Debug/main.o
So I wrote a command to compile the Xpressive.hpp file with the exact same flags:
所以我写了一个命令来编译具有完全相同标志的 Xpressive.hpp 文件:
sudo g++ -Wall -fexceptions -g /usr/local/include/boost/xpressive/xpressive.hpp
sudo g++ -Wall -fexceptions -g /usr/local/include/boost/xpressive/xpressive.hpp
I compiled the original code again with the -H
and got this output:
我用 再次编译了原始代码-H
并得到了这个输出:
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
The ! means that the compiler was able to use the precompiled header. An x means it was not able to use it. Using the appropriate compiler flags is crucial. I took off the -H and ran some speed tests. The precompiled header had an improvement from 14 seconds to 11 seconds. Not bad but not great.
这 !意味着编译器能够使用预编译的头文件。x 表示它无法使用它。使用适当的编译器标志至关重要。我取下 -H 并进行了一些速度测试。预编译的头文件从 14 秒改进到 11 秒。不错,但不是很好。
Note: Here's the link to the example: http://www.boost.org/doc/libs/1_43_0/doc/html/xpressive/user_s_guide.html#boost_xpressive.user_s_guide.examplesI couldn't get it to work in the post.
注意:这是示例的链接:http: //www.boost.org/doc/libs/1_43_0/doc/html/xpressive/user_s_guide.html#boost_xpressive.user_s_guide.examples我无法让它在邮政。
BTW: I'm using the following g++
顺便说一句:我正在使用以下 g++
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
回答by Brian R. Bondy
Firstly, see the documentation here.
You compile headers just like any other file but you put the output inside a file with a suffix of .gch
.
您可以像编译任何其他文件一样编译头文件,但将输出放在后缀为.gch
.
So for example if you precompile stdafx.h you will have a precompiled header that will be automatically searched for called stdafx.h.gch
anytime you include stdafx.h
因此,例如,如果您预编译 stdafx.h,您将有一个预编译的头文件,该头文件将在stdafx.h.gch
您包含的任何时候自动搜索调用stdafx.h
Example:
例子:
stdafx.h:
stdafx.h:
#include <string>
#include <stdio.h>
a.cpp:
a.cpp:
#include "stdafx.h"
int main(int argc, char**argv)
{
std::string s = "Hi";
return 0;
}
Then compile as:
然后编译为:
> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out
> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out
Your compilation will work even if you remove stdafx.h after step 1.
即使您在第 1 步之后删除 stdafx.h,您的编译也能正常工作。
回答by psaghelyi
The -x
specifier for C++ precompiled headers is -x c++-header
, not -x c++
. Example usage of PCH follows.
-x
C++ 预编译头文件的说明符是-x c++-header
,而不是-x c++
。PCH 的示例用法如下。
pch.h
:
pch.h
:
// Put your common include files here: Boost, STL as well as your project's headers.
main.cpp
:
main.cpp
:
#include "pch.h"
// Use the PCH here.
Generate the PCH like this:
像这样生成 PCH:
$ g++ -x c++-header -o pch.h.gch -c pch.h
The pch.h.gch
must be in the same directory as the pch.h
in order to be used, so make sure that you execute the above command from the directory where pch.h
is.
Thepch.h.gch
必须与 the 位于同一目录pch.h
中才能使用,因此请确保从 where 目录执行上述命令pch.h
。
回答by Paul
I have managed to get precompiled headers working under gcc once in the past, and I recall having problems then as well. The thing to remember is that gcc will ignore the file (header.h.gch or similar) if certain conditions are not met, a list of which can be found on the gcc precompiled header documentation page.
过去我曾经设法让预编译的头文件在 gcc 下工作,我记得当时也遇到了问题。要记住的是,如果不满足某些条件,gcc 将忽略该文件(header.h.gch 或类似文件),其列表可以在gcc 预编译头文件文档页面上找到。
Generally it's safest to have your build system compile the .gch file as a first step, with the same command line options and executable as the rest of your source. This ensures the file is up to date and that there are no subtle differences.
通常,最安全的做法是让您的构建系统首先编译 .gch 文件,并使用与其余源代码相同的命令行选项和可执行文件。这可以确保文件是最新的并且没有细微的差异。
It's probably also a good idea to get it working with a contrived example first, just to remove the possibility that your problems are specific to source code in your project.
先用一个人为的例子来处理它可能也是一个好主意,只是为了消除您的问题特定于您项目中的源代码的可能性。
回答by simon
Call gcc same way as you call it for your source file but with a header file.
调用 gcc 的方式与为源文件调用 gcc 的方式相同,但使用头文件。
e.g.
例如
g++ $(CPPFLAGS) test.h
this generates a file called test.h.gch
这会生成一个名为 test.h.gch 的文件
Every time gcc searches for test.h it look first for test.h.gch and if it finds it it uses it automatically.
每次 gcc 搜索 test.h 时,它首先查找 test.h.gch,如果找到它,它会自动使用它。
More information can be found under GCC Precompiled Headers
更多信息可以在GCC 预编译头文件下找到
回答by íhor Mé
Make sure to -include your_header.h
确保 -include your_header.h
This is how I precompiled and used bits/stdc++.h
collection.
这就是我预编译和使用bits/stdc++.h
集合的方式。
Code
代码
#include <bits/stdc++.h>
Then I located the lib by compiling my file with -H and looking at output
然后我通过使用 -H 编译我的文件并查看输出来找到 lib
g++ sol.cpp -H -O3 -pthread -lm -std=c++14 -o executable
where I saw
我看到的地方
. /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h
So I made a new directory bits
inside of current one and copied stdc++.h
from there.
所以我bits
在当前目录中创建了一个新目录并stdc++.h
从那里复制。
Then I ran
然后我跑了
g++ bits/stdc++.h -O3 -std=c++14 -pthread
which generated bits/stdc++.gch
其中产生 bits/stdc++.gch
Normally I compiled my code via
通常我通过编译我的代码
g++ sol.cpp -O3 -pthread -lm -std=c++14 -o executable
, but I had to modify that to
,但我不得不将其修改为
g++ sol.cpp -include bits/stdc++.h -O3 -pthread -lm -std=c++14 -o executable
as it only resolved to .gch
file instead of .h
with -include bits/stdc++.h
That was key for me. Other thing to keep in mind is that you have to compile *.h
header file with almost the same parameters as you compile your *.cpp
. When I didn't include -O3
or -pthread
it ignored the *.gch
precompiled header.
因为它只解决了.gch
归档而不是.h
with-include bits/stdc++.h
那对我来说很关键。要记住的另一件事是,您必须使用与编译*.h
.zip 文件几乎相同的参数来编译头文件*.cpp
。当我没有包含-O3
或-pthread
忽略*.gch
预编译头时。
To check if everything's correct you can measure time difference via comparing result of
要检查一切是否正确,您可以通过比较结果来测量时间差
time g++ sol.cpp ...
or run
或运行
g++ sol.cpp -H -O3 -pthread -lm -std=c++14 -o executable
again and look for header paths and if you now get !
before library path, for example
再次查找标题路径,如果您现在!
在库路径之前获得,例如
! ./bits/stdc++.h.gch
....