6

从零开始手敲次世代游戏引擎(八十二)

 3 years ago
source link: https://zhuanlan.zhihu.com/p/142531075
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

从零开始手敲次世代游戏引擎(八十二)

代码虽然是用来写程序让计算机执行的,但是源代码其实更加是用来让人看的。

代码的可读性、可维护性是很重要的。这也就是为什么虽然最终都是编译成为机器码,但是却有如此多种编程语言的道理。就好像对人来说,虽然最终都是糖、蛋白、脂肪这些营养物质,但是却有各种各样的菜式料理一样。

在过往,关于代码风格的争论在程序员群体当中也是喋喋不休,甚至听说有的程序员因为这个问题和公司一言不合拍屁股走人的。

好在现在这方面也已经可以高度自动化了。程序员可以在一定程度上按照自己喜欢的方式来,而代码的统一整理工作可以交给自动化工具完成。

本篇介绍一下最近用clang tools进行的一些代码整理工作。

clang-tidy

首先是clang-tidy这个工具。这个工具提供了一系列modernize-开头的checker,可以用来将C++代码(部分)自动升级到modern C++。

Clang-Tidy, part 1: Modernize your source code using C++11/C++14 - KDAB​www.kdab.com图标Extra Clang Tools 11 documentation​clang.llvm.org

我在项目当中实际使用的是一个python的脚本:

https://github.com/netwarm007/GameEngineFromScratch/blob/article_82/scripts/run-clang-tidy.py​github.com

具体使用的方法是,首先在调用cmake编译项目的时候,传入

-DCMAKE_EXPORT_COMPILE_COMMANDS=ON

这个选项。这样在项目的生成目录下就会有一个名为compile_commands.json的文件生成。里面记录了每个源文件编译的时候相关的编译命令和选项。

之后,在该目录执行上面的python脚本(需要先安装python执行环境):

../scripts/run-clang-tidy.py -header-filter='.*' -checks='-*,modernize-use-override' -fix

其中,-fix 选项表示尝试自动修改代码。如果没有这个选项则只是检查,不进行实际修改。-header-filter=".*' 这个选项表示将头文件也纳入修改范围,而-checks='-*,modernize-use-override' 表示关闭其他缺省的checker,单独执行modernize-use-override这一项检查。

下面是执行的结果之一,可以看到派生类当中的virtual关键字被移除,添加了新的override关键字。这就可以保证该方法是对基类虚方法的重载。(而过去的virtual的写法并不能保证这一点)

类似的checker还有一堆,具体清单参照这里。

Extra Clang Tools 11 documentation​clang.llvm.org

我这里基本上将所有的modernize-开头的checker,以及一部分其他checker都执行了一遍。有少数几个checker造成代码当中出现冗余的';'号等小问题,需要手工修改一下。

clang-format

clang-format是用来对代码风格进行检查修改的自动化工具。它可以直接在命令行使用,也可以集成在VS、VS Code、Vim当中使用。

Clang 11 documentation​clang.llvm.org

因为我们现在是在项目中程导入,所以首先需要对项目当中所有的文件进行一次集中的整理。因为clang-format自身没有对文件目录遍历的能力,所以这里需要结合其他的命令行工具来进行。在我的项目当中,我写了下面这个shell文件,自动对除External之外的所有目录当中的代码进行风格化。

#!/bin/bash
find . -path ./External -prune -o \( -name "*.cpp" -o -name "*.c" -o -name "*.mm" -o -name "*.h" -o -name "*.hpp" \) -exec clang-format -i --style=file {} +;

clang-format自身提供了几个常见的代码规范模板,比如LLVM、Google、Mozilla等等。除此之外,我们也可以通过一个名为.clang-format的Json文件来详细自定义代码风格。我这个人对于具体的代码风格没有太多的执念,只要统一就好,所以我的配置文件很简单:

BasedOnStyle: Google
IndentWidth: 4
IncludeBlocks: Preserve

clang-check

这个并不是代码美化工具,而是C++源码静态分析工具。可以帮我们找到一些诸如变量未初始化、内存泄露等问题。同样的,因为其自身没有批处理能力,所以用简单的shell脚本补足:

#!/bin/bash
cd build
export COMPILE_DB=$(/bin/pwd);
grep file compile_commands.json |
awk '{ print $2; }' |
sed 's/\"//g' |
while read FILE; do
  (cd $(dirname ${FILE});
      clang-check -analyze -p ${COMPILE_DB} $(basename ${FILE})
        );
  done
v2-419dbe208f1d0842263c1f499b447a3d_720w.jpg


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK