11.14 EA:VS對Linux上的支持,讓我們的開發人員很Happy

引子(有些地方叫楔子?)

美國藝電公司(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++”這一個組件。

EA:VS對Linux上的支持,讓我們的開發人員很Happy

然後,我們就可以創建一個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的一個開源庫。

EA:VS對Linux上的支持,讓我們的開發人員很Happy

我們可以看到,我在代碼中添加了一斷點,同時我配置了在運行時使用WSL這一選項,所以,當我調試這個程序時,VS將會在WSL中啟動並連接到VS的GDB調試器,這並不需要拷貝程序到Linux機器中。
通過設置Remote Build Root, Project and Deploy directories選項,並設定好WSL的路徑到當前Windows上的相同目錄即可。

EA:VS對Linux上的支持,讓我們的開發人員很Happy

下面是我在進行調試並觸發斷點後,繼續執行的一個例子。


EA:VS對Linux上的支持,讓我們的開發人員很Happy

在遠程Linux機器上構建工程

當我們不使用WSL,而是選擇一臺遠程Linu機器來搭建編譯環境時,唯一令我們擔心的是生成的執行文件如何部署以及其起來的庫文件和資源文件的問題。
我們的做法是,創建一個源文件來映射到遠程機器中,然後使用Visual Studio的編譯後實踐功能來拷貝這個文件。在工程屬性的”Build Events” -> “Post-Build Event” -> “Additional Files To Copy”中,我們可以指定需要拷貝到遠程機器中的文件列表,這些文件將會在構建成功完成之後自動拷貝過去。有了這個功能,我們就可以確保在我們調試程序的時候,這些執行文件已經存在於遠程機器上面了。


EA:VS對Linux上的支持,讓我們的開發人員很Happy

從上圖中可以看到將待拷貝的文件映射到目標路徑的語法,這在兩個不同的文件系統中互相映射文件是非常方便的。

我們還想要更多

上面的做法中,有一個不足之處。執行文件的部署只能發生在構建階段,我們希望能在以下三個不同的階段都能在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將扮演者越來越重要的角色:它不在是那種”可有可無”的玩意了。


分享到:


相關文章: