54

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

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

显然我想离开stdafx.hVisual Studio,因为代码库非常大,而且预编译的头文件会增加编译时间。

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

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

    #ifdef USE_PRECOMPILED_HEADER
    ... my stuff
    #endif 
    
  3. 使用此处的方法- 编译 VC++/FI隐式包含stdafx.h在每个 cpp 文件中。因此,在 VS 中,您的代码可以轻松切换以在没有预编译头文件的情况下进行编译,并且无需更改任何代码。
    我个人不喜欢依赖,而且混乱stdafx.h正在推动一个大的代码库。因此,这个选项对我很有吸引力——在 Linux 上你没有stdafx.h,同时仍然能够在 VS 上打开预编译的头文件/FI

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

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

4

10 回答 10

48

你最好还是使用预编译的头文件来实现最快的编译。

您也可以在 gcc 中使用预编译的头文件。 见这里

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

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,您的编译也将正常工作。

于 2009-07-28T00:00:24.887 回答
3

上次我需要做同样的事情时,我使用了选项 3 。我的项目很小,但效果很好。

于 2009-07-28T00:00:51.030 回答
2

我会选择选项 4 或选项 2。我已经在各种 VS 版本和 Linux 上的 GCC 上尝试了预编译的头文件(关于此的博客文章在这里这里)。根据我的经验,VS 对包含路径的长度、包含路径中的目录数量和包含文件的数量比 G++ 更敏感。当我测量构建时间时,正确安排的预编译头文件会对 VS 下的编译时间产生巨大影响,而 G++ 对此几乎没有印象。

实际上,基于上述内容,我上次在一个项目中所做的需要控制编译时间是在 Windows 下预编译 stdafx.h 的等价物,它是有意义的,只是将其用作常规文件在 Linux 下。

于 2009-08-06T21:18:03.263 回答
2

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

于 2014-03-05T13:04:23.993 回答
2

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

原因如下:

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

如果您没有在所有编译器之间共享相同的代码,那么您每天都会遇到类似的问题。如果你强迫你的 VS 开发人员在推送更改之前检查 gcc 上的编译,那么你将放弃使用预编译头文件带来的所有生产力收益。

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

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

于 2014-09-07T06:35:12.427 回答
1

真的很简单:

Project->Project Settings (Alt + F7)

Project-Settings-Dialog:
C++ -> Category: Precompiled Headers -> Precompiled Headers 单选按钮 -> 禁用

于 2011-01-28T18:00:40.937 回答
1

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

于 2011-08-04T23:25:20.150 回答
1

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

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

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

于 2017-02-01T15:30:32.630 回答
0

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

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

于 2009-07-28T00:08:25.807 回答
0

我有一种情况,特别是 #2 对我不起作用(有许多 VS 构建配置,其中 a #ifdefaround#include "stdafx.h"不起作用)。其他解决方案不是最理想的,因为文件本身是跨项目的并且是跨平台的。我不想强制设置预处理器宏或强制 linux 甚至 windows 构建使用(或不使用)pch,所以......

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

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

Any given project can just include the correct version of the file. This admittedly is probably not the best option for cpp files that are only used by a single project.

于 2018-11-27T20:06:09.160 回答