使用GCC先行编译信头

r1zhe5dt  于 2022-11-13  发布在  其他
关注(0)|答案(7)|浏览(169)

如何获得使用GCC的预编译头文件?
我的尝试没有什么运气,我也没有看到很多好的例子来说明如何设置它。我已经在Cygwin GCC 3.4.4上试过了,并在Ubuntu上使用了4.0。

vybvopom

vybvopom1#

首先,我使用了下面的代码:

#include <boost/xpressive/xpressive.hpp>
#include <iostream>

using namespace std;
using namespace boost::xpressive;

// A simple regular expression 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的 * Hello, World! * 程序。首先,我用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再次编译了原始代码,得到了以下输出:

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秒。不错,但不是很好。
注意:下面是一个例子。我无法让它在帖子中工作。
顺便说一句:我正在使用下面的 g++

g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
06odsfpq

06odsfpq2#

Firstly, see the documentation here
您可以像编译任何其他文件一样编译头文件,但是您将输出放在一个后缀为.gch的文件中。
因此,例如,如果预编译stdafx. h,则将有一个预编译头文件,只要包含stdafx.h,就会自动搜索该头文件,以查找名为stdafx.h.gch的内容
示例:
标准:

#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,您的编译仍会运作。

wmomyfyw

wmomyfyw3#

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所在的目录执行上述命令。

mzaanser

mzaanser4#

调用GCC的方式与为源文件调用GCC的方式相同,但要使用头文件。
例如:

g++ $(CPPFLAGS) test.h

这将生成一个名为 test.h.gch 的文件。
每次GCC搜索 test.h 时,它首先查找 test.h.gch,如果找到它,它会自动使用它。
更多信息可在GCC Precompiled Headers下找到。

qfe3c7zg

qfe3c7zg5#

我曾经设法让预编译的头文件在gcc下工作过一次,我记得当时也遇到过问题。要记住的是,如果不满足某些条件,gcc将忽略该文件(header.h.gch或类似文件),可以在gcc precompiled header documentation page上找到这些条件的列表。
通常最安全的做法是让构建系统首先编译.gch文件,使用与源代码其余部分相同的命令行选项和可执行文件。这可以确保文件是最新的,并且没有细微的差异。
首先让它使用一个人为的示例可能也是一个好主意,这只是为了消除问题特定于项目中源代码的可能性。

webghufk

webghufk6#

  • 请务必-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**这对我来说很关键。另一件要记住的事情是,你必须使用几乎与编译*.cpp相同的参数来编译*.h头文件。当我没有包含-O3-pthread时,它会忽略*.gch预编译头文件。
要检查一切是否正确,您可以通过比较以下两个参数的结果来测量时差:

time g++ sol.cpp ...

或运行

g++ sol.cpp -H -O3 -pthread -lm -std=c++14 -o executable

再次查找标题路径,如果您现在在库路径之前得到!,例如

! ./bits/stdc++.h.gch
....
zzoitvuj

zzoitvuj7#

一个关于文件扩展名的微妙提示,绊倒了我,因为我没有密切关注:将.gch扩展名添加到预编译文件的全名中;它不会替换.h。如果你把它弄错了,编译器就找不到它,也就无法正常工作。
预压缩h =〉预压缩h.gch
非:
预补偿h =〉预补偿gch
使用GCC的-H来检查它是否正在查找/使用它。

相关问题