带有GCC的预编译头文件

时间:2008-09-12 12:42:58

标签: c++ gcc precompiled-headers

任何人都有成功获得与GCC一起使用的预编译头文件吗?我的尝试没有运气,我没有看到很多关于如何设置它的好例子。我已经尝试过cygwin gcc 3.4.4并在Ubuntu上使用4.0。

7 个答案:

答案 0 :(得分: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的一个问候世界(见下面的链接)。首先,我使用gcc中的-H选项进行编译。它显示了它使用的大量标题列表。然后,我查看了我的IDE(代码::块)正在生成的编译标志,并看到类似这样的内容:

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

!意味着编译器能够使用预编译的头。 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我无法在帖子中使用它。

BTW:我正在使用以下g ++

g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3

答案 1 :(得分:51)

Firstly, see the documentation here

您可以像编辑任何其他文件一样编译标题,但是将输出放在后缀为.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,您的编辑也会有效。

答案 2 :(得分:8)

用于生成pch而不是使用-x c++使用-x c++-header

pch.h:

<put your common include files here>

pch.cpp:

#include "pch.h"

生成PCH:

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

pch.h.gch必须与pch.h在同一目录中!

答案 3 :(得分:6)

我过去曾设法在gcc下使用预编译的头文件,我还记得有问题。要记住的是,如果不满足某些条件,gcc将忽略该文件(header.h.gch或类似文件),其列表可在gcc precompiled header documentation page上找到。

通常,最安全的做法是让构建系统将.gch文件编译为第一步,使用相同的命令行选项并将其作为源的其余部分执行。这可确保文件是最新的,并且没有细微差别。

首先让它与一个人为的例子一起工作可能也是一个好主意,只是为了消除你的问题特定于项目源代码的可能性。

答案 4 :(得分:6)

以您为源文件调用gcc的方式调用gcc,但使用头文件。

e.g。

g++ $(CPPFLAGS) test.h

这会生成一个名为test.h.gch的文件

每次gcc搜索test.h时,它首先查找test.h.gch,如果找到它则会自动使用它。

可以在GCC Precompiled Headers

下找到更多信息

答案 5 :(得分:1)

请确保-include your_header.h

这就是我预编译和使用bits/stdc++.h集合的方式。

代码

#include <bits/stdc++.h>

然后我通过使用-H编译文件并查看输出来定位该库

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

答案 6 :(得分:0)

一个关于文件扩展名的微妙提示,因为我没有给予足够的关注而让我感到困惑:.gch 扩展名被添加到预编译文件的全名中,它不会替换 .h .如果你弄错了,编译器就找不到它,默默地不工作。

precomp.h => precomp.h.gch

不是:

precomp.h => precomp.gch

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