gcc预编译头文件使用-c选项时的奇怪行为

pac*_*nga 4 c++ gcc precompiled-headers

短篇故事:

我无法使用gcc -c选项使预编译的头文件正常工作.

很长的故事:

伙计们,我在Linux上使用gcc-4.4.1,在一个非常大的项目中尝试预编译头之前,我决定在简单程序上测试它们.他们"有点工作",但我对结果不满意,我确信我的设置有问题.

首先,我编写了一个简单的程序(main.cpp)来测试它们是否可以工作:

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/type_traits.hpp>

int main()
{
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后我创建了预编译头文件pre.h(在同一目录中),如下所示:

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/type_traits.hpp>
Run Code Online (Sandbox Code Playgroud)

...并编译它:

$ g++ -I. pre.h
Run Code Online (Sandbox Code Playgroud)

(pre.h.gch创建)

之后,我使用和不使用预编译头来测量编译时间:

与pch

$ time g++ -I. -include pre.h main.cpp

real    0m0.128s
user    0m0.088s
sys  0m0.048s
Run Code Online (Sandbox Code Playgroud)

没有pch

$ time g++ -I. main.cpp 

real    0m0.838s
user    0m0.784s
sys  0m0.056s
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好!快了近7倍,令人印象深刻!现在让我们尝试一些更现实的东西.我的所有资源都是使用-c选项构建的,出于某种原因我无法使用pch.您可以通过以下步骤重现这一点......

我创建了测试模块foo.cpp,如下所示:

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/type_traits.hpp>

int whatever()
{
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

以下是我尝试使用和不使用pch构建模块foo.cpp的时间:

与pch

$ time g++ -I. -include pre.h -c foo.cpp 

real    0m0.357s
user    0m0.348s
sys 0m0.012s
Run Code Online (Sandbox Code Playgroud)

没有pch

$ time g++ -I. -c foo.cpp 

real    0m0.330s
user    0m0.292s
sys 0m0.044s
Run Code Online (Sandbox Code Playgroud)

这很奇怪,看起来根本没有加速!(我跑了好几次).事实证明在这种情况下根本没有使用预编译的头文件,我用-H选项检查它(输出"g ++ -I.-include pre.h -c foo.cpp -H"没有列出pre.h. gch at all).

我究竟做错了什么?

pac*_*nga 8

好吧,我想我找到了解决方案:-fpch-preprocess应该与-c选项一起使用.它就像一个魅力!

这是时间:

与pch

$ time g++ -I. -include pre.h -c foo.cpp -fpch-preprocess

real    0m0.028s
user    0m0.016s
sys 0m0.016s
Run Code Online (Sandbox Code Playgroud)

没有pch

$ time g++ -I. -c foo.cpp 

real    0m0.330s
user    0m0.292s
sys 0m0.044s
Run Code Online (Sandbox Code Playgroud)

更新:我在gcc帮助邮件列表上问了同样的问题,Ian Lance Taylor通过使用distcc/ccache解释了这个奇怪的行为.这些工具首先预处理源,这就是需要这些选项的原因.