这篇文章是奥尔加·阿尔基波娃写的。
许多大型代码库使用所谓的unity(jumbo)构建,其中许多源文件包含在一个或几个“unity”文件中进行编译,这使得编译和链接速度更快。
只是为了避免任何混乱-这个博客与Unity游戏引擎无关。
查看一些客户关于缓慢智能感知的反馈,我们发现项目通常同时包含源文件和包含这些源文件的unity文件。目前没有简单的方法从构建中排除源文件,从IntelliSense解析中排除unity文件,因此我们在那里做了很多不必要的工作。
unity构建的速度给我们留下了深刻的印象,尤其是在游戏开发中,尽管将文件组合在一起通常需要修改代码,以便能够在没有错误的情况下构建并维护代码语义。请参阅下面关于统一构建的利弊的文章 克马克 和 铬 内部版本:
在VisualStudio2017版本15.8(预览版3)中,我们引入了一个实验性的unity构建支持,这使得新用户可以很容易地采用unity,并允许现有的unity用户具有更好的IDE性能。请让我们知道它是否适用于您和什么可以使它更容易。
统一构建选项
要启用实验性统一支持,项目需要将EnableUnitySupport设置为“true”。您可以将其设置为环境变量,或在根目录中创建Directory.Build.props,内容如下:
[code language=“xml”]<项目xmlns=“http://schemas.microsoft.com/developer/msbuild/2003">
当启用该特性时,您将看到C/C++属性中的“统一构建”选项:
设置 “包含在统一文件中” “是”表示该文件应包含在unity文件中,而不应单独编译。通常,您希望为项目配置(即影响所有c/cpp文件)设置此属性,而不是像对“Excluded from build”属性那样单独为每个文件设置此属性。对于大型项目,不为每个文件设置属性会显著减小项目xml的大小并使其加载更快。
如果 “自定义统一文件” 属性为空或设置为“否”,生成将在中自动创建unity文件 “Unity文件目录” . 每个unity文件将包含具有相同编译器选项的源文件的#includes。具有不同编译器选项的文件(例如不同的include目录或预处理器定义)将位于不同的unity文件中。不同的unity构建属性(除了“unity文件中的订单号”)也会导致创建不同的unity文件。但是,通常您希望将它们设置为项目配置,因此它们适用于所有文件。
如有必要,#includes的顺序可以由 “Unity文件中的订单号” 值,您需要分别为每个文件设置它。
您还可以在每个“包含”之前/之后指定要包含的代码段。您可以直接在中定义它们 “要在Include之前/之后添加的代码段” 属性,或者对于更复杂的代码段,将它们放在一些文件中并设置在其中查找这些文件的位置 “要在包含之前/之后添加的文件代码段” 属性。代码段可以使用以下宏:
$$unity_id$$ - unique unity file hash $$file_number$$ - source file number in the unity file $$file_name$$ - source file name $$file_path$$ - source file full path"
例如,如果将“要在包含之前添加的文件代码段”设置为UnityPrefix.cpp,其中包含以下内容:
[code language=“c”]#pragma消息(“Unity编译:$$fileu name$$”)#定义UNITYu ID$$UNITYu ID$$u$$文件号$$
以及“要添加的代码片段AfterInclude”到“#undef UNITY ID”,生成的UNITY文件将包含:
[code language=“c”]#pragma消息(“Unity编译:input.cpp”)#定义统一u ID 1stayuscbveild3u 1#包括“C:MyProjectinput.cpp”#未定义单位ID
“仅合并来自同一文件夹的文件” 属性允许将unity文件内容限制为一个文件夹,除非此文件夹包含的值小于 “Unity文件中的最小源数” 财产。文件较少的文件夹仍将与其他类似文件夹合并在一个unity文件中。
如果 “多处理器编译” (/MP)为“是”,Visual Studio将创建至少与cl.exe使用的处理器数量相同的unity文件。
如果 “预编译头文件” 是由源代码指定和使用的,unity文件也将包含它。
手动自定义统一文件集成
如果在IDE之外生成unity文件并将其包含在项目文件中,以便可以手动更改其内容或生成选项,则需要执行以下操作:
- 对于项目配置(所有文件的默认值),请同时设置 “包含在统一文件中” 和 “自定义统一文件” 到 “是的” .
- 对于每个自定义文件集 “包含在统一文件中” 到 “没有” .
这将禁用自定义unity文件的IntelliSense分析。
使用MSBuild目标的自定义unity文件集成
如果您有一个生成unity文件的脚本或工具,您可以在构建中使用它,而不是我们默认的unity文件生成器。
请查看Common7idevcTargetsMicrosoft.Cpp.Unity.targets中的“CreateUnityFiles”目标
您可以实现自己的“CreateUnityFiles”目标,它看起来非常相似,但是使用“Exec”任务来调用脚本,而不是“CreateUnityFile”和“CleanupOldUnityFiles”任务。
假设您有一个MyCreateUnityFiles.cmdscript,它在作为第一个参数传递的指定目录中创建unity文件。您可以使用以下内容创建MyUnityFilesCreation.targets(请参见第15-20行):
[code language=“xml”]<项目xmlns=“http://schemas.microsoft.com/developer/msbuild/2003">
<项目组>
要覆盖默认目标,需要在vcxproj文件中的Microsoft.cpp.targets导入之后定义目标。您不需要在ClCompile之前“连接”目标以使其执行,因为它已经在Microsoft.Cpp.Unity.targets中执行过。
要在解决方案中的所有vcxproj文件中自动导入目标文件,请在目录.Build.props中添加以下属性:
[code language=“xml”]
不能将Directory.Build.targets用于自定义CreateUnityFiles目标,因为此文件在Microsoft.Cpp.Unity.targets之前导入。
向我们发送反馈
请下载 Visual Studio 2017 15.8版预览版 试着团结起来争取支持。我们很想知道它是如何为您工作。请通过下面的评论或电子邮件给我们反馈( visualcpp@microsoft.com ). 一般问题请 报告问题 .