在跨平台代码中处理stdafx.h

我有一个基于Visual Studio C ++的程序,它使用预编译的头文件( stdafx.h )。 现在我们使用gcc 4.x将应用程序移植到Linux上。

问题是如何在两种环境下处理预编译的头文件。 我GOOGLE了,但不能得出结论。

很显然,我想在Visual Studio中保留stdafx.h ,因为代码库相当大,预编译头文件提高了编译时间。

但问题是在Linux中要做什么。 这是我发现的:

  1. 保持stdafx.h 。 gcc编译代码的速度比VC ++快得多(或者只是我的Linux机器更强大… :)),所以我可能对此选项感到满意。
  2. 从这里使用方法 – 使stdafx.h看起来像( USE_PRECOMPILED_HEADER为VS设置USE_PRECOMPILED_HEADER ):

     #ifdef USE_PRECOMPILED_HEADER ... my stuff #endif 
  3. 使用这里的方法 – 用/FI编译VC ++ 隐式地在每个cpp文件中包含stdafx.h 。 因此,在VS中,您的代码可以很容易地进行编译,而无需预编译头文件,也不需要更改代码。
    我个人不喜欢依赖和stdafx.h混乱正在推动一个大代码基地。 因此,这个选项对我很有吸引力 – 在Linux上你没有stdafx.h ,但仍然可以通过/FI打开VS上的预编译头文件。

  4. 在Linux上,只将stdafx.h编译为预编译头文件(模仿Visual Studio)

你的意见? 还有其他方法来处理这个问题吗?

您最好使用预编译头还是为了最快的编译。

你也可以在gcc中使用预编译的头文件。 看到这里 。

编译后的预编译头文件将附加一个扩展名为.gch而不是.pch

因此,例如,如果您预编译stdafx.h,您将拥有一个预编译头文件,只要您包含stdafx.h ,就会自动search名为stdafx.h

例:

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,编译也将起作用。

上次我使用了选项3来做同样的事情。 我的项目非常小,但是这个工作非常好。

我要么去选项4或选项2.我已经在各种VS版本和Linux上的GCC( 在这里和这里的博客文章)尝试预编译头。 根据我的经验,VS对包含path的长度,包含path中的目录数量以及包含文件的数量比G ++更敏感得多。 当我测量编译时间时,正确安排的预编译头文件会对VS下的编译时间产生巨大的影响,而G ++对此并没有什么印象。

其实,基于上面我所做的上一次我在一个项目中,这是必要的,以遏制编译时间是预编译stdafx.h在Windows下的等价物,它是有道理的,只是用它作为一个普通的文件在Linux下。

很简单的解决scheme 在Linux环境中为“stdafx.h”添加一个虚拟文件条目。

这很简单,真的:

项目 – >项目设置(Alt + F7)

项目 – 设置 – 对话框:
C ++ – >类别:预编译头文件 – >预编译头文件单选button – >禁用

由于stdafx.h默认是所有特定于Windows的东西,所以我在其他平台上放了一个空的stdafx.h 。 这样,您的源代码保持不变,同时在Linux上有效禁用stdafx ,而无需从代码中删除所有#include "stdafx.h"行。

我只会在一个大的开发团队中使用选项1。 选项2,3和4经常会阻止你的团队其他成员的生产力,所以可以在编译的时候每天保存几分钟。

原因如下:

假设一半的开发人员使用VS,一半使用gcc。 每隔一段时间,一些VS开发人员会忘记在.cpp文件中包含一个头文件。 他不会注意到,因为stdafx.h隐含地包含它。 所以,他在版本控制中推动了他的改变,然后gcc团队的一些其他成员将会得到编译器错误。 因此,通过使用预编译的头文件,每5分钟一次,您就可以获得5个其他人通过修复丢失的头文件而浪费的时间。

如果你没有在所有的编译器中使用相同的代码,那么你每天都会遇到这样的问题。 如果你强迫你的VS开发人员在推送更改之前检查gcc的编译,那么你将会从使用预编译头文件中获得所有的生产力提升。

选项4听起来很有吸引力,但是如果你想在某个时间点使用另一个编译器呢? 选项4只适用于你只使用VS和gcc。

请注意,选项1可能会使gcc编译受到几秒钟的影响。 虽然它可能不明显。

如果你在你的项目中使用CMake,那么有一些模块可以为你自动化,非常方便,例如在这里可以看到cmake-precompiled-header 。 要使用它只包括模块和调用:

 include( cmake-precompiled-header/PrecompiledHeader.cmake ) add_precompiled_header( ${target} ${header} FORCEINCLUDE SOURCE_CXX ${source} ) 

另一个名为Cotire的模块创build头文件进行预编译(无需手动编写StdAfx.h),并以其他方式加速构build – 请参见此处 。

我已经为跨平台代码做了选项2(#ifdef)和选项4(PCH for gcc),没有任何问题。

我发现gcc编译速度比VS快得多,所以预编译头文件通常不是那么重要,除非你引用了一些大的头文件。