[opt] 打包时检查生成桥接函数时的development选项与当前development选项一致。`Generate/All`之后切换development选项再打包,将会产生严重的崩溃

main
walon 2024-05-24 18:32:44 +08:00
parent b96d6fc10d
commit 3de931a3af
4 changed files with 111 additions and 68 deletions

View File

@ -1,8 +1,10 @@
using HybridCLR.Editor.Settings; using HybridCLR.Editor.Settings;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEditor; using UnityEditor;
using UnityEditor.Build; using UnityEditor.Build;
@ -16,6 +18,8 @@ namespace HybridCLR.Editor.BuildProcessors
{ {
public int callbackOrder => 0; public int callbackOrder => 0;
public static bool DisableMethodBridgeDevelopmentFlagChecking { get; set; }
public void OnPreprocessBuild(BuildReport report) public void OnPreprocessBuild(BuildReport report)
{ {
HybridCLRSettings globalSettings = SettingsUtil.HybridCLRSettings; HybridCLRSettings globalSettings = SettingsUtil.HybridCLRSettings;
@ -67,6 +71,24 @@ namespace HybridCLR.Editor.BuildProcessors
Debug.LogWarning("[CheckSettings] No hot update modules configured in HybridCLRSettings"); Debug.LogWarning("[CheckSettings] No hot update modules configured in HybridCLRSettings");
} }
if (!DisableMethodBridgeDevelopmentFlagChecking)
{
string methodBridgeFile = $"{SettingsUtil.GeneratedCppDir}/MethodBridge.cpp";
var match = Regex.Match(File.ReadAllText(methodBridgeFile), @"// DEVELOPMENT=(\d)");
if (match.Success)
{
int developmentFlagInMethodBridge = int.Parse(match.Groups[1].Value);
int developmentFlagInEditorSettings = EditorUserBuildSettings.development ? 1 : 0;
if (developmentFlagInMethodBridge != developmentFlagInEditorSettings)
{
Debug.LogError($"[CheckSettings] MethodBridge.cpp DEVELOPMENT flag:{developmentFlagInMethodBridge} is inconsistent with EditorUserBuildSettings.development:{developmentFlagInEditorSettings}. Please run 'HybridCLR/Generate/All' before building.");
}
}
else
{
Debug.LogError("[CheckSettings] MethodBridge.cpp DEVELOPMENT flag not found. Please run 'HybridCLR/Generate/All' before building.");
}
}
} }
} }
} }

View File

@ -38,6 +38,7 @@ namespace HybridCLR.Editor.Commands
TemplateCode = templateCode, TemplateCode = templateCode,
OutputFile = outputFile, OutputFile = outputFile,
GenericMethods = analyzer.GenericMethods, GenericMethods = analyzer.GenericMethods,
Development = EditorUserBuildSettings.development,
}); });
g.PrepareMethods(); g.PrepareMethods();

View File

@ -1,4 +1,5 @@
using HybridCLR.Editor.Installer; using HybridCLR.Editor.BuildProcessors;
using HybridCLR.Editor.Installer;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -85,99 +86,109 @@ namespace HybridCLR.Editor.Commands
bool oldOpenHarmonyProj = EditorUserBuildSettings.exportAsOpenHarmonyProject; bool oldOpenHarmonyProj = EditorUserBuildSettings.exportAsOpenHarmonyProject;
#endif #endif
bool oldBuildScriptsOnly = EditorUserBuildSettings.buildScriptsOnly; bool oldBuildScriptsOnly = EditorUserBuildSettings.buildScriptsOnly;
EditorUserBuildSettings.buildScriptsOnly = true;
string location = GetLocationPathName(outputPath, target);
string oldBuildLocation = EditorUserBuildSettings.GetBuildLocation(target); string oldBuildLocation = EditorUserBuildSettings.GetBuildLocation(target);
EditorUserBuildSettings.SetBuildLocation(target, location); try
switch (target)
{ {
case BuildTarget.StandaloneWindows: CheckSettings.DisableMethodBridgeDevelopmentFlagChecking = true;
case BuildTarget.StandaloneWindows64: EditorUserBuildSettings.buildScriptsOnly = true;
string location = GetLocationPathName(outputPath, target);
EditorUserBuildSettings.SetBuildLocation(target, location);
switch (target)
{ {
#if UNITY_EDITOR_WIN case BuildTarget.StandaloneWindows:
UnityEditor.WindowsStandalone.UserBuildSettings.createSolution = true; case BuildTarget.StandaloneWindows64:
#endif {
#if UNITY_EDITOR_WIN
UnityEditor.WindowsStandalone.UserBuildSettings.createSolution = true;
#endif
break;
}
case BuildTarget.StandaloneOSX:
{
#if UNITY_EDITOR_OSX
UnityEditor.OSXStandalone.UserBuildSettings.createXcodeProject = true;
#endif
break; break;
}
#if TUANJIE_2022_3_OR_NEWER
case BuildTarget.HMIAndroid:
#endif
case BuildTarget.Android:
{
EditorUserBuildSettings.exportAsGoogleAndroidProject = true;
break;
}
#if TUANJIE_2022_3_OR_NEWER
case BuildTarget.OpenHarmony:
{
EditorUserBuildSettings.exportAsOpenHarmonyProject = true;
break;
}
#endif
} }
case BuildTarget.StandaloneOSX:
Debug.Log($"GenerateStripedAOTDlls build option:{buildOptions}");
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions()
{ {
#if UNITY_EDITOR_OSX scenes = EditorBuildSettings.scenes.Where(s => s.enabled).Select(s => s.path).ToArray(),
UnityEditor.OSXStandalone.UserBuildSettings.createXcodeProject = true; locationPathName = location,
#endif options = buildOptions,
break; target = target,
} targetGroup = BuildPipeline.GetBuildTargetGroup(target),
#if TUANJIE_2022_3_OR_NEWER };
case BuildTarget.HMIAndroid:
#endif var report = BuildPipeline.BuildPlayer(buildPlayerOptions);
case BuildTarget.Android:
if (report.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded)
{ {
EditorUserBuildSettings.exportAsGoogleAndroidProject = true; throw new Exception("GenerateStripedAOTDlls failed");
break;
} }
#if TUANJIE_2022_3_OR_NEWER
case BuildTarget.OpenHarmony:
{
EditorUserBuildSettings.exportAsOpenHarmonyProject = true;
break;
}
#endif
} }
finally
Debug.Log($"GenerateStripedAOTDlls build option:{buildOptions}");
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions()
{ {
scenes = EditorBuildSettings.scenes.Where(s => s.enabled).Select(s => s.path).ToArray(), CheckSettings.DisableMethodBridgeDevelopmentFlagChecking = false;
locationPathName = location, EditorUserBuildSettings.buildScriptsOnly = oldBuildScriptsOnly;
options = buildOptions, EditorUserBuildSettings.SetBuildLocation(target, oldBuildLocation);
target = target,
targetGroup = BuildPipeline.GetBuildTargetGroup(target),
};
var report = BuildPipeline.BuildPlayer(buildPlayerOptions); switch (target)
{
EditorUserBuildSettings.buildScriptsOnly = oldBuildScriptsOnly; case BuildTarget.StandaloneWindows:
EditorUserBuildSettings.SetBuildLocation(target, oldBuildLocation); case BuildTarget.StandaloneWindows64:
switch (target)
{
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
{ {
#if UNITY_EDITOR_WIN #if UNITY_EDITOR_WIN
UnityEditor.WindowsStandalone.UserBuildSettings.createSolution = oldCreateSolution; UnityEditor.WindowsStandalone.UserBuildSettings.createSolution = oldCreateSolution;
#endif #endif
break; break;
} }
case BuildTarget.StandaloneOSX: case BuildTarget.StandaloneOSX:
{ {
#if UNITY_EDITOR_OSX #if UNITY_EDITOR_OSX
UnityEditor.OSXStandalone.UserBuildSettings.createXcodeProject = oldCreateSolution; UnityEditor.OSXStandalone.UserBuildSettings.createXcodeProject = oldCreateSolution;
#endif #endif
break; break;
} }
#if TUANJIE_2022_3_OR_NEWER #if TUANJIE_2022_3_OR_NEWER
case BuildTarget.HMIAndroid: case BuildTarget.HMIAndroid:
#endif #endif
case BuildTarget.Android: case BuildTarget.Android:
{ {
EditorUserBuildSettings.exportAsGoogleAndroidProject = oldExportAndroidProj; EditorUserBuildSettings.exportAsGoogleAndroidProject = oldExportAndroidProj;
break; break;
} }
#if TUANJIE_2022_3_OR_NEWER #if TUANJIE_2022_3_OR_NEWER
case BuildTarget.OpenHarmony: case BuildTarget.OpenHarmony:
{ {
EditorUserBuildSettings.exportAsOpenHarmonyProject = oldOpenHarmonyProj; EditorUserBuildSettings.exportAsOpenHarmonyProject = oldOpenHarmonyProj;
break; break;
} }
#endif #endif
} }
if (report.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded)
{
throw new Exception("GenerateStripedAOTDlls failed");
} }
Debug.Log($"GenerateStripedAOTDlls target:{target} path:{outputPath}"); Debug.Log($"GenerateStripedAOTDlls target:{target} path:{outputPath}");
} }

View File

@ -25,6 +25,8 @@ namespace HybridCLR.Editor.MethodBridge
public string OutputFile { get; set; } public string OutputFile { get; set; }
public IReadOnlyCollection<GenericMethod> GenericMethods { get; set; } public IReadOnlyCollection<GenericMethod> GenericMethods { get; set; }
public bool Development { get; set; }
} }
private readonly List<GenericMethod> _genericMethods; private readonly List<GenericMethod> _genericMethods;
@ -33,6 +35,8 @@ namespace HybridCLR.Editor.MethodBridge
private readonly string _outputFile; private readonly string _outputFile;
private readonly bool _development;
private readonly TypeCreator _typeCreator; private readonly TypeCreator _typeCreator;
private readonly HashSet<MethodDesc> _managed2nativeMethodSet = new HashSet<MethodDesc>(); private readonly HashSet<MethodDesc> _managed2nativeMethodSet = new HashSet<MethodDesc>();
@ -50,6 +54,7 @@ namespace HybridCLR.Editor.MethodBridge
_templateCode = options.TemplateCode; _templateCode = options.TemplateCode;
_outputFile = options.OutputFile; _outputFile = options.OutputFile;
_typeCreator = new TypeCreator(); _typeCreator = new TypeCreator();
_development = options.Development;
} }
private readonly Dictionary<string, TypeInfo> _sig2Types = new Dictionary<string, TypeInfo>(); private readonly Dictionary<string, TypeInfo> _sig2Types = new Dictionary<string, TypeInfo>();
@ -391,6 +396,10 @@ namespace HybridCLR.Editor.MethodBridge
List<string> lines = new List<string>(20_0000); List<string> lines = new List<string>(20_0000);
lines.Add("\n");
lines.Add($"// DEVELOPMENT={(_development ? 1 : 0)}");
lines.Add("\n");
var classInfos = new List<ClassInfo>(); var classInfos = new List<ClassInfo>();
var classTypeSet = new HashSet<TypeInfo>(); var classTypeSet = new HashSet<TypeInfo>();
foreach (var type in structTypes) foreach (var type in structTypes)