BuildEditor.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. using HybridCLR.Editor;
  2. using HybridCLR.Editor.Commands;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using UnityEditor;
  8. using UnityEditor.Compilation;
  9. using UnityEngine;
  10. using Debug = UnityEngine.Debug;
  11. namespace ET
  12. {
  13. public enum PlatformType
  14. {
  15. None,
  16. Android,
  17. IOS,
  18. Windows,
  19. MacOS,
  20. Linux
  21. }
  22. public enum BuildType
  23. {
  24. Development,
  25. Release,
  26. }
  27. public class BuildEditor : EditorWindow
  28. {
  29. private PlatformType activePlatform;
  30. private PlatformType platformType;
  31. private bool clearFolder = true;
  32. private bool isBuildExe = true;
  33. private bool isContainAB = false;
  34. private CodeOptimization codeOptimization = CodeOptimization.Release;
  35. private BuildOptions buildOptions;
  36. private BuildAssetBundleOptions buildAssetBundleOptions = BuildAssetBundleOptions.None;
  37. public static string YooAssetCodeDll;
  38. private GlobalConfig globalConfig;
  39. [MenuItem("ET/Build Tool")]
  40. public static void ShowWindow()
  41. {
  42. GetWindow<BuildEditor>(DockDefine.Types);
  43. }
  44. private void OnEnable()
  45. {
  46. YooAssetCodeDll = Application.dataPath + "/Res/CodeDll/";
  47. globalConfig = Resources.Load<GlobalConfig>("GlobalConfig");
  48. #if UNITY_ANDROID
  49. activePlatform = PlatformType.Android;
  50. #elif UNITY_IOS
  51. activePlatform = PlatformType.IOS;
  52. #elif UNITY_STANDALONE_WIN
  53. activePlatform = PlatformType.Windows;
  54. #elif UNITY_STANDALONE_OSX
  55. activePlatform = PlatformType.MacOS;
  56. #elif UNITY_STANDALONE_LINUX
  57. activePlatform = PlatformType.Linux;
  58. #else
  59. activePlatform = PlatformType.None;
  60. #endif
  61. platformType = activePlatform;
  62. }
  63. private void OnGUI()
  64. {
  65. this.platformType = (PlatformType)EditorGUILayout.EnumPopup(platformType);
  66. this.clearFolder = EditorGUILayout.Toggle("clean folder? ", clearFolder);
  67. this.isBuildExe = EditorGUILayout.Toggle("build exe?", this.isBuildExe);
  68. this.isContainAB = false;
  69. this.codeOptimization = (CodeOptimization)EditorGUILayout.EnumPopup("CodeOptimization ", this.codeOptimization);
  70. //EditorGUILayout.LabelField("BuildAssetBundleOptions ");
  71. //this.buildAssetBundleOptions = (BuildAssetBundleOptions)EditorGUILayout.EnumFlagsField(this.buildAssetBundleOptions);
  72. switch (this.codeOptimization)
  73. {
  74. case CodeOptimization.None:
  75. case CodeOptimization.Debug:
  76. this.buildOptions = BuildOptions.Development | BuildOptions.ConnectWithProfiler;
  77. break;
  78. case CodeOptimization.Release:
  79. this.buildOptions = BuildOptions.None;
  80. break;
  81. }
  82. GUILayout.Space(5);
  83. if (GUILayout.Button("BuildPackage"))
  84. {
  85. if (this.platformType == PlatformType.None)
  86. {
  87. ShowNotification(new GUIContent("please select platform!"));
  88. return;
  89. }
  90. var globalConfig = Resources.Load<GlobalConfig>("GlobalConfig");
  91. if (globalConfig.CodeMode == CodeMode.Server)
  92. {
  93. ShowNotification(new GUIContent("not supoort CodeMode: Server!"));
  94. return;
  95. }
  96. if (globalConfig.PlayMode == YooAsset.YooAssets.EPlayMode.EditorSimulateMode)
  97. {
  98. ShowNotification(new GUIContent("YooAsset.PlayMode not support EditorSimulateMode!"));
  99. return;
  100. }
  101. if (platformType != activePlatform)
  102. {
  103. switch (EditorUtility.DisplayDialogComplex("Warning!", $"current platform is {activePlatform}, if change to {platformType}, may be take a long time", "change", "cancel", "no change"))
  104. {
  105. case 0:
  106. activePlatform = platformType;
  107. break;
  108. case 1:
  109. return;
  110. case 2:
  111. platformType = activePlatform;
  112. break;
  113. }
  114. }
  115. BuildHelper.Build(this.platformType, this.buildAssetBundleOptions, this.buildOptions, this.isBuildExe, this.isContainAB, this.clearFolder);
  116. }
  117. GUILayout.Label("");
  118. GUILayout.Label("Build & copy AOTMetadlls");
  119. if (GUILayout.Button("Hybrid-GenerateAll & copy2CodeDll"))
  120. {
  121. //CompileDll时,HotUpdateDll目录的model.dll会被清理掉,生成link.xml会报错
  122. //所以在compileDll后,增加了BuildModel & copy动作
  123. //PrebuildCommand.GenerateAll();
  124. BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
  125. CompileDllCommand.CompileDll(target);
  126. //生成最新的mode.dll & hotfix.dll,然后copy到hotupdate目录,供linkxml用
  127. BuildModelAndHotfix(this.codeOptimization);
  128. CopyHotfixdllToHybridDir();
  129. Il2CppDefGeneratorCommand.GenerateIl2CppDef();
  130. // 这几个生成依赖HotUpdateDlls
  131. LinkGeneratorCommand.GenerateLinkXml(target);
  132. // 生成裁剪后的aot dll
  133. StripAOTDllCommand.GenerateStripedAOTDlls(target, EditorUserBuildSettings.selectedBuildTargetGroup);
  134. // 桥接函数生成依赖于AOT dll,必须保证已经build过,生成AOT dll
  135. MethodBridgeGeneratorCommand.GenerateMethodBridge(target);
  136. ReversePInvokeWrapperGeneratorCommand.GenerateReversePInvokeWrapper(target);
  137. AOTReferenceGeneratorCommand.GenerateAOTGenericReference(target);
  138. string aotDllDir = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
  139. HotUpdateAssemblyManifest manifest = AssetDatabase.LoadAssetAtPath("Assets/Res/Config/HotUpdateAssemblyManifest.asset", typeof(HotUpdateAssemblyManifest)) as HotUpdateAssemblyManifest;
  140. if (manifest == null)
  141. {
  142. throw new Exception($"resource asset:{nameof(HotUpdateAssemblyManifest)} 配置不存在,请在Resources目录下创建");
  143. }
  144. List<string> AOTMetaAssemblies = (manifest.AOTMetadataDlls ?? Array.Empty<string>()).ToList();
  145. foreach (var dll in AOTMetaAssemblies)
  146. {
  147. string dllPath = $"{aotDllDir}/{dll}";
  148. if (!File.Exists(dllPath))
  149. {
  150. Debug.LogError($"ab中添加AOT补充元数据dll:{dllPath} 时发生错误,文件不存在。裁剪后的AOT dll在BuildPlayer时才能生成,因此需要你先构建一次游戏App后再打包。");
  151. continue;
  152. }
  153. string dllBytesPath = $"{YooAssetCodeDll}/{dll}.bytes";
  154. File.Copy(dllPath, dllBytesPath, true);
  155. Debug.Log($"copy AOT dll {dllPath} -> {dllBytesPath}");
  156. }
  157. }
  158. GUILayout.Label("");
  159. GUILayout.Label("Build热更dll & ab:");
  160. this.globalConfig.CodeMode = CodeMode.Client;// (CodeMode)EditorGUILayout.EnumPopup("CodeMode: ", this.globalConfig.CodeMode);
  161. if (GUILayout.Button("BuildModelAndHotfix"))
  162. {
  163. BuildModelAndHotfix(this.codeOptimization);
  164. //用yooAsset打ab, 不用你了
  165. //AfterCompiling();
  166. ShowNotification("Build Model And Hotfix Success!");
  167. }
  168. if (GUILayout.Button("BuildAB by YooAsset"))
  169. {
  170. var target = EditorUserBuildSettings.activeBuildTarget;
  171. BuildHelper.BuildAB(target, null);
  172. }
  173. GUILayout.Label("");
  174. GUILayout.Label("Config Tools: =======================");
  175. if (GUILayout.Button("ExcelExporter"))
  176. {
  177. //Directory.Delete("Assets/Bundles/Config", true);
  178. ToolsEditor.ExcelExporter();
  179. }
  180. if (GUILayout.Button("Proto2CS"))
  181. {
  182. ToolsEditor.Proto2CS();
  183. }
  184. GUILayout.Space(5);
  185. }
  186. private static void CopyHotfixdllToHybridDir()
  187. {
  188. var target = EditorUserBuildSettings.activeBuildTarget; ;
  189. var dll = Path.Combine(YooAssetCodeDll, "Model.dll.bytes");
  190. if (!File.Exists(dll))
  191. {
  192. Debug.LogError($"not exists: {dll}");
  193. }
  194. else
  195. {
  196. File.Copy(dll, Path.Combine(SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target), "Model.dll"), true);
  197. }
  198. dll = Path.Combine(YooAssetCodeDll, "Hotfix.dll.bytes");
  199. if (!File.Exists(dll))
  200. {
  201. Debug.LogError($"not exists: {dll}");
  202. }
  203. else
  204. {
  205. File.Copy(dll, Path.Combine(SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target), "Hotfix.dll"), true);
  206. }
  207. dll = Path.Combine("./Library/ScriptAssemblies", "Unity.Mono.dll.bytes");
  208. if (!File.Exists(dll))
  209. {
  210. Debug.LogError($"not exists: {dll}");
  211. }
  212. else
  213. {
  214. File.Copy(dll, Path.Combine(SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target), "Unity.Mono.dll"), true);
  215. }
  216. }
  217. public static void BuildModelAndHotfix(CodeOptimization codeOptimization = CodeOptimization.Release)
  218. {
  219. if (Define.EnableCodes)
  220. {
  221. throw new Exception("Remove macro 'ENABLE_CODES' first!");
  222. }
  223. var globalConfig = Resources.Load<GlobalConfig>("GlobalConfig");
  224. if (globalConfig.CodeMode == CodeMode.Server)
  225. {
  226. throw new Exception("Don't compile server here, open 'ET.sln' to compile!");
  227. }
  228. BuildAssembliesHelper.BuildModel(codeOptimization, globalConfig);
  229. BuildAssembliesHelper.BuildHotfix(codeOptimization, globalConfig);
  230. File.Copy(Path.Combine("./Library/ScriptAssemblies", "Unity.Mono.dll"), Path.Combine(YooAssetCodeDll, $"Unity.Mono.dll.bytes"), true);
  231. }
  232. //将model.dll打包成ab
  233. /*private static void AfterCompiling()
  234. {
  235. Directory.CreateDirectory(BuildAssembliesHelper.CodeDir);
  236. // 设置ab包
  237. AssetImporter assetImporter = AssetImporter.GetAtPath("Assets/Bundles/Code");
  238. assetImporter.assetBundleName = "Code.unity3d";
  239. AssetDatabase.SaveAssets();
  240. AssetDatabase.Refresh();
  241. Debug.Log("build success!");
  242. }*/
  243. public static void ShowNotification(string tips)
  244. {
  245. EditorWindow game = EditorWindow.GetWindow(typeof(EditorWindow).Assembly.GetType("UnityEditor.GameView"));
  246. game?.ShowNotification(new GUIContent($"{tips}"));
  247. }
  248. }
  249. }