当前位置:   article > 正文

山东大学编译原理实验_UE4.24 FastBuild(v1.02) 支持C++与 Shader 可用的分布编译加速方案...

山东大学编译原理实验build

5b8fa692aa1aecbf721f878202331f84.png

背景

因项目需要 , 近期研究整理了下网上流传的各种版本UE4 的 FastBuild 支持方案 , 不过使用上有较多问题:

  1. 要么支持的UE版本较老,与项目版本(4.24)不一致无法用 (如目前看到较多文章/代码和讨论是 4.18,4.20,4.22的)
  2. 要么终于找到差不多的版本改掉错误后,"看起来可以" 编译加速, 实际上没有处理UE4的编译缓存和依赖文件, 导致每次构建都重新编译, 最终加速又没有效果
  3. 还有的是环境问题 , 缺失依赖库等,编译各种报错
  4. 不支持Shader编译 , 或者本地编译正常,但是分发到远程由于路径映射问题会导致ShaderCompileWorker 编译失败, 从而启用FASTBuild Shader 联编后导致编辑器崩溃

总之, 在此之前还没看到比较完整解决UE4.24 版本 C++ 与 Shader 编译都能很好支持以至于可以实际可用的情况 。

本文提供一份Windows 10 系统 UE4.24 下自测可用的FASTBuild 支持代码 (git) , 并简单阐明原理和改进过程,供需要的朋友参考,这样以后如果Epic官方依然没有正式支持FASTBuild或者支持不稳时候 ,也可以自行修改 。(本文可能适合之前稍微了解过FASTBuild 和 UE 编译流程的朋友食用,如果完全不了解,可以最后看看文章最后的参考部分 )

在贴代码之前, 简单说下方案的原理和优点吧 。

UE4 的 FASTBuild 支持分布编译的原理

UE4 是模块化组织C++代码 ,模块中有C#描述的模块的依赖关系,根据依赖关系可以生成依赖图 ,因此只要定义构建目标 (模块), UBT即可自动推导出依赖关系图,收集到要构建的单元 (C++文件),然后根据目标的平台配置即可自动生成对应平台的构建指令列表,这个构建指令就是UBT 中的 Action , 因此只要实现执行 Action 即可实现一个自定义的编译器 。

UBT 内置了 Incredbuild 的支持,当检测到Incredbuild(UE中叫XGE [(Xoreax Grid Engine , 网络计算引擎)])可用时, 会将这个Action List 导出一个 ***_xge.xml 给 IncredbuildIncredbuild 收到解析后,就可以自动发挥分布编译的功能 。

同理, 我们也可以给FASTBuild 搞一份他专有的 fbuild.bff 文件(描述构建目标依赖图和命令,类 CMakelist.txt), FASTBuild 执行这个文件就可以将编译命令分发到各个节点执行数百核心得加速编译(大型开源免费真香现场, Incredbuild授权好像不便宜) 。

再同理 , Shader编译过程也是一样,可以参考 Shader 编译时, UE4将编译Shader的任务导出 XGE 支持格式代码(参考Engine/Source/Runtime/Engine/Private/ShaderCompiler/ShaderCompilerXGE.cpp的实现 ),也做一份 FASTBuild 导出,也就自然支持了Shader 分布编译了 。

然后呢 , 再看FASTbuild , 它就是一个专门针对各种主流编译器编译这个过程做了专项优化的分布式计算(编译)工具 ,实际上也可以支持性自定义的命令,例如后面的Shader编译过程,只是在远程计算机上执行指令,指定输入输出,指定程序依赖集合,就可以能将任务分发出去,结果收回来 。

FASTBuild 分为两个部分, 一个是编译客户端 FBuild.exe , 负责解析 bff 编译文件(类似makefile / CMakeList),将解析的编译命令分派给注册进来的FBuildWorker.exe, Worker 是个工具人,就是无脑接受命令然后执行得到结果发回给 FBuild , FASTBuild 为了工具简单无依赖,所以使用一个共享文件系统作为登记 Worker 的数据库 ,所以只要配置系统环境变量里的FASTBUILD_BROKERAGE_PATH , FBuild 就知道 中有多少个登记了的Worker (地址) , 那么编译任务描述bff文件里的编译命令就能分给哪些 Worker 了 。

刚说过UE4 有自己的编译体系 , 也就是UBT (Unreal Build Tool , 参考代码在 /Engine/Source/Programs/UnrealBuildTool),编译中会涉及到判断文件新旧(如Makefile) 从而当个别文件变更时,可以计算出哪些文件需要编译(增量编译) , 编译缓存计算和更新逻辑,可以参考UBT 的 BuildMode 代码 。

参考代码后会发现 UE4.24 的编译和链接并非使用原来直接的cl.exe 与 link.exe , 而是 cl-filter.exe, link-filter.exe , 这两个程序源码可以参考 EngineExtrasWindowscl-filter 目录 ,实际命令会用 cl-filter 调用 cl.exe 编译,并且还会生成额外文件 (include/txt) 作为依赖判定,如果FASTBuild 编译直接用cl代替就会出现每次编译都会重新全部构建的诡异现象 (FASTBuild 构建应该用-clean, 因为UBT自己有缓存系统) 。

本方案的由来

参考诸多代码后,经历了开头的各种问题,然后也改了 FASTBuild 本身的代码(增加参数支持输出依赖文件), 针对项目目录结构改了UBT 的支持代码(因为P4管理构建引擎, 在引擎Intermediate 目录写bff 文件会上传,别人拉取后导致不可写导致其他问题),各种修改解决各种问题 。。。编译项目时可用,用BuildGraph编译引擎安装版又不可用 。

直到后来拉了4.26代码,发现4.26 的/Engine/Extras/Experimental 实验性质目录下居然包含了FASTBuild扩展支持 (好像4.25就有了,但是没拉过4.25没注意),以前纠结用奇怪方法绕过的cl-filter 问题官方也是修改 FASTBuild 源码 (v0.95版本),不过改的比较优雅一点 ,后来结合之前的个中修改以及调试和测试,把4.26对 FASTBuild的修改和4.26里UBT对FASTBuild的支持代码(相对独立)部分移植到UE4.24 与 FASTBuild-v1.02 (FASTBuild的最新版),也就是现在的这份代码 。

这份代码脱胎于官方未来的扩展(官方实际上也是从早期的一个网友扩展里改过来的,源文件里有说明),相对来说稳定性好一点点 , 也处理,不过Shader部分没有支持,从参考文献中找了Shader部分的代码,稍作修改测试实验后也证实了Shader 编译的正确性(证实确实工作了,不够效率提升的具体数字,大家可以自己验证下) 。

另外,期间也试用过IncredBuild, 不得不说有UE4官方的自然支持,IncredBuild 的扩展的确非常易于使用和稳定 , 只要安装完配置了证书,几乎无感就开启加速,对于大公司或者不差钱的主来说,直接用IncredBuild 应该非常适合的 。

关键代码

本来想贴代码diff 的, 不过贴起来比较多, 贴代码图片又不礼貌,可以直接到这个gayhub 看看代码.
给UE4的C++编译器装上涡轮​github.com

1812a3bbc5b891293d461a451348b021.png
这个是构建机某次构建安装版时表明的确FASTBuild生效了

这个使用的时候的要点 :

  1. FASTBuild 的两个程序 FBuild.exeFBuildWorker.exe 里面提供了, 也可以自己从代码里的v-1.02 编译(代码做过修改,不要用官方版, 不兼容)
  2. 可以将 FBuild.exe, FBuildWorker.exe 放在UE4 /Engine/Extras/FASTbuild/Win64 目录下,这样引擎的UBT 可以直接从默认位置找,如果不放在哪里,那么就要配置 PATH 环境变量,你懂得 。
  3. 多台部署Worker 的机器 ,在Worker启动之前配置 FASTBUILD_BROKERAGE_PATH 变量,可以设置利用率和空闲检测 。
  4. 需要修改 UBT 的 FASTBuild 编译选项通过 BuildConfiguration.xml 配置, 必须要放在特定的目录,一般可以放在 <文档>/Unreal Engine/UnrealBuildTool/ 下面(没有的话,自己建立一个目录)
  5. 因为改了UBT代码,项目用的话,需要重新编译UBT ,两种方式:
    1. 直接编译译引擎(编译过程就直接启动FASTBuild 多核了)
    2. 或者工程项目生成时用 -game 选项附带 UBT 构建项目自动触发UBT重新构建。

开启FASTBuild 使用

  1. 请确认将TurboBuildUE/UE4.24目录里的 UnrealBuildTool-v2 里面的代码补丁合入到你的引擎4.24里面,以及Shader编译支持的部分 ShaderCompiler 也合入到引擎代码里 , 参考代码里的readme.md
  2. 可以用打过补丁的fastbuild-v1.02 源码编译后,将FBuild.exe 和FBuildWorker.exe 放到 /Engine/Extras/FASTBuild/Win64 目录下(当然也可以直接用我提供编译好的)
  3. <我的文档>/Unreal Engine/UnrealBuildTool/BuildConfiguration.xml 中增加选项开启 FASTBuild
  4. 在环境变量中增加 FASTBuildFASTBUILD_BROKERAGE_PATH 配置共享目录(为什么? 可以参考前面原理和 FASTBuild 官网看看),然后在多台机器启动FBuildWorker.exe (都需要配置共享目录环境变量)
  5. 然后就可以构建UE4项目或者UE4引擎了,(重新)启动VS 点击编译(重启是UBT内部重新读取环境变量)
  6. 构建Shader FASTBuild 加速默认开启,如果要关闭,配置 Dev.Shaders 配置即可 。
  7. 实际使用效果,我自测了下,因为机器较少(大约5台,还出现2台无法支持C++编译的情况,问题没查), 效果嘛 。。。(lll¬ω¬) , 应该有一些,欢迎大家一起来改进FASTBuild 免费提升效能,增加公司CPU利用率 。
  8. 如果要看每台机器的参与情况, 可以编译github 代码里的 Dashboard 程序查看 。

未来优化

如果4.26 正式版本UE官方给出了稳定版, 那么FASTBuild 的扩展支持应该也不用太操心了 。不过目前来看,还存在一些不大不小的坑:

  1. 似乎依然不是很稳定,目前在某些 Worker 机器上会出现编译失败(DLL 缺失),但是某些机器又正常,暂时没有详细去看是啥原因,因为FASTBuild 在Worker上的日志几乎没有(我还没发现),然后就是远程调试慢慢磨,希望FASTBuild 未来版本能加强一些运行时的日志支持 。
  2. 《腾讯游戏开发精粹》中提到压缩文件缓解带宽的优化,可能我们本地的集群机器较少,看了下机器的带宽完全没有打满(Increbuild 却几乎打满了),所以估计我用的FASTBuild 这个版中间某些地方可能设置不对或者有缺陷,并没有利用好机器的最大性能 ,所以在代码中还没加这个patch优化 (压缩文件传输的)。
  3. Shader的编译运行时控制台动态修改参数现在没生效,需要改配置(EngineBase.ini , 可以参考代码里的 Dev.Shaders 部分增加的ini 选项,我没有附带BaseEngine 新增 ini Section 说明), 以及对应FB的参数设置似乎还没好啥经验值参考
  4. 交叉平台的编译,目前我们用Windows 交叉构建 Linux / Android / IOS , 尽管FB有Mac版本,但是我们MAC引擎目前还没启用 , FB在代码里现在对其他例如 PS4/5 , Android 是不支持的,这个是后续需要支持的, (Increbuild 这里还没测试过)
  5. 可能对FASTBuild 里面还不是很熟悉,感觉FB的调试和日志排查问题暂时比较繁琐一些,远程错误的回传比较精简,在添加自定义的构建步骤时定位错误不太方便 。

哈哈, 最后,如果这个文章真的帮助到各位大佬公司节省了大量时间或者金钱 ,私信打赏一波呗 (●'◡'●) , 啊, 不是, 是大家把后续的好的改进方案一起分享下~

参考相关

UE4.26 (Preview) 该版的 0.95 fastbuild diff 文件与UBT.FASTBuild.cs

《腾讯游戏开发精粹》-使用Fastbuild 助力UE4

https://www.fastbuild.org/docs/features/caching.html

https://zhuanlan.zhihu.com/p/158400394

https://gist.github.com/hillin/b6b491ee03f22b960a7e3e90e1c6f4ec

https://www.fastbuild.org/docs/home.html

https://blog.kangkang.org/index.php/archives/409

https://www.cnblogs.com/Shaojunping/p/11933626.html

https://github.com/fastbuild/fastbuild/issues/539

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号