| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 开发工具 -> 【ZeloEngine】重新理解CMake -> 正文阅读 |
|
[开发工具]【ZeloEngine】重新理解CMake |
【ZeloEngine】重新理解CMake
引子这两天重构了ZeloEngine的cmake脚本,正好重新思考一下,谈论cmake时,我们到底在解决什么问题 本文先说结论,然后讨论cmake知识,然后讨论怎么应用在这次重构中 重构结论构建时间41.547356s => 37.4614157s,稍微优化了一些 Visual Studio工程目录现在:干净,少量target 构建依赖图现在:相对干净,每个节点连接数合适 cmake脚本cloc 715 => 583
怎么做到的?
CMake做什么?
说白了,CMake是在已有的平台编译工具链上加了一层抽象,自己造了新的构建语言DSL,用来翻译到目标工具链上 用CMake主要解决跨平台编译的问题
编译器做什么?cmake只是在工具链上封装一层,本质还是编译器在起作用 重新梳理了编译概念后,我解开了几个误区,结论如下: 编译的本质,是一些target,每个target有一些属性,target之间有依赖关系,编译完每个target后,再链接到exe 所以ZeloEngine可以这样改进:
静态库 vs 动态库静态库
动态库
静态库优势
静态库劣势
动态库优势
动态库劣势
构建依赖解决了什么问题?把引擎当作一个黑盒,它引用了一堆第三方库 所以理论上,搞一个Engine.exe,把所有代码放在一起,然后引用所有第三方库,就可以了 那么拆分依赖有什么用呢?
一个大的引擎中,有一些小模块是可以复用的,有一些模块随着时间推移不再被引用,可以被删除 并行度与依赖反相关,分层设计,模块化,降低图的深度 前面提到引擎内部target其实不需要拆,是因为互相依赖很强,而且因为体量小,一个人开发,完全清楚使用情况 依赖与self-contained想要利用好依赖,就要构造self-contained依赖图 self-contained这个词,来自于#include依赖关系 在构建系统中,扩展为构建依赖关系,包含#include依赖和链接依赖 只需要做到:依赖所有自己直接需要的库 我们在解决什么问题?本质上,是为引擎定制一个C++构建系统 以Unreal为例,大型游戏引擎的专用构建系统需求:
说实话,cmake确实没有那么好用,曾经尝试过自己写zmake,效果很差,垃圾 ZeloEngine的体量处在一个尴尬点,并没有那么小,随便写写不考虑通用性;也没有那么大,我有足够的成本去维护一个专用的构建系统换掉CMake ZeloEngine的需求:
目录结构与构建大型引擎项目的目录结构也是架构设计的一部分 目录结构和构建系统的关系
引擎分层与构建引擎架构中,按bottom-up的分层顺序:
关于LuaBindLuaBind会反向被Engine引用,Engine在初始化时调用 但是这并不是循环引用,因为Engine是private引用LuaBind,可以理解为弱引用(weak_ptr) // 这个问题困扰了我很长一段时间,为啥循环引用可以正常工作,其实没有循环引用 关于MainMain.exe只是一个平台入口,定位类似EAMain,核心功能由引擎库提供 引入modern CMakePS 本节只摘选和本文相关的内容,更深入分析请参考《参考》 传统的cmake是过程式的,所有调用都是全局影响的,主要靠目录结构递归来传递 modern cmake是声明式的,面向对象的,我定义一些target,每个target有一些构建属性,包含target之间的依赖关系,这些target定义之间是没有顺序依赖的,也不应该有顺序依赖(self-contained) 引入private依赖,拆分interface库和module原来:一个子模块就是一个静态库,还会和其他子模块互相引用 现在:
构建依赖图cmake config阶段就可以分析出依赖了,不需要编译,因为cmake脚本描述了构建依赖关系 生成构建依赖图
图例如下,图例中需要注意的:
cmake依赖图的不足:没有体现分层,第三方库二分图 这个问题不大,没有也够用了 第三方库管理第三方库和自己写的引擎库是一个二分图,引擎依赖第三方库 最原始的cmake方法,是find_package脚本,一般find脚本cmake或者第三方库会写好,自己写也很容易 ZeloEngine为了降低成本,用一种混合方式管理第三方库,按优先级顺序:
// bootstrape是一个脚本工具,读配置文件下载源码,提供了一定的下载管理功能,避免重复下载,并且支持下载文件等 自动化第三方库的管理需要自动化:
一些特定需求举例
展望
参考
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 7:18:24- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |