使用 GCC 预编译头文件

发布于 2024-07-04 08:36:34 字数 260 浏览 12 评论 0原文

如何获得与 GCC 一起使用的预编译头?

我的尝试并不顺利,也没有看到很多关于如何设置它的好例子。 我尝试过 Cygwin GCC 3.4.4 并在 Ubuntu

How can I get 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

随梦而飞# 2024-07-11 08:36:35

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必须与位于同一目录中code>pch.h 才能使用,因此请确保从 pch.h 所在目录执行上述命令。

The -x specifier for C++ precompiled headers is -x c++-header, not -x c++. Example usage of PCH follows.

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.

Generate the PCH like this:

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

弃爱 2024-07-11 08:36:35

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

例如,

g++ $(CPPFLAGS) test.h

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

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

更多信息可以在 GCC 预编译标头下找到。

Call GCC the same way as if you call it for your source file, but with a header file.

E.g.,

g++ $(CPPFLAGS) test.h

This generates a file called test.h.gch.

Every time GCC searches for test.h, it looks first for test.h.gch and if it finds it it uses it automatically.

More information can be found under GCC Precompiled Headers.

葬花如无物 2024-07-11 08:36:35

我过去曾经成功地让预编译头在 gcc 下工作过一次,我记得当时也遇到了问题。 要记住的是,如果不满足某些条件,gcc 将忽略该文件(header.h.gch 或类似文件),可以在 gcc 预编译头文档页面

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

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

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.

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.

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.

紫竹語嫣☆ 2024-07-11 08:36:35

确保-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 位/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
....

Make sure to -include your_header.h

This is how I precompiled and used bits/stdc++.h collection.

Code

#include <bits/stdc++.h>

Then I located the lib by compiling my file with -H and looking at output

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.

Then I ran

g++ bits/stdc++.h -O3 -std=c++14  -pthread

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

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
....
作死小能手 2024-07-11 08:36:35

首先,请参阅此处的文档

您可以像任何其他文件一样编译标头,但将输出放入后缀为 .gch 的文件中。

因此,例如,如果您预编译 stdafx.h,您将拥有一个预编译标头,每当您包含 stdafx.h 时,都会自动搜索名为 stdafx.h.gch 的预编译标头

示例:

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

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.

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

Example:

stdafx.h:

#include <string>
#include <stdio.h>

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

Your compilation will work even if you remove stdafx.h after step 1.

高冷爸爸 2024-07-11 08:36:35

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

precomp.h =>; precomp.h.gch

不是:

precomp.h => precomp.gch

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

A subtle tip about the file extension that tripped me up, because I wasn't paying close enough attention: the .gch extension is added to the precompiled file's full name; it doesn't replace .h. If you get it wrong, the compiler won't find it and silently does not work.

precomp.h => precomp.h.gch

Not:

precomp.h => precomp.gch

Use GCC's -H to check if it's finding/using it.

懵少女 2024-07-11 08:36:34

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

#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;
}

这只是一个 Hello, World !程序来自 Boost Xpressive。 首先,我在 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 秒。 不错,但也不是很好。

注意:这是示例< /a>. 我无法让它在帖子中工作。

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

g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3

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 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;
}

This was just a Hello, World! program from Boost Xpressive. 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:

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:

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:

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.

Note: Here's the example. I couldn't get it to work in the post.

BTW: I'm using the following g++:

g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文