ModuleRules(XXX.build.csファイル)について

この記事は[Unreal Engine 4 (UE4) Advent Calendar 2015](http://qiita.com/advent-calendar/2015/ue4) 10日目の記事になります。

公式にドキュメントが追加されたようです。

https://docs.unrealengine.com/4.27/ja/ProductionPipelines/BuildTools/UnrealBuildTool/ModuleFiles/

https://docs.unrealengine.com/4.27/ja/ProductionPipelines/BuildTools/UnrealBuildTool/TargetFiles/

↓は古い情報です。

#ModuleRulesって何すんの？

本来ならVisualStudioやXCodeのプロジェクトプロパティで設定できるビルドのオプションを設定できる機能はこんなのがあります。

①コンパイルの最適化、デバッグシンボルの設定
②include、ライブラリのパス
③使用するライブラリ名の指定

UnrealEngineはこれらの設定が書かれているプロジェクトファイルを自動に作るようになっているので、UnrealEngine側にこれらの設定を伝えるために宣言する必要があります。
XXX(モジュール名).build.csファイルに記述されているModuleRulesクラス内で宣言することができます。
※定義はRulesComplier.csにて宣言されていますので興味がある方は一度目を通してみるのも良いかと思います。

①はUnrealEngine側でコントロールされているので特に設定することはありませんが、
②と③はアプリによって、いろいろなサードパーティ制のライブラリを使う際に必要となるので
今回は設定をする必要がある②と③を中心にまとめました。

#PC開発関連
##インクルードパスの指定
`List<string> PublicIncludePaths`
`List<string> PrivateIncludePaths`
PublicとPrivateは他のモジュールへ公開するかどうかの設定になります。
プラグインを作成する方は設計する段階で公開する必要があるか考えましょう。
※通常ゲーム用のModuleRulesの場合はPrivateで問題ないと思います。

##依存関係のあるモジュールの指定
`List<string> PublicDependencyModuleNames`
`List<string> PrivateDependencyModuleNames`
使用するEngine側のモジュールやプラグインの指定はこれを使用します。
Engineのモジュールはこちらを参考にして見てください。

##実行時に必要な追加モジュール名
`List<string> DynamicallyLoadedModuleNames`
上記の「依存関係のあるモジュール」の設定で基本的に問題無く動作するのですが、
C++ソースコード上では使用しないがブループリントでは使用するプラグインはこの設定にしたほうが良いと思います。
実は、C++のビルド時は依存関係の設定が無くてもエディタ上ではプラグインが有効になっていれば、この設定を行わなくてもエディタからの起動時は動作してしまいます。
しかし、この設定を行わないとパッケージビルドに含まれず、パッケージビルドの起動時にエラーが発生してしまい、再度作りなおすはめになるので気をつけましょう。

##モジュール名によるインクルードパスの指定 
`List<string> PublicIncludePathModuleNames` 
`List<string> PrivateIncludePathModuleNames`  
他のモジュール内のヘッダーファイルをインクルードする場合、モジュール名で指定できます。

##ライブラリパスの指定
`List<string> PublicLibraryPaths`
サードパーティ製のライブラリをリンクする場合そのライブラリが入っているディレクトリパスを指定します。

##追加するライブラリファイル名
`List<string> PublicAdditionalLibraries`
サードパーティ製のライブラリをリンクする場合ライブラリファイル名をこれで指定します。

##参照するDLLファイルの指定
`List<string> PublicDelayLoadDLLs` 
モジュールやプラグイン自体はDLLになりますが、それ以外のサードパティ製のDLLをビルドシステムに設定する必要がある場合指定します。

##循環参照として扱われるべきモジュールの依存関係のリスト。
`List<string> CircularlyReferencedDependentModules`
なるべく循環参照はしない設計にするのが好ましいのですが、どうしても循環参照をしないとダメな場合はこの設定を使用します。
このモジュールは、既にパブリックまたはプライベートの依存モジュールリストに追加されている必要があるそうです。

##システムインクルードパスの指定  
`List<string> PublicSystemIncludePaths`
`#include <>`での宣言している場合システムインクルードと認識されますので、こちらを使ってフォルダのパスを指定する必要があります。
古いソースを使う場合、修正する箇所が多い、もしくはライセンスの関係で修正できない場合は使うこととなるでしょう。
(多分普通に使うケースは少ないと思います。)

##定数追加(#define)
`List<string> Definitions`
[こちら](http://historia.co.jp/archives/3636)のヒストリアさんのHPでも解説されていますが環境変数(#define)を宣言することができます。
記述はC#ですので条件により定義するかどうか分けることができます。

##依存ファイルの指定
`List<RuntimeDependency> RuntimeDependencies`
プロジェクトをパッケージ化する時にUnrealEngineは必要なファイルとみなしたものだけ
パッケージに含めるようにファイルをコピーをします。

そのため、サードパーティ製のライブラリの独自ファイルやDLLはUnrealEngineが必要がないと判断し、
パッケージに含まれません。独自に追加したファイルを製品パッケージに含めることがこの設定でできます。

**使用例**

ファイルパスはRuntimeDependencyを作成して指定します。
``
RuntimeDependencies.Add(new RuntimeDependency( Filename ) );
``

#Mac・iOS関連
注意：一応、簡単に調べたことをまとめていますが、実際に動作検証は行っていないので
参考程度にしてください。
##フレームワーク名の指定
`List<string> PublicFrameworks`
Mac、iOSではライブラリファイル名の他にフレームワークの指定が必要になるので
使用するフレームワークをこれで指定します。

##Weak Linkするフレームワーク名の指定 
`List<string> PublicWeakFrameworks`
Mac、iOSの開発経験が少ない自分はよくわかっていないのですが、
バージョン違いに対応するためのLinkの機能だそうです。

##追加するリソースファイルの指定
`List<UEBuildBundleResource> AdditionalBundleResources`
XCodeのプロジェクで追加しているリソースファイル(画像、plistなどのファイル)はこれで指定できるようです。

##シャドーファイルの指定
`List<string> PublicAdditionalShadowFiles`
UE4はWindows上でC++を使用したios開発を行う際、別なMacを利用しリモートビルドを行います。
リモートビルドするMacに転送する必要なファイルをこれで指定します。


#おまけ
自分でプラグインを作る場合、知っておくと便利なパスの取得方法を紹介します。

##エンジンサードパーティフォルダのパス取得

`UEBuildConfiguration.UEThirdPartySourceDirectory`

※`using UnrealBuildTool;`の宣言が必要です。

`Engine\Source\ThirdParty`フォルダにライブラリをおいてリンクする場合これを使用します。


##モジュールのディレクトリ プロパティ
上記の方法だと、`Engine\Source\ThirdParty`フォルダ限定になります。
できれば、公開のことを考えるとモジュールと同じフォルダ階層にライブラリは入れておきたいです。
それを解決する方法が公式Wikiに書いています。

参考 Linking Static Libraries Using The Build System
https://wiki.unrealengine.com/Linking_Static_Libraries_Using_The_Build_System
ModuleRulesに以下の処理を追加することによりモジュールと同じフォルダ階層にアクセスすることができます。

```
using System.IO;
 
public class UE4Magic : ModuleRules
{
    private string ModulePath
    {
        get { return Path.GetDirectoryName( RulesCompiler.GetModuleFilename( this.GetType().Name ) ); }
    }
 
    private string ThirdPartyPath
    {
        get { return Path.GetFullPath( Path.Combine( ModulePath, "../../ThirdParty/" ) ); }
    }
 
    [Constructor]
}
```

#まとめ
ざっとまとめてみましたが、外部機器やミドルウェアをUnrealEngineで使えるようにしたいと思った方には参考になったら幸いです。

明日は@shop_0761さんのと@shsnow23さんです。