BuildGraph:构建支持多平台打包的二进制引擎

Error of Not Importing Provision

Other errors during compilation:

1
2
3
4
5
6
7
8
9
10
11
****** [6/11] Compile UE4Game IOS

Reading local file list from C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Saved\BuildGraph\Compile UnrealHeaderTool Mac\Tag-Compile UnrealHeaderTool Mac.xml
Reading local file list from C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Saved\BuildGraph\Update Version Files\Tag-Update Version Files.xml
Reading shared manifest from C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Saved\BuildGraph\Compile UnrealHeaderTool Mac\Manifest.xml
Running: C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Binaries\DotNET\UnrealBuildTool.exe UE4Game IOS Development -NoUBTMakefiles -nobuilduht -precompile -allmodules -nolink -nodebuginfo -Manifest=C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Intermediate\Build\Manifest.xml -NoHotReload -log="C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Programs\AutomationTool\Saved\Logs\UBT-UE4Game-IOS-Development.txt"
[Remote] Using remote server 'xx.xx.xx.xxx' on port 22 (user 'buildmachine')
[Remote] Using private key at C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Build\NotForLicensees\SSHKeys\10.75.27.129\buildmachine\RemoteToolChainPrivate.key
[Remote] Using base directory '/Users/buildmachine/UE4/Builds/lipengzha-PC2'
ERROR: Unable to find mobile provision for UE4Game. See log for more information.
Took 4.0300959s to run UnrealBuildTool.exe, ExitCode=6

This is because the provision was not configured during the engine compilation, and it needs to be set in Engine/Config/BaseEngine.ini.

Here you can only specify the name of the provision file. The code in UEBuildIOS.cs will look for it under the path C:\Users\lipengzha\AppData\Local\Apple Computer\MobileDevice\Provisioning Profiles.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected IOSProvisioningData(IOSProjectSettings ProjectSettings, bool bIsTVOS, bool bForDistribtion)
{
// ...
if(!string.IsNullOrEmpty(MobileProvision))
{
DirectoryReference MobileProvisionDir;
if(BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
{
MobileProvisionDir = DirectoryReference.Combine(new DirectoryReference(Environment.GetEnvironmentVariable("HOME")), "Library", "MobileDevice", "Provisioning Profiles");
}
else
{
MobileProvisionDir = DirectoryReference.Combine(DirectoryReference.GetSpecialFolder(Environment.SpecialFolder.LocalApplicationData), "Apple Computer", "MobileDevice", "Provisioning Profiles");
}

FileReference PossibleMobileProvisionFile = FileReference.Combine(MobileProvisionDir, MobileProvision);
if(FileReference.Exists(PossibleMobileProvisionFile))
{
MobileProvisionFile = PossibleMobileProvisionFile;
}
}
// ...
}

This process can also be imported through the engine, which requires not just importing the provision but also importing the certificate (which can also be imported via iPhonePackager):

If not importing, the following error will occur:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
****** [7/12] Compile UE4Game IOS

Reading local file list from C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Saved\BuildGraph\Compile UnrealHeaderTool Mac\Tag-Compile UnrealHeaderTool Mac.xml
Reading local file list from C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Saved\BuildGraph\Update Version Files\Tag-Update Version Files.xml
Reading shared manifest from C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Saved\BuildGraph\Compile UnrealHeaderTool Mac\Manifest.xml
Running: C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Binaries\DotNET\UnrealBuildTool.exe UE4Game IOS Development -NoUBTMakefiles -nobuilduht -precompile -allmodules -nolink -nodebuginfo -Manifest=C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Intermediate\Build\Manifest.xml -NoHotReload -log="C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Programs\AutomationTool\Saved\Logs\UBT-UE4Game-IOS-Development.txt"
[Remote] Using remote server '192.168.1.123' on port 22 (user 'buildmachine')
[Remote] Using private key at C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Build\NotForLicensees\SSHKeys\192.168.1.123\buildmachine\RemoteToolChainPrivate.key
[Remote] Using base directory '/Users/buildmachine/UE4/Builds/lipengzha-PC3'
[Remote] Uploading C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Intermediate\Remote\UE4Game\IOS\Development\com.xxxxx.xxxx.xx_Development_SignProvision.mobileprovision
[Remote] Exporting certificate for C:\Users\lipengzha\AppData\Local\Apple Computer\MobileDevice\Provisioning Profiles\com.xxxxx.xxxx.xx_Development_SignProvision.mobileprovision...
Executing iPhonePackager ExportCertificate C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Source -provisionfile C:\Users\lipengzha\AppData\Local\Apple Computer\MobileDevice\Provisioning Profiles\com.xxxxx.xxxx.xx_Development_SignProvision.mobileprovision -outputcertificate C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Intermediate\Remote\UE4Game\IOS\Development\Certificate.p12
CWD: C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Binaries\DotNET\IOS
Initial Dir: C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Source
Env CWD: C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Binaries\DotNET\IOS
BranchPath = lipengzha-PC3/C/BuildAgent/workspace/FGameEngine/Engine/Engine/Binaries --- GameBranchPath = lipengzha-PC3/C/BuildAgent/workspace/FGameEngine/Engine/Engine/Binaries

----------
Executing command 'ExportCertificate' '' ...
Looking for a certificate that matches the application identifier '9TV4ZYSS4J.com.xxxxx.xxxx.xx'
.. Provision entry SN '61B440405D86B84D' matched 0 installed certificate(s)
.. Failed to find a valid certificate that was in date
IPP ERROR: Failed to find a valid certificate

ERROR: IphonePackager failed.
Took 2.9281688s to run UnrealBuildTool.exe, ExitCode=6

After resolving the issues above, the BuildGraph process can be executed normally, exporting the binary engine compiled according to the engine code, and upon startup, it can be seen that packaging for Windows/Android/IOS is available.

## Error Troubleshooting

No certificate for team xxxx matching

This issue is likely caused by a mismatch between the configured certificate in the project and the one in the system (or a single mobileProvision corresponding to multiple certificates). After performing the following steps, a machine restart is needed for the changes to take effect.

If you encounter the following error message:

1
Code Signing Error: No certificate for team '9TV4ZYSS4J' matching 'iPhone Developer: Created via API (JDPXHYVWYZ)' found: Select a different signing certificate for CODE_SIGN_IDENTITY, a team that matches your selected certificate, or switch to automatic provisioning.

Solution:

  1. Clean up the extra mobileprovision files in ~/Library/MobileDevice/Provisioning Profiles on Mac.
  2. Clear any expired developer certificates in the Mac keychain.
  3. Reimport the mobileprovision and certificates.

Note: The name of the imported mobileprovision file must match the MobileProvision specified in BaseEngine.ini.

errSecInternalComponent error

Troubleshooting steps:

Execute the codesign command directly on the machine’s bash to see if a password prompt appears. If it does, it indicates that the keychain is locked.
Signing command:

1
codesign --force --sign 36126F8C735011DCC435309E03BC0B85C28CE7CB --verbose --preserve-metadata=identifier,entitlements,flags --timestamp=none /Users/buildmachine/UE4/Builds/Client/Binaries/IOS/Payload/FGame.app

Method One

This is due to the lack of permission to access the keychain when calling /usr/bin/codesign via ssh. You can use the following command to unlock in ssh:

1
security unlock-keychain -p password login.keychain

During UE remote builds, you can run this command to unlock the keychain in the current ssh environment, allowing subsequent signing to execute normally. Modify the Engine\Build\BatchFiles\Mac\Build.sh file to include the following content before calling UBT for compilation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/sh

cd "`dirname "$0"`/../../../.."

# Setup Mono
source Engine/Build/BatchFiles/Mac/SetupMono.sh Engine/Build/BatchFiles/Mac

if [ "$4" == "-buildscw" ] || [ "$5" == "-buildscw" ]; then
echo Building ShaderCompileWorker...
mono Engine/Binaries/DotNET/UnrealBuildTool.exe ShaderCompileWorker Mac Development
fi
echo unlock mac keychain...
security unlock-keychain -p password login.keychain
echo Running command : Engine/Binaries/DotNET/UnrealBuildTool.exe "$@"
mono Engine/Binaries/DotNET/UnrealBuildTool.exe "$@"

ExitCode=$?
if [ $ExitCode -eq 254 ] || [ $ExitCode -eq 255 ] || [ $ExitCode -eq 2 ]; then
exit 0
else
exit $ExitCode
fi

As the Build.sh will be passed to Mac via RSync during compilation, the following log can be seen:

1
2
3
4
5
6
7
8
9
10
11
[Remote] Executing build
Running bundled mono, version: Mono JIT compiler version 5.16.0.220 (2018-06/bb3ae37d71a Fri Nov 16 17:12:11 EST 2018)
unlock mac keychain...
Running command : Engine/Binaries/DotNET/UnrealBuildTool.exe UnrealHeaderTool Mac Development -SkipRulesCompile -XmlConfigCache=/Users/buildmachine/UE4/Builds/lipengzha-PC2/C/BuildAgent/workspace/FGameEngine/Engine/Engine/Intermediate/Build/XmlConfigCache.bin -precompile -allmodules -Log=/Users/buildmachine/UE4/Builds/lipengzha-PC2/C/BuildAgent/workspace/FGameEngine/Engine/Engine/Programs/AutomationTool/Saved/Logs/UBT-UnrealHeaderTool-Mac-Development_Remote.txt -Manifest=/Users/buildmachine/UE4/Builds/lipengzha-PC2/C/BuildAgent/workspace/FGameEngine/Engine/Engine/Intermediate/Remote/UnrealHeaderTool/Mac/Development/Manifest.xml
Target is up to date
Deploying UnrealHeaderTool Mac Development...
Deploying now!
Total execution time: 1.01 seconds
[Remote] Downloading C:\BuildAgent\workspace\FGameEngine\Engine\Engine\Intermediate\Remote\UnrealHeaderTool\Mac\Development\Manifest.xml
[Remote] Downloading build products
receiving file list ... done

This way, the keychain will be unlocked with every build, avoiding signing errors caused by lack of access to codesign during ssh connection.

Note: It is also necessary to check whether the value of SigningCertificate in BaseEngine.ini has been specified.

Method Two

If the intermediate developer certificate from Apple in the system is expired, it will also lead to this issue. The solution is to import the new Apple developer root certificate:

Delete the Apple Worldwide Developer Relations Certification Authority from the keychain, and then re-download and import a new one from the link above.

Method Three

Check in the keychain if the certificate was imported under Login or System. If it is in Login, delete it and re-import it to System.

Invalid trust settings

If you see the following error in the log:

1
2
Code Signing Error: Invalid trust settings. Restore system default trust settings for certificate "iPhone Developer: Created via API (JDPXHYVWYZ)" in order to sign code with it.
Code Signing Error: Code signing is required for product type 'Application' in SDK 'iOS 13.6'

This is due to a change in trust settings for the certificate in the Mac keychain. Change it back to Use System Defaults to resolve the issue.

unable to build chain to self-signed root for signer

Check if the certificate is imported under Login or System in the keychain. If it is in Login, delete it, and re-import it into System.

Copying Custom Directories

When building the binary engine, by default it is consistent with the installation from EpicLauncher, but if you modify the engine and want to package some new directories, modify the InstalledEngineFilters.xml file by adding directories under CopyEditorFilter:

InstalledEngineFilters.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<!-- Define Editor Filters -->
<Property Name="CopyEditorFilter">
<!-- This assembly is normally embedded into the UBT executable, but it can technically be rebuilt from an installed build -->
Engine/Binaries/ThirdParty/Newtonsoft/...
Engine/Binaries/ThirdParty/VisualStudio/...

<!-- In-editor documentation -->
Engine/Documentation/Source/Shared/...
Engine/Documentation/Extras/...

<!-- Content folders -->
Engine/Content/...
<!-- Shaders folders -->
Engine/Shaders/...
<!-- Source code -->
Engine/Source/UE4Game.Target.cs
Engine/Source/UE4Editor.Target.cs

<!-- Starter content -->
Samples/StarterContent/Content/...
Samples/MobileStarterContent/Content/...

<!-- Templates -->
Templates/TemplateCategories.ini
Templates/FP_FirstPerson/...
Templates/FP_FirstPersonBP/...
Templates/Media/...
Templates/TP_Blank/...
Templates/TP_BlankBP/...
Templates/TP_FirstPerson/...
Templates/TP_FirstPersonBP/...
Templates/TP_Flying/...
Templates/TP_FlyingBP/...
Templates/TP_HandheldARBP/...
Templates/TP_ProductConfigBP/...
Templates/TP_Rolling/...
Templates/TP_RollingBP/...
Templates/TP_SideScroller/...
Templates/TP_SideScrollerBP/...
Templates/TP_ThirdPerson/...
Templates/TP_ThirdPersonBP/...
Templates/TP_TopDown/...
Templates/TP_TopDownBP/...
Templates/TP_TwinStick/...
Templates/TP_TwinStickBP/...
Templates/TP_Vehicle/...
Templates/TP_VehicleBP/...
Templates/TP_Puzzle/...
Templates/TP_PuzzleBP/...
Templates/TP_2DSideScroller/...
Templates/TP_2DSideScrollerBP/...
Templates/TP_VehicleAdv/...
Templates/TP_VehicleAdvBP/...
Templates/TP_VirtualRealityBP/...

<!-- Enterprise Templates -->
Templates/TP_AEC_BlankBP/...
Templates/TP_AEC_ArchvisBP/...
Templates/TP_PhotoStudioBP/...

Templates/TP_ME_BlankBP/...
Templates/TP_ME_VProdBP/...

Templates/TP_CollaborativeBP/...

<!-- Shared template resources -->
Templates/TemplateResources/...

<!-- Build files -->
Engine/Build/Build.version
Engine/Build/Target.cs.template
</Property>

Modify according to your needs.

Incremental Build for Binary Engine

To avoid recompiling the Engine module every time, which can lead to a large number of dependent modules in the engine being recompiled, modify the Engine.Build.cs:

1
2
3
4
5
6
PrivateIncludePathModuleNames.AddRange(
new string[] {
"MessagingRpc",
"PortalRpc",
"PortalServices",
}

Change it to:

1
2
3
4
5
6
PublicDependencyModuleNames.AddRange(
new string[] {
"MessagingRpc",
"PortalRpc",
"PortalServices",
}

Relevant discussions on UDN: Make Installed Build Win64中 Compile UE4Game Win64 特别慢的问题

Conclusion

This article mainly introduces the workflow of BuildGraph, optimization of build speed, and support for Android/IOS packaging.

It is important to note that the command used at the beginning of the article:

1
RunUAT.bat BuildGraph -target="Make Installed Build Win64" -script=Engine/Build/InstalledEngineBuild.xml -set:WithMac=false -set:WithAndroid=false -set:WithIOS=false -set:WithTVOS=false -set:WithLinux=false -set:WithHTML5=false -set:WithSwitch=false -WithDDC=false -set:WithWin32=false -set:WithLumin=false -set:WithPS4=false -set:WithXboxOne=false -set:WithHoloLens=false -set:GameConfigurations=Development

The GameConfigurations was only set to Development, which means the compiled engine can only package Development. If you want to support Shipping packaging, you need to specify in BuildGraph: -set:GameConfigurations=Development;Shipping, but this will increase the build time since both Development and Shipping need to be compiled separately, adding some additional compilation time overhead across all supported platforms. However, this is necessary and can be selectively turned on during daily development to save build time.

The article is finished. If you have any questions, please comment and communicate.

Scan the QR code on WeChat and follow me.

Title:BuildGraph:构建支持多平台打包的二进制引擎
Author:LIPENGZHA
Publish Date:2020/11/08 15:40
Update Date:2023/10/22 12:35
Word Count:4.5k Words
Link:https://en.imzlp.com/posts/11956/
License: CC BY-NC-SA 4.0
Reprinting of the full article is prohibited.
Your donation will encourage me to keep creating!