[UE4]Module之間的相依性

在建立完專案並打開Primary Game Module中的Build.cs後,可以看到裡面預設了幾個相依的Module。

HorizonTutorialGame.Build.cs
using UnrealBuildTool;

public class HorizonTutorialGame : ModuleRules

{

public HorizonTutorialGame(ReadOnlyTargetRules Target) : base(Target)

{

PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

PublicDependencyModuleNames.AddRange(new string[] { “Core”, “CoreUObject”, “Engine”, “InputCore” });

PrivateDependencyModuleNames.AddRange(new string[] { });

}

}

Code 2.7.1 “Core”、”CoreUObject”、”Engine”、”InputCore”為引擎核心的幾個Module

其中:

l Core Module位於:${UE4_ENGINE_ROOT}\Engine\Source\Runtime\Core\Core.Build.cs

l CoreUObject Module位於:${UE4_ENGINE_ROOT}\Engine\Source\Runtime\CoreUObject\ CoreUObject.Build.cs

l Engine Module位於:${UE4_ENGINE_ROOT}\Engine\Source\Runtime\Engine\Engine.Build.cs

l InputCore Module位於:${UE4_ENGINE_ROOT}\Engine\Source\Runtime\InputCore\ InputCore.Build.cs

當我們把該Module的名字加進PublicDependencyModuleNames之後有什麼特別的意義?

我們知道,在C++中要對h檔進行include之前,我們必須先提供include search path,讓編譯器知道目標檔案在電腦上的位置。當我們將想要相依的Module加入到PublicDependencyModuleNames之後,引擎就會自動去尋找「Engine」跟專案「${PROJECT_NAME}」底下的Source還有Plugins所有的Build.cs,定位出相關Module的位置後,再把該Module底下的Public以及Classes這二個資料夾加入到這個Module中的include search path當中。因此,當我們在對該Module進行C++程式編寫的時候,就可以自由的對相依Module放在Public跟Classes中的.h檔進行include的動作。

只是從上面的例子我們發現除了,PublicDependencyModuleNames之外,還有PrivateDependencyModuleNames提供給我們用來設定Module之間的相依性。到底這二個List之間有什麼不同?

其實對於終端,沒有任何其他人會來依賴我們的Game Module而言,要將這些依賴性放在其中那個清單中,其實並沒有什麼差別,但是,若是我們這個Module本身的設計是有可能給其他人引用的話,例如Plugin中Module,就必須要思考一下這些依賴性到底要放在PublicDependencyModuleNames還是PrivateDependencyModuleNames中。

當我們放在PublicDependencyModuleNames中的話,代表的便是我們可以很放心的在我們的.h中include任何相依Module的檔案,因為在Public清單上的相關module,其include search path會曝露給相依鍊(dependency chain)上的所有Module;相反的,若我們放在PrivateDependencyModuleNames時,我們就必需把所有include到相依Module的檔案,都放到Private這個資料夾下的.h或.cpp中進行include。

一個簡單的規則是:在Public或Classes這二個folder中include到的.h所在module就放在PublicDependencyModuleNames,其餘就放在PrivateDependencyModuleNames。

例如下面的例子,我們設計了二個Module:HorizonTutorialGame跟HorizonTutorialGameEditor,其中HorizonTutorialGame會去依賴Engine Plugin中的Paper2D,見Figure 2.7.1。

image

Figure 2.7.1 Paper2D這個Module存在於引擎${UE4_ENGINE_ROOT}\Engine\Plugins\2D\Paper2D\Source\Paper2D,而其他二個Module則是我們所建立的Game Module。

由於HorizonTutorialGameEditor是最末端的GameModule,因此不管是把相依的HorizonTutorialGame放在PublicDependencyModuleNames或PrivateDependencyModuleNames都不會有任何的影響,但HorizonTutorialGame就不同了,其所依賴的Paper2D若是Public資料夾下的任何一個檔案有被使用到,則Paper2D這個Module就必須要放在PublicDependencyModuleNames。

在這裡,將HorizonTutorialGame所依賴的Paper2D放到PublicDependencyModuleNames所代表的意義,便是將Paper2D的include search path同時曝露給HorizonTutorialGame跟HorizonTutorialGameEditor。若是把Paper2D放到HorizonTutorialGame中的PrivateDependencyModuleNames,則就只有HorizonTutorialGame這個Module可以include的到Paper2D下的Public跟Classes下的檔案,若是HorizonTutorialGameEditor也想要include到Paper2D中的類別,我們就必須手動到HorizonTutorialGameEditor下的build.cs中加上依賴才行,其依賴關係就會變成如Figure 2.7.2的樣子,徒增不少複雜性與使用上的困擾。

image

Figure 2.7.2 當HorizonTutorialGame將Paper2D設成PrivateDependencyModuleNames時,則相依的HorizonTutorialGameEditor若也想要include到Paper2D中的類別,就必須自己手動再加入相依關係。

Leave a Reply

Your email address will not be published. Required fields are marked *