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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:32:28  来源:igfitidea点击:

Precompiled headers with GCC

c++gccprecompiled-headers

提问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 -Hoption 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(链接见下文)。首先,我用-Hgcc 中的选项编译。它显示了它使用的大量标题列表。然后,我查看了我的 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 -Hand 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.gchanytime 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 -xspecifier for C++ precompiled headers is -x c++-header, not -x c++. Example usage of PCH follows.

-xC++ 预编译头文件的说明符是-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.gchmust be in the same directory as the pch.hin order to be used, so make sure that you execute the above command from the directory where pch.his.

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++.hcollection.

这就是我预编译和使用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 bitsinside of current one and copied stdc++.hfrom 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 .gchfile instead of .hwith -include bits/stdc++.hThat was key for me. Other thing to keep in mind is that you have to compile *.hheader file with almost the same parameters as you compile your *.cpp. When I didn't include -O3or -pthreadit ignored the *.gchprecompiled header.

因为它只解决了.gch归档而不是.hwith-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
....