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

时间:2009-07-27 23:49:47

标签: c++ visual-studio gcc cross-platform stdafx.h

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

问题是如何在两种环境中处理预编译的头文件。 我用Google搜索但无法得出结论。

显然,我希望在Visual Studio中保留stdafx.h,因为代码库非常大,预编译的头文件会增加编译时间。

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

  1. 保持原样stdafx.h。 gcc比VC ++编译代码要快得多(或者只是我的Linux机器更强...... :)),所以我对这个选项很满意。
  2. 使用here中的方法 - 使stdafx.h看起来像(仅为VS设置USE_PRECOMPILED_HEADER):

    #ifdef USE_PRECOMPILED_HEADER
    ... my stuff
    #endif 
    
  3. 使用here中的方法 - 在每个cpp文件中使用/FI将VC ++编译为隐式包含stdafx.h。因此,在VS中,您的代码可以轻松切换,无需预编译头文件即可编译,无需更改代码 我个人不喜欢依赖,而混乱stdafx.h正在推动一个大的代码库。因此,该选项对我很有吸引力 - 在Linux上你没有stdafx.h,同时仍然只能通过/FI在VS上打开预编译的标题。

  4. 在Linux上编译stdafx.h仅作为预编译头(模仿Visual Studio)
  5. 您的意见?还有其他方法可以解决这个问题吗?

10 个答案:

答案 0 :(得分:46)

最好还是使用预编译的标题来进行最快的编译。

您也可以在gcc中使用预编译头文件。 See here

已编译的预编译标头的附加内容为.gch,而不是.pch

因此,例如,如果您预先编译stdafx.h,您将拥有一个预编译的头文件,只要您包含stdafx.h.gch

,就会自动搜索名为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,您的编辑也会有效。

答案 1 :(得分:3)

我上次使用option 3时需要做同样的事情。我的项目很小但是效果非常好。

答案 2 :(得分:2)

我要么选择选项4还是选项2.我已尝试在各种VS版本和Linux上的GCC上预编译标题(关于此herehere的博客文章)。根据我的经验,VS对包含路径的长度,包含路径中的目录数量以及包含G ++的文件数量更加敏感。当我测量构建时间时,正确排列的预编译头将对VS下的编译时间产生巨大影响,而G ++对此几乎不感兴趣。

实际上,根据上面的内容,我上次在一个项目中所做的工作是必须控制编译时间,在Windows下预编译相当于stdafx.h的地方是有意义的,只是简单地用它作为Linux下的常规文件。

答案 3 :(得分:2)

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

答案 4 :(得分:2)

我只会在大型开发团队中使用选项1。 选项2,3和4通常会停止团队中其他成员的工作效率,因此可以在编译时每天节省几分钟。

这就是原因:

假设您的一半开发人员使用VS而另一半使用gcc。 偶尔会有一些VS开发人员忘记在.cpp文件中包含标题。 他没有注意到,因为stdafx.h隐含地包含它。因此,他推动了版本控制中的更改,然后gcc团队的其他一些成员将收到编译器错误。  因此,通过使用预编译的标头每天每5分钟获得一次,其他5人通过修复丢失的标头而浪费。

如果您不在所有编译器中共享相同的代码,那么每天都会遇到类似的问题。如果强制VS开发人员在推送更改之前检查gcc上的编译,那么使用预编译头文件将会提高所有工作效率。

选项4听起来很吸引人,但是如果你想在某个时间点使用另一个编译器怎么办?选项4仅在您使用VS和gcc时才有效。

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

答案 5 :(得分:1)

这很简单,真的:

项目 - &gt;项目设置(Alt + F7)

项目 - 设置 - 对话框:
C ++ - &gt;类别:预编译标题 - &gt;预编译标题单选按钮 - &gt;禁用

答案 6 :(得分:1)

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

答案 7 :(得分:1)

如果您在项目中使用CMake,那么有些模块会为您自动化,非常方便,例如,请参阅 cmake-precompiled-header here。要使用它,只需包含模块并调用:

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

另一个名为 Cotire 的模块会创建要预编译的头文件(无需手动编写StdAfx.h)并以其他方式加速构建 - 请参阅here

答案 8 :(得分:0)

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

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

答案 9 :(得分:0)

我遇到一种情况,特别是#2不适用于我(有许多VS构建配置,其中#ifdef周围的#include "stdafx.h"无效)。其他解决方案不是最理想的,因为文件本身是跨项目的以及跨平台的。我不想强制设置预处理器宏,也不想强制Linux甚至Windows构建使用(或不使用)pch,所以...

对于给定名为notificationEngine.cpp的文件,我所做的工作被完全删除了#include stdafx.h行,在名为pchNotificationEngine.cpp的同一目录中创建了一个新文件,其内容如下:

#include "stdafx.h"
#include "notificationEngine.cpp"

任何给定的项目都只能包含文件的正确版本。显然,对于仅由单个项目使用的cpp文件,这可能不是最佳选择。