UE構建基礎和實踐:四、使用指令碼打包

2023-07-25 12:00:51

序言

使用UE版本為UE5.20
在實際專案中,我們常常使用自動化指令碼來進行構建,它可以增加我們的生產效率,並降低人為操作帶來的失誤風險。

BuildGraph

BuildGraph UE官方提供的構建指令碼系統,它可以讀取對應的XML指令碼實現自動化打包。
BuildGraph相關的參考BuildGraph | UE檔案
重點是它相關的語法

自動化指令碼

自動化指令碼我打算使用(.bat / .sh)「殼」檔案作為入口,執行py指令碼並拉起執行BuildGraph命令的UAT,並且設定相關的引數。

Build.bat

python3 Build.py

執行該目錄的py指令碼

Build.py

import sys
import os

def main(argv):
    ProjectName             = "BuildTest"
    ProjectDir              = r"E:/AllProject/UE_5_2_0/BuildTest/"
    Platform                = "Android"
    ClientConfig            = "Development"
    OutputDir               = r"E:/AllProject/UE_5_2_0/BuildTest/PakOutputX"
    SkipBuildProject        = "true"
    SkipBuildEditor         = "true"
    Unrealexe               = r"E:\UE\UE_4.27_Source\UnrealEngine\Engine\Binaries\Win64\UnrealEditor-Cmd.exe "
    EditorIOPort            = "54689"

    cmd = f"-set:ProjectName={ProjectName} -set:ProjectDir={ProjectDir} -set:Platform={Platform}" \
            f" -set:ClientConfig={ClientConfig} -set:OutputDir={OutputDir} -set:SkipBuildProject={SkipBuildProject}" \
                f" -set:SkipBuildEditor={SkipBuildEditor} -set:Unrealexe={Unrealexe} -set:EditorIOPort={EditorIOPort}"


    fileDir     = r"E:\UE\UE_4.27_Source\UnrealEngine\Engine\Build\BatchFiles\RunUAT.bat"
    target      = "MyBuild"
    script      = r"E:\AllProject\UE_5_2_0\BuildTest\BuildTools\Build.xml"

    cmd = f"{fileDir} BuildGraph -Script={script} -Target={target} {cmd}"

    print(f"cmd: {cmd}")

    ret = os.system(cmd)

    if ret == 0:
        print(f"run build ret val = {ret}")
    else:
        raise Exception("project build faild!")
        pass


if __name__ == "__main__":
    main(sys.argv[1:])
    input("press any to close")

這個py主要是拼接了引數到命令裡面,方便設定命令。命令拼接好後拉起RunUAT.bat執行BuildGraph命令並傳遞命令引數。

注意target是我們後面Build.xml指令碼裡的MyBuild那個Agent

cmd: 列印了拼接的命令。

BuildGraph指令碼Build.xml

<?xml version='1.0' ?>
<BuildGraph xmlns="http://www.epicgames.com/BuildGraph" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.epicgames.com/BuildGraph ../../Engine/Build/Graph/Schema.xsd">
    <!-- Base Options -->
    <Option Name="ProjectName"         DefaultValue=""                Description="project path like D:\UEProj\BuildTest\BuildTest.uproject" />
    <Option Name="ProjectDir"          DefaultValue=""                Description="for run BuildGraph scripts uproject, same as ProjectPath usually" />
    <Option Name="Platform"            DefaultValue=""                Description="target platform like Windows, Android, IOS and so on"/>
    <Option Name="ClientConfig"        DefaultValue="Development"     Description="config like Debug, Development, Shipping" />
    <Option Name="OutputDir"           DefaultValue=""                Description="" />
    <Option Name="SkipBuildProject"    DefaultValue="true"            Description="skip build project default = true" />
    <Option Name="SkipBuildEditor"     DefaultValue="true"            Description="skip build editor default = true " />
    <Option Name="Unrealexe"           DefaultValue=""                Description="like UnrealEngine\Engine\Binaries\Win64\UnrealEditor-Cmd.exe" />
    <Option Name="EditorIOPort"        DefaultValue="64752"           Description="ensure the port unuse" />


    <!-- Advance Options-->
    <Option Name="WithClean"           DefaultValue="false"           Description="clean before build" />
    <Option Name="WithCook"            DefaultValue="true"            Description="cook assets" />

    <Property Name="ProjectFullName"   Value="$(ProjectDir)$(ProjectName).uproject" />
    
    <!-- Base -->
    <Property Name="BaseCmd"           Value="-project=$(ProjectFullName) -ScriptsForProject=$(ProjectFullName)" />

    <!-- Check SDK Command -->
    <Property Name="CheckSDKCmd"       Value="Turnkey -command=VerifySdk -platform=Android -UpdateIfNeeded"            If="$(Platform) == Android" />

    <!-- Editor IO Command -->
    <Property Name="EditorIOCmd"       Value="-EditorIO -EditorIOPort=$(EditorIOPort)" />

    <!-- Sub Command -->
    <Property Name="CleanCmd"          Value="" />
    <Property Name="CleanCmd"          Value="-clean"                                              If="$(WithClean)" />

    <Property Name="HeadCmd"           Value="BuildCookRun -project=$(ProjectFullName) -target=BuildTest -platform=$(Platform)" />
    <Property Name="HeadCmd"           Value="$(HeadCmd) -cookflavor=ASTC"                         If="$(Platform) == Android" />
    <Property Name="HeadCmd"           Value="$(HeadCmd) -prereqs -nop4 -utf8output -Unrealexe=$(Unrealexe)" />

    <Property Name="BuildCmd"          Value="-build -clientconfig=$(ClientConfig)" />
    <Property Name="BuildCmd"          Value="$(BuildCmd) -nocompile -nocompileuat"                If="$(SkipBuildProject)" />
    <Property Name="BuildCmd"          Value="$(BuildCmd) -nocompileeditor -skipbuildeditor"       If="$(SkipBuildEditor)" />

    <Property Name="CookCmd"           Value="-cook -iostore -compressed" />
    <Property Name="CookCmd"           Value="$(BuildCmd) -skipcook"                               If="$(WithCook) == false" />


    <Property Name="PakCmd"            Value="-pak" />

    <Property Name="StageCmd"          Value="-stage" />

    <Property Name="PackageCmd"        Value="-package" />

    <Property Name="ArchiveCmd"        Value="-archive -archivedirectory=$(OutputDir)" />

    <!-- Client Command -->
    <Property Name="ClientCmd"         Value="$(BaseCmd) $(CheckSDKCmd) $(EditorIOCmd) $(HeadCmd) $(BuildCmd) $(CookCmd) $(PakCmd) $(StageCmd) $(PackageCmd) $(ArchiveCmd)" />

    <!-- Build -->
    <Agent Name="MyBuild"       Type="BuildOnWindows">
        <Node Name="MyBuildNode">
            <Log Message="BuildCookRun with arguments: $(ClientCmd)" />
            <Command Name="BuildCookRun"        Arguments="$(ClientCmd)" />
        </Node>
    </Agent>

</BuildGraph>

這個指令碼就是進行根據條件拼接BuildCookRunUAT命令,它的引數可以在上一章的使用UAT打包構建的命令中找到(也可以參考後面範例的輸出紀錄檔)。
BuildGraph 的命令的Target是MyBuild,MyBuild執行了BuildCookRun這個Command並把拼接命令傳遞過去。

紀錄檔和執行結果

紀錄檔

圈出的地方分別是py和Build.xml輸出的命令列

執行結果

結語

  • 在打包的時候使用BuildGraph這一步不是必須的,完全可以直接使用py拼接BuildCookRun的命令,拉起UAT執行。不過BuildGraph在構建Editor時因為有現成的指令碼會更方便些。
  • 這是在UE5.20環境下測試的,在UE4上應該是大同小異的
  • 這個是基於基本打包命令實現的,實際生產環境會控制更多的引數以及其他一些客製化化的修改