EA:VS对Linux上的支持,让我们的开发人员很Happy!

EA:VS对Linux上的支持,让我们的开发人员很Happy!

作者:BlogUpdater |  时间:2019-11-14 |  浏览:244 |  评论已关闭 条评论

引子(有些地方叫楔子?)
美国艺电公司(Electronic Arts,NASDAQ: ERTS,简称EA),是全球著名的互动娱乐软件公司,主要经营各种电子游戏的开发、出版以及销售业务。美国艺电创建于1982年,总部位于美国加利福尼亚州红木城。知名游戏品牌:EA Sports的《极品飞车》系列,FIFA系列,NBA系列等等。EA Games的指环王系列,中土之战系列,荣誉勋章系列,命令与征服系列等等。
最近,EA写了一篇文章,讲述了他们是如何使用Visual Studio的跨平台特性来支持他们在Linux上的开发工作。这篇文章来自EA的高级软件工程师Ben May。

正文开始
EA目前正在使用的寒霜引擎(Frostbite Engine)中有一个Linux组件用来渲染我们很多的流行游戏。当我们看到微软在Visual Studio中添加了对Linux的支持时,这立刻就引起了我的注意。
在EA,我们的游戏开发工程师比较熟悉在Windows平台上开发,所以我们考虑到,如果强迫他们在Linux平台上开发将会是一件很困难的事儿,因此,我们决定使用clang和Windows中的交叉编译来解决这个问题。

最初的时候,我们不得不手工的将这一整套开发流程给串起来,我们使用了Visual Studio的Makefile工程来构建我们的源代码,然后我们通过SSH向目标Linux机器拷贝了一些工具,并编写了一些小的工具来在远程Linux机器上启动GDBServer,从而可以在PC上进行远程调试。

当Visual Studio中的Linux Workload发布后,我们发现,原来微软已经将这些繁琐的流程全部集成到了Visual Studio中,我们的开发人员可以安装Linux Workload并可以直接在Visual Studio中调试远程Linux上的程序了。

从目前的情况来看,我们成功的集成了WSL和远程调试功能,这简化了我们之前所做的一些串联工作。我们的开发人员对此那是十分高兴。下面,我将具体的谈一谈我们做了些什么。

搭建编译环境
我们内部的编译环境中,使用到了我们的一些内部工具来将内部的编译格式转换为许多其他的格式,例如vcxproj/csproj/make等。当我们决定将Linux平台添加到支持平台时,我们决定最好是能在Visual Studio中搭建主要的工作环境,因为我们的主要是在Windows平台上开发面向所有其他平台的游戏产品。
另外一个需求,是我们希望持续集成能在Linux平台上对代码进行验证,而不需要在Linux中编译代码,那样比较贵,而且比较难以维护。
以上这两个需求,促使我们在Windows平台使用clang来交叉编译我们的代码。

对于交叉编译器,我们使用了一个叫做”Canadian cross”的编译器。感兴趣的朋友可以到Github和Wiki上找到更多信息,包括为什么叫它”Canadian cross”。我们已经在一台Linux机器上构建了LLVM和GCC工具链,然后将它们移动到一台安装有clang的Windows机器上。基于此,我们在Windows上搭建的交叉编译环境概况如下:
1. 我们使用LLVM
2. 我们合并了Windows版本的LLVM和Linux的版本,因为我们的目标平台是Linux,所以我们需要获得到所有的依赖的库和头文件。
3. 我们同时也使用了带LLVM的GCC工具链。为了得到Windows版本的gcc工具链,我们在Linux上使用了crosstool-NG这个工具来编译它。
4. 然后,在编译的时候,需要添加命令行参数:-target x86_64-pc-linux-gnu和-sysroot= 5. 可能你还需要使用-Wno-nonportable-include-path这个编译开关来关闭一些警告,并且还需要自行修正一些关于头文件包含路径的问题。

当我们的工具链环境组装好之后,我们会使用功能一个内部生成器来生成makefile文件,然后使用上面提到的交叉编译工具来编译我们的代码,另外还会生成vcxproj和sln工程文件。这个就是我们开始将开发工作迁移到Visual Studio Linux Workload的地方。

Visual Studio集成
开发者首先需要确保机器上安装了Visual Studio中的”Linux development with C++”这一个组件。

然后,我们就可以创建一个Linux Makefile工程来开始我们的工作了。为了编译我们的代码,我们只需简单的点击Build,这将会执行我们的交叉编译工具并生成最终的执行文件。

在WSL上构建工程
我们可以配置生成器来使用两种不同部署/调试环境:
1. WSL(Windows Subsystem For Linux)
2. Remote Linux Host

如果你不需要在屏幕上渲染任何东西的话,我想最简单的方式是WSL。换句话说,如果你需要开发的仅仅是一些单元测试或者控制台应用,WSL是最简单,也是最快速的方法。
如果开发者使用WSL,那么生成的执行文件实际上不需要部署,这是因为WSL能从本地的Windows机器上直接访问这些执行文件,因为不需要将这些文件拷贝到目标机器(有些文件确实很大),这可以节省不少的时间。

下面是使用了Visual Studio Linux Makefile工程和我们的交叉编译器来构建EASTL的截图。EASTL是EA的一个开源库。

我们可以看到,我在代码中添加了一断点,同时我配置了在运行时使用WSL这一选项,所以,当我调试这个程序时,VS将会在WSL中启动并连接到VS的GDB调试器,这并不需要拷贝程序到Linux机器中。
通过设置Remote Build Root, Project and Deploy directories选项,并设定好WSL的路径到当前Windows上的相同目录即可。

下面是我在进行调试并触发断点后,继续执行的一个例子。

在远程Linux机器上构建工程
当我们不使用WSL,而是选择一台远程Linu机器来搭建编译环境时,唯一令我们担心的是生成的执行文件如何部署以及其起来的库文件和资源文件的问题。
我们的做法是,创建一个源文件来映射到远程机器中,然后使用Visual Studio的编译后实践功能来拷贝这个文件。在工程属性的”Build Events” -> “Post-Build Event” -> “Additional Files To Copy”中,我们可以指定需要拷贝到远程机器中的文件列表,这些文件将会在构建成功完成之后自动拷贝过去。有了这个功能,我们就可以确保在我们调试程序的时候,这些执行文件已经存在于远程机器上面了。

从上图中可以看到将待拷贝的文件映射到目标路径的语法,这在两个不同的文件系统中互相映射文件是非常方便的。

我们还想要更多
上面的做法中,有一个不足之处。执行文件的部署只能发生在构建阶段,我们希望能在以下三个不同的阶段都能在Linux上顺利工作,它们分别是:
1. 构建阶段
2. 部署阶段
3. 调试阶段
这样的话,我们就可以不需要远程机器连接的情况下编译代码,这个特性在持续集成环境,或者某些场景(例如,有时候我们仅需要在本机构建一次来修复一个小问题,然后提交到自动化测试环境)中十分有用。
如果能提供部署和调试阶段的支持就更好了:这样我们就可以直接在VS中部署程序并直接在远程机器上调试。
我们当前还是使用Visual Studio来调用我们自己的构建工具来编译我们的项目,但是VS的Linux Workload还支持基于MSBuild的Linux工程。目前,我们还没有时间去尝试这个,当然,如果使用MSBuild来编译Linux项目确实奏效的话,我们是十分乐意尝试一下的。

我们一直以来都在和VS团队一起协作来开发Linux组件,在将来的发布版本中,我们希望能做到:
1. 将构建完全从部署和调试中剥离出来,这样就可以实现本机交叉编译。
2. 在Linux Makefile中支持”incremental”构建和部署环境监测功能,这样我们就不需要每次都重新编译一个解决方案下的所有工程(有些大型解决方案有超过500个工程)。这个特性主要是为了能跟家快速的迭代。
3. 我们已经请求VS团队将WSL直接调试添加到Linux Makefile工程中,目前在我们的编译环境中,Linux Makefile工程还不支持WSL直接编译,所有我们还是需要通过SSH连接到WSL中来进行调试,这意味着我们需要在WSL上运行sshd后台服务。这个支持已经集成到MSBuild Linux工程和CMake工程了,但是对于Makefile工程,还是未能支持。
4. 尝试将我们的代码迁移到MSBuild Linux工程并和微软紧密合作,实现本机编译(使用我们的工具链)。这将可以解决上面提到的Makefile工程中国的”incremental”编译的问题。
以上这些对我们来说,确实很重要。我们的开发人员可以使用功能他们熟悉的开发平台和IDE来工作,同时还可以继续在开发和调试Linux程序。

总结
文章到这里就结束了。我们可以看到,VS团队确实不在以Windows为宇宙中心了,因为在这个生态系统中,Linux将扮演者越来越重要的角色:它不在是那种”可有可无”的玩意了。

标签:

评论已关闭。