在现代C ++ Builder应用程序中使用预编译头文件的最佳实践是什么?

时间:2013-08-05 16:12:28

标签: c++builder precompiled-headers c++builder-xe4

我目前正在将大型RAD Studio 2010项目迁移到XE4。作为其中的一部分,我正在重新创建许多项目文件。我想借此机会确保我们为预编译头文件使用最好的机制,因为似乎有几种方法可以做到。

目前我们只编译32位,但将来会使用64位编译器。

以下是我们目前在2010年所做的工作,以及为什么我不确定在XE4中该做些什么:

在RAD Studio 2010中

我们有一个文件PchApp.h,其中包含<vcl.h>和许多其他常用的头文件,主要是项目中各种常用核心类的标题。此标头包含在每个CPP文件的顶部,后跟#pragma hdrstop,如下所示:

// Top of .cpp file
#include "PchApp.h"
#pragma hdrstop

// Normal includes here
#include "other.h"
#include "other2.h"
// etc

然后,我们在项目选项的预编译标题部分中进行以下设置:

Current RS2010 precompiled header settings

编译速度不是特别快(大约350,000行代码需要12分钟。)我不确定:

  • &#34;注入预编译的头文件&#34;:这应该注入PchApp.h吗?
  • &#34;缓存预编译头文件(必须与-H或-H&#34; xxx&#34使用)&#34;:-H选项是&#34; PCH文件名&#34;,所以我们正在使用它,但是预编译标题的确定点是它已经被缓存了#34;或者每次编译预编译一次。这有什么额外的区别呢?
  • 我们是否应该在.cpp文件中包含两行包含PchApp.h和pragma hdrstop?有没有办法在项目选项中执行此操作,而不是在每个文件中复制这两行?他们有必要吗?

换句话说,我不确定这些是正确的还是最佳的设置,但是从阅读the documentation开始,我同样不确定哪些更好。我知道我不能很好地理解所有选项 - 这个问题的一个原因是:)

在RAD Studio XE4

XE4 32位编译器选项对话框是相同的,但有两件事让我感到困惑和/或让我不确定当前的2010方法是最好的。

1。默认行为

创建新的VCL Forms项目时,IDE会创建标题named by default Project1PCH1.h, which is intended to be the project's precompiled header.此标题包含<vcl.h><tchar.h>,并在项目管理器中显示为节点。它不包含在默认的Form1.cpp中,但#include <vcl.h>后跟#pragma hdrstop位于Form1.cpp的最顶端,后跟其他标题。

使用此标题的新项目的默认XE4设置对话框是: XE4 default precompiled header settings

我(天真地?)正在假设默认值实际上是最佳/最佳设置。有些事情让我困惑:

  • 项目的预编译标题Project1PCH1.h未在任何地方的预编译标题设置中提及。
  • 标题未缓存
  • 未指定PCH文件名(这应该是Project1PCH1.h吗?)
  • .cpp文件也不包含Project1PCH1.h

实际上我不知道编译器或IDE实际上是如何知道它应该使用Project1PCH1.h或者它应该使用它的.cpp文件,因为它没有被引用我能找到的任何方式。

对我来说,这是最令人费解的事情,并且提出这个问题,并清除我对PCHes的困惑。我曾计划复制/使用IDE的默认设置,但在我明白他们在做什么之前我不想这样做。

2。 PCH向导

自2010年以来,IDE已包含预编译头向导。我还没有能够让它工作 - 我现在正在再次运行它以获得结果并解释我对#34;没有工作的记忆,但它似乎需要几个小时,所以我稍后会更新这个问题。

编辑:它运行,虽然它需要几个小时,并产生一个列表(对我来说,知道源基础)奇数标头。我几年前尝试它的回忆是它根本没有运行 - 这是一个明显的改进。

由于它存在,因此可能是在为升级2010项目而形成的新创建的项目文件中设置使用预编译头的最佳方法。我该如何做到最好?包括PchApp.h在内的所有.cpp文件是否会混淆它?

问题

以此为背景,我有以下问题:

  • 现有设置。我正在创建一个新项目文件,并添加了数千个预先存在的.cpp文件,所有文件都包含#34; #include PchApp.h; #pragma hdrstop&#34;在顶部。我应该复制现有的RS2010 PCH设置吗?我应该删除上面两行并用其他东西替换它们吗?
  • 使用PCH向导:根据您的经验,这是否会创建最佳设置?它是否包含文件,如果修改,将导致项目的大面积重建(可能不是编码的最佳)?是否可以在现有项目上使用,或者像我们的&#34; #include PchApp.h&#34;需要在使用之前将其剥离吗?
  • CPP文件/单位和正确的包含。使用预编译标头的.cpp文件不应包含预编译标头本身,而只包括.cpp实际需要的标头,即使PCH包含那些?如果您有我们目前的情况,PchApp.h文件包含几个常见标题,那么.cpp文件实际上不包含这些文件,该怎么办?如果删除包含PchApp.h并将其替换为PchApp.h中特定.cpp文件所需的标头子集,它们是否应高于或低于#pragma hdrstop? (上面,我认为。)如果你在其中包含未包含在预编译头文件中的其他内容会怎么样 - 它会改变该特定单元的PCH使用情况,导致PCH重建(性能问题?)等等?
  • 默认设置:假设新项目的默认设置是最佳的,那么如何将当前系统迁移到使用它?
  • 非默认设置:如果默认设置不是最佳设置,那么是什么?我想这是关键问题。
  • 32位和64位:知道我们很快就会转移到64位,我们应该怎样做才能让预编译的头在32位和64位上运行?是否所有PCH知识都在项目选项而不是.cpp文件中,因此32位和64位编译的设置不同?
  

我正在寻求一个清晰,详细,解释性和指导性的答案,这个答案清楚地解释了最好的答案   练习,设置选项,包含在.cpp中的项目   文件,标题和/或项目文件,等等 - 换句话说,现在要清理我的东西(毕竟以上!)相当混乱的理解。今后其他C ++ Builder用户可以将其作为首选PCH参考的高质量答案将非常出色。 我打算在中添加赏金   我能够的几天。

2 个答案:

答案 0 :(得分:1)

  1. 现有设置。根据我的经验,我通常会更改这些设置,因为如果您有数百个文件 - 它似乎并不是最佳的。在xCode中,即它是默认配置。应该没有编译性能差异。
  2. 使用PCH向导老实说,我从未在真实项目中使用过它,并没有给我留下深刻印象,所以只是忘记了这一点并使用了手动设置。
  3. CPP文件/单位和正确的包含。不同的IDE具有不同的默认设置。我通常使用的是:
    • 自动注入预编译头文件(在.cpp中没有手动#include)
    • 首先包含适当的头匹配.cpp(如果存在)(myfile.cpp - 然后包含myfile.h)
    • 之后包括执行特定工作的所有特定标头(特定的lib标头等)
    • 在“myfile.h”中只包括必须的东西。避免使用任何可以避免的东西。
    • 您为特定.cpp文件专门包含的所有内容都应位于#pragma hdrstop之下。您想要预编译的所有内容都应该在上面。
  4. 默认设置我认为这不是最佳选择。至于我,只需更改设置中的几个选项就可以轻松迁移。
  5. 非默认设置正如我上面提到的 - 对我而言,最佳设置是自动注入预编译的标头。第3项中的更多细节。
  6. 32位和64位没有遇到任何问题。它应为每个特定配置生成自己的预编译头。

答案 1 :(得分:1)

这就是我的所作所为(虽然我不确定这是不是一个好主意,但似乎有效)

  1. 确保Project1PCH1.h存在(Project1是项目的名称)
  2. 让它包含#pragma hdrstop和2个尾随换行符(当我没有尾随换行符时,我得到了奇怪的错误,可能是编译器错误)
  3. 在“所有配置”中输入“注入预编译头文件”,然后命名为“Project1PCH1.h”
  4. 请勿在其他文件中执行#include "PchApp.h"#pragma hdrstop等任何操作。
  5. 正确检查所有构建(即文件有自己的优点,不依赖于注入的PCH)
  6. 将一些包含放入Project1PCH1.h。我使用向导提出一些建议,但你必须应用一些人工逻辑来获得良好的构建。
  7. 当它在32位模式下正常工作时,一切都能快速编译;你可以告诉你,如果你正在编译你的项目并且一个特定的.cpp文件比其他文件需要更长的时间,你是否还没有完全正确。该向导根据包含给定标题的文件数量提出建议,但这有点虚假;你需要在其中包含任何系统头(或升级头等),如果它不是PCH的一部分,它将显着增加编译时间。

    我不打算在其中包含我自己的项目标题,只包括系统和标准标题。根据您的项目IDK,这可能会有所不同。

    PCH不适用于.c个文件,因此如果您的文件中有任何文件,则需要让Project1PCH1.h拥有#ifdef __cplusplus个警卫。

    另外:即使bcc64不支持PCH(但它确实注入了文件),如果你的PCH设置正确,它似乎确实使编译速度提高了一点,我不确定为什么


    我还不了解的事情:

    • 为什么New Project向导会自动生成Project1PCH1.h但实际上没有在Project Properties的“Inject Precompiled Header”字段中设置它?
    • 有时构建失败,说它无法打开Project1PCH1.h,但如果我做了一些更改并重新保存,通常似乎可以解决这个问题。