前文說到ue3開始,虛幻就使用了unrealbuildtool(以下簡稱ubt)來編譯和生成代碼。
為什麼這麼做而不是使用vs是很好了解的:因為vs跨平台會比較麻煩。像虛幻這樣體量的工程,單為工程做一次vs配置就基本是一天的時間
而且ue4還不像ue3那樣就十幾個工程,把所有uproject都看做工程的話,得幾十了。依賴關系複雜度幾何增長,用vs的工具去維護……而且要維護各個平台和配置……再加上維護完後mac、linux還得維護一遍……
但是為什麼不使用成熟的cmake呢,私以為可能是因為ubt裡有一系列錯綜複雜的規則,用cmake制作出來,即便可讀性ok,調試也比較麻煩。而且cmake對引擎使用者提出了一定的要求,而ubt則相對簡單——隻要你不糾結它如何實作。
官網的這篇文章詳細解釋了為什麼要做一個build tool出來:
what are the advantages of generating project files?
可以先看看ubt的基本規則:
目前說來,虛幻的所有代碼集中在下面幾個檔案夾裡:
<root>的source,這個檔案夾裡主要是引擎代碼。
其中:
source/runtime裡主要是引擎的核心代碼。
source/developer裡似乎主要是一些工具工程。
source/editor裡是編輯器相關代碼。
source/programs裡是引擎使用中需要用到的工具。比如ubt、unrealheadertool、swarm(分布式光照計算系統)等等。
source/thirdparty裡是各種第三方庫。
<root>的plugin,這個檔案夾裡有各式各樣的plugin實作。特殊的是plugin的組織中需要多一個uplugin,可能是plugin下可能會有一些資源什麼的吧。我們後面再來看uplugin。
<工程項目>的source,如果是代碼工程的話。
ubt目前隻認這幾個檔案夾,也就是說,如果你要為引擎擴充功能,您隻能在這些檔案夾裡建立自己的工程。這一點是在ubt裡寫死的,有代碼的可以關注一下ubt工程的findallrulessourcefiles這個方法。
在這些檔案夾裡,您可以搜尋到大量的*.build.cs檔案,這些build.cs就是虛幻的工程組織核心,基本上,每個build檔案都可以被視為一個工程檔案,而build檔案所在的檔案夾可以被視為此工程的根目錄。接下來,我們不妨稱這些擁有build.cs的檔案夾為工程。ubt一開始會先去找所有的build.cs,把它們放在一起生成一個臨時的dll。然後基于它們逐個進行一系列的代碼分析工作,最後調用指令行進行編譯和連接配接過程。
對于每個工程而言,代碼一般都散落在下面幾個檔案夾:
classes:如果你在工程根目錄下寫了個classes,就相當于告訴ubt這些檔案是要用unrealheadertool來生成運作時反射資訊的。是以,這個檔案夾裡頭檔案的寫法必須符合可反射類的寫法規範。
還記得虛幻的哪些類是可反射的嗎?對了,所有uobject的派生類包括aactor的派生類。具體是否有所驗證還沒看,不過最好是按照這個節奏來。
規範上無非主要就是ustruct、uclass這些宏,抄幾個就能找到感覺,或者用編輯器的類生成功能也可。
看起來,虛幻引擎釋出時(不是通過編譯生成,而是通過launcher下載下傳的那種),這些classes檔案是随引擎釋出的,友善不具備全代碼的mod愛好者和blueprint開發者們來制作遊戲。
public:公共頭檔案,跟classes一樣随着引擎釋出而釋出,是以這裡一般都是些比較開放的接口,比如子產品入口、功能核心接口什麼的。基本上這些接口沒有廢話,很清晰,跟實作相關的細節隐藏得非常好。與classes相同,如果你的工程裡有public,那麼裡面的.h就會被當作public來。
private:這個檔案夾似乎不是虛幻定死的,也就是似乎可以不用private的名字,或者多來幾個檔案夾什麼的。除了uht中有一段代碼與之有一定關聯之外,ubt裡是完全沒有跟這個有關的東西。它裡面基本上就是各種實作代碼,以及要在實作間共享的頭檔案。你也可以建立其他類似的檔案夾,隻需要build.cs裡寫上相應的檔案夾名即可:

此外還有需要注意的地方是source根目錄下的target.cs檔案,target的最終目标一般都是可執行檔案,可以說,target是整個生成期的入口,生成會首先從找到target開始,如果沒有target或者找不到,就會直接失敗。
此外,需要注意的是,target.cs裡面寫的類的類名,必須是target.cs的檔案名加target,例如:sample.target.cs,其類名必須是sampletarget。ubt的gettargettypeandrulesinstance方法裡印證了這一點。
ubt裡面還是有不少限定用法的,target就是其中之一,虛幻是一個比較強調命名的引擎,改名有很多麻煩,最好是能夠一步到位。
今天抽空看了看文檔,大概跟了跟ubt的流程,明天繼續。