98

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

4

7 回答 7

61

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


#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 的一个问候世界(请参阅下面的链接)。首先,我使用-Hgcc 中的选项进行编译。它显示了它使用的大量标题列表。然后,我查看了我的 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并得到了这个输出:

g++ -Wall -fexceptions -H -g -c main.cpp -o obj/Debug/main.o
!/usr/local/include/boost/xpressive/xpressive.hpp.gch
主文件
. /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
主文件

这 !意味着编译器能够使用预编译的头文件。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我无法让它在邮政。

顺便说一句:我正在使用以下 g++

g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3

于 2010-05-29T14:59:42.410 回答
56

首先,请参阅此处的文档

您像任何其他文件一样编译头文件,但您将输出放在后缀为.gch.

stdafx.h.gch因此,例如,如果您预编译 stdafx.h,您将拥有一个预编译的标头,只要您包含该标头,就会自动搜索该标头stdafx.h

例子:

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,您的编译也将正常工作。

于 2009-07-28T00:52:58.353 回答
9

调用 gcc 的方式与为源文件调用它的方式相同,但使用头文件。

例如

g++ $(CPPFLAGS) test.h

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

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

更多信息可以在GCC Precompiled Headers下找到

于 2008-09-13T14:49:55.883 回答
9

-xC++ 预编译头文件的说明符是-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

于 2012-05-25T14:25:31.973 回答
8

过去我曾经设法让预编译的头文件在 gcc 下工作,我记得当时也有问题。要记住的是,如果不满足某些条件,gcc 将忽略文件(header.h.gch 或类似文件),可以在gcc 预编译头文件页面上找到其列表。

通常,最安全的做法是让您的构建系统首先编译 .gch 文件,使用与源代码的其余部分相同的命令行选项和可执行文件。这可以确保文件是最新的并且没有细微的差异。

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

于 2008-09-12T13:40:00.600 回答
3

确保-include your_header.h

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

代码

#include <bits/stdc++.h>

然后我通过使用 -H 编译我的文件并查看输出来找到 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归档而不是归档.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
....
于 2020-03-06T21:14:48.297 回答
0

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

precomp.h => 预压缩。h.gch

不是:

precomp.h => 预压缩。gch

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

于 2021-01-15T05:11:32.470 回答