任何人都成功地获得了与 GCC 一起使用的预编译头文件吗?我的尝试没有运气,也没有看到很多关于如何设置它的好例子。我已经尝试过 cygwin gcc 3.4.4 并在 Ubuntu 上使用 4.0。
7 回答
我肯定取得了成功。首先,我使用了以下代码:
#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 的一个问候世界(请参阅下面的链接)。首先,我使用-H
gcc 中的选项进行编译。它显示了它使用的大量标题列表。然后,我查看了我的 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
您像任何其他文件一样编译头文件,但您将输出放在后缀为.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,您的编译也将正常工作。
调用 gcc 的方式与为源文件调用它的方式相同,但使用头文件。
例如
g++ $(CPPFLAGS) test.h
这会生成一个名为 test.h.gch 的文件
每次 gcc 搜索 test.h 时,它首先查找 test.h.gch,如果找到它,它会自动使用它。
更多信息可以在GCC Precompiled Headers下找到
-x
C++ 预编译头文件的说明符是-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
。
过去我曾经设法让预编译的头文件在 gcc 下工作,我记得当时也有问题。要记住的是,如果不满足某些条件,gcc 将忽略文件(header.h.gch 或类似文件),可以在gcc 预编译头文件页面上找到其列表。
通常,最安全的做法是让您的构建系统首先编译 .gch 文件,使用与源代码的其余部分相同的命令行选项和可执行文件。这可以确保文件是最新的并且没有细微的差异。
首先让它与一个人为的示例一起工作可能也是一个好主意,只是为了消除您的问题特定于项目中的源代码的可能性。
确保-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
....
关于文件扩展名的一个微妙提示,因为我没有给予足够的关注,所以让我感到困惑:.gch
扩展名被添加到预编译文件的全名中,它不会替换.h
. 如果你弄错了,编译器将找不到它并且默默地不起作用。
precomp.h => 预压缩。h.gch
不是:
precomp.h => 预压缩。gch
使用 gcc-H
检查它是否正在查找/使用它。