【问题标题】:Handling stdafx.h in cross-platform code在跨平台代码中处理 stdafx.h
【发布时间】:2010-11-14 13:02:53
【问题描述】:

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

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

显然我想将 stdafx.h 留在 Visual Studio 中,因为代码库非常大,并且预编译的标头会缩短编译时间。

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

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

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

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

你的意见?是否有其他方法可以解决此问题?

【问题讨论】:

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


    【解决方案1】:

    你最好还是使用预编译的头文件以获得最快的编译速度。

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

    已编译的预编译标头将附加一个扩展名作为.gch 而不是.pch

    因此,例如,如果您预编译 stdafx.h,您将有一个预编译的标头,只要您包含 stdafx.h,就会自动搜索该标头称为 stdafx.h.gch

    例子:

    stdafx.h:

    #include <string>
    #include <stdio.h>
    

    a.cpp:

    #include "stdafx.h"
    int main(int argc, char**argv)
    {
      std::string s = "Hi";
      return 0;
    }
    

    然后编译为:

    &gt; g++ -c stdafx.h -o stdafx.h.gch
    &gt; g++ a.cpp
    &gt; ./a.out

    即使您在第 1 步后删除 stdafx.h,您的编译也将正常工作。

    【讨论】:

    • 我的意思是在你运行 g++ -c stdafx.h -o stdafx.h.gch 之后,你可以删除 stdafx.h 并且你的编译仍然可以工作(g++ a.cpp)。你实际上不会这样做,但我提到它作为它使用预编译头的证据。
    • @Brian 也许我错了,但这看起来像我列出的选项 4 :) 我试图从 a.cpp 中删除 stdafx.h 并且它没有编译 - 只有在包括相应的头文件。我用 strace 确认了 :))。
    • @idimba:是的,它是选项 4,但是您修改了问题并在我发布答案三分钟后添加了 #4。相应的头文件无论如何都应该包含在源代码中。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

          真的很简单:

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

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                【解决方案8】:

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

                原因如下:

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

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

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

                请注意,选项 1 可能会使 gcc 编译延迟几秒钟。虽然可能不明显。

                【讨论】:

                  【解决方案9】:

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

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

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

                  【讨论】:

                    【解决方案10】:

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

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

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

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

                    【讨论】:

                    • 别担心我最近对另一个问题的评论:The compiler for main just needs the function/class declarations (.hpp), not the implementations/definitions. The linker finds those. #includeing .cpp files can be done but is incredibly bizarre.
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2015-09-15
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2010-11-24
                    相关资源
                    最近更新 更多