在跨平台代码中处理stdafx.h
我有一个基于Visual Studio C ++的程序,它使用预编译的头文件( stdafx.h
)。 现在我们使用gcc 4.x将应用程序移植到Linux上。
问题是如何在两种环境下处理预编译的头文件。 我GOOGLE了,但不能得出结论。
很显然,我想在Visual Studio中保留stdafx.h
,因为代码库相当大,预编译头文件提高了编译时间。
但问题是在Linux中要做什么。 这是我发现的:
- 保持
stdafx.h
。 gcc编译代码的速度比VC ++快得多(或者只是我的Linux机器更强大… :)),所以我可能对此选项感到满意。 -
从这里使用方法 – 使
stdafx.h
看起来像(USE_PRECOMPILED_HEADER
为VS设置USE_PRECOMPILED_HEADER
):#ifdef USE_PRECOMPILED_HEADER ... my stuff #endif
-
使用这里的方法 – 用
/FI
编译VC ++ 隐式地在每个cpp文件中包含stdafx.h
。 因此,在VS中,您的代码可以很容易地进行编译,而无需预编译头文件,也不需要更改代码。
我个人不喜欢依赖和stdafx.h
混乱正在推动一个大代码基地。 因此,这个选项对我很有吸引力 – 在Linux上你没有stdafx.h
,但仍然可以通过/FI
打开VS上的预编译头文件。 - 在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快得多,所以预编译头文件通常不是那么重要,除非你引用了一些大的头文件。