UE4.25.1 的 Assembly 路径错误

在 UE4.25.1 中,引擎生成的 Engine/Intermediate/Build/BuildRules/UE4Rules.dll 等文件具有路径错误。

具体的原因是在 UnrealBuildTool/System/RulesCompiler.csCreateEngineOrEnterpriseRulesAssembly函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// UE 4.25.1
private static RulesAssembly CreateEngineOrEnterpriseRulesAssembly(RulesScope Scope, List<DirectoryReference> RootDirectories, string AssemblyPrefix, IReadOnlyList<PluginInfo> Plugins, bool bReadOnly, bool bSkipCompile, RulesAssembly Parent)
{
// ...
// Get the path to store any generated assemblies
DirectoryReference AssemblyDir = RootDirectories[0];
if (UnrealBuildTool.IsFileInstalled(FileReference.Combine(AssemblyDir, AssemblyPrefix)))
{
DirectoryReference UserDir = Utils.GetUserSettingDirectory();
if (UserDir != null)
{
ReadOnlyBuildVersion Version = ReadOnlyBuildVersion.Current;
AssemblyDir = DirectoryReference.Combine(UserDir, "UnrealEngine", String.Format("{0}.{1}", Version.MajorVersion, Version.MinorVersion));
}
}

// Create the assembly
FileReference EngineAssemblyFileName = FileReference.Combine(AssemblyDir, "Intermediate", "Build", "BuildRules", AssemblyPrefix + "Rules" + FrameworkAssemblyExtension);
RulesAssembly EngineAssembly = new RulesAssembly(Scope, RootDirectories, Plugins, ModuleFileToContext, new List<FileReference>(), EngineAssemblyFileName, bContainsEngineModules: true, DefaultBuildSettings: BuildSettingsVersion.Latest, bReadOnly: bReadOnly, bSkipCompile: bSkipCompile, Parent: Parent);
//...
}

上面的代码中 AssemblyDir 是引擎目录,AssemblyPrefixUE4,拼接起来能够通过UnrealBuildTool.IsFileInstalled 的检测。
但是,在 if 的代码块中,获取了用户目录,在 IOS 中就是:

1
2
3
4
# win
C:\Users\lipengzha\AppData\Local\UnrealEngine\4.25
# Mac
/Users/buildmachine/Library/Application Support/Epic

拼接起来就是上面这两个 USER_DIRUnrealEngine/4.25/,在下面读取 Assembly 的流程中就会使用这个路径。

在使用 Win 的时候,其实没有问题,因为就算把 UE4Rules.dll 写入到用户目录下,在 Win 上同样是可以访问到的。但是 ,在使用 Win 远程构建 IOS 的时候就会出现问题。
在远程构建时,会使用 Rsync 把引擎的文件同步到 Mac 上再执行编译,其中就包括 Engine/Intermediate/Build/BuildRuls/ 下的所有文件,因为 4.25.1 中的代码会把 Build/BuildRuls/UE4Rules.dll 等生成到 Win 的用户目录下,所以远程构建,RSync 就不能正确地把 BuildRuls 下的文件上传到 Mac 上,故而引起打包错误:

1
2
ERROR: Precompiled rules assembly '/Users/buildmachine/Library/Application Support/Epic/UnrealEngine/4.25/Intermediate/Build/BuildRules/UE4Rules.dl
l' does not exist.

可以看到,在 Mac 上也是从 Mac 的用户目录查找的,因为压根 Mac 上就没有这俩文件,所以就会产生这个错误。
解决这个问题的办法,就是修改 UnrealBuildTool/System/RulesCompiler.csCreateEngineOrEnterpriseRulesAssembly函数,把 BuildRules 相关的文件写入到 Engine/Intermediate/Build/BuildRules 中,在 UE4.25.2 中已经修复了这个错误。
4.25.2 Hotfix released 中列出了 Fixed! UE-94140 Fix assembly location for remote toolchain,其实就是直接修改了CreateEngineOrEnterpriseRulesAssembly 函数:

1
2
3
4
5
6
7
8
9
// UE 4.25.2
private static RulesAssembly CreateEngineOrEnterpriseRulesAssembly(RulesScope Scope, List<DirectoryReference> RootDirectories, string AssemblyPrefix, IReadOnlyList<PluginInfo> Plugins, bool bReadOnly, bool bSkipCompile, RulesAssembly Parent)
{
// ...
// Create the assembly
FileReference EngineAssemblyFileName = FileReference.Combine(RootDirectories[0], "Intermediate", "Build", "BuildRules", AssemblyPrefix + "Rules" + FrameworkAssemblyExtension);
RulesAssembly EngineAssembly = new RulesAssembly(Scope, RootDirectories[0], Plugins, ModuleFileToContext, new List<FileReference>(), EngineAssemblyFileName, bContainsEngineModules: true, DefaultBuildSettings: BuildSettingsVersion.Latest, bReadOnly: bReadOnly, bSkipCompile: bSkipCompile, Parent: Parent);
// ...
}

可以直接在 github 中查看:UnrealBuildTool/System/RulesCompiler.cs#L442