BuildAssembliesHelper.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Threading;
  6. using UnityEngine;
  7. using UnityEditor;
  8. using UnityEditor.Compilation;
  9. namespace ET
  10. {
  11. public static class BuildAssembliesHelper
  12. {
  13. public const string CodeDir = "Assets/Bundles/Code/";
  14. public static void BuildModel(CodeOptimization codeOptimization, GlobalConfig globalConfig)
  15. {
  16. List<string> codes;
  17. switch (globalConfig.CodeMode)
  18. {
  19. case CodeMode.Client:
  20. codes = new List<string>()
  21. {
  22. "Assets/Scripts/Codes/Model/Client/",
  23. "Assets/Scripts/Codes/Model/Share/",
  24. "Assets/Scripts/Codes/Model/Client/",
  25. "Assets/Scripts/Codes/ModelView/Client/",
  26. };
  27. break;
  28. case CodeMode.Server:
  29. codes = new List<string>()
  30. {
  31. "Assets/Scripts/Codes/Model/Generate/Server/",
  32. "Assets/Scripts/Codes/Model/Share/",
  33. "Assets/Scripts/Codes/Model/Server/",
  34. "Assets/Scripts/Codes/Model/Client/",
  35. };
  36. break;
  37. case CodeMode.ClientServer:
  38. codes = new List<string>()
  39. {
  40. "Assets/Scripts/Codes/Model/Share/",
  41. "Assets/Scripts/Codes/Model/Client/",
  42. "Assets/Scripts/Codes/ModelView/Client/",
  43. "Assets/Scripts/Codes/Model/Generate/ClientServer/",
  44. "Assets/Scripts/Codes/Model/Server/",
  45. };
  46. break;
  47. default:
  48. throw new Exception("not found enum");
  49. }
  50. BuildAssembliesHelper.BuildMuteAssembly("Model", codes, Array.Empty<string>(), codeOptimization, globalConfig.CodeMode);
  51. File.Copy(Path.Combine(Define.BuildOutputDir, $"Model.dll"), Path.Combine(CodeDir, $"Model.dll.bytes"), true);
  52. File.Copy(Path.Combine(Define.BuildOutputDir, $"Model.pdb"), Path.Combine(CodeDir, $"Model.pdb.bytes"), true);
  53. Debug.Log("copy Model.dll to Bundles/Code success!");
  54. }
  55. public static void BuildHotfix(CodeOptimization codeOptimization, GlobalConfig globalConfig)
  56. {
  57. string[] logicFiles = Directory.GetFiles(Define.BuildOutputDir, "Hotfix_*");
  58. foreach (string file in logicFiles)
  59. {
  60. File.Delete(file);
  61. }
  62. int random = RandomGenerator.RandomNumber(100000000, 999999999);
  63. string logicFile = $"Hotfix_{random}";
  64. List<string> codes;
  65. switch (globalConfig.CodeMode)
  66. {
  67. case CodeMode.Client:
  68. codes = new List<string>()
  69. {
  70. "Assets/Scripts/Codes/Hotfix/Share/",
  71. "Assets/Scripts/Codes/Hotfix/Client/",
  72. "Assets/Scripts/Codes/HotfixView/Client/",
  73. };
  74. break;
  75. case CodeMode.Server:
  76. codes = new List<string>()
  77. {
  78. "Assets/Scripts/Codes/Hotfix/Share/", "Assets/Scripts/Codes/Hotfix/Server/", "Assets/Scripts/Codes/Hotfix/Client/",
  79. };
  80. break;
  81. case CodeMode.ClientServer:
  82. codes = new List<string>()
  83. {
  84. "Assets/Scripts/Codes/Hotfix/Share/",
  85. "Assets/Scripts/Codes/Hotfix/Client/",
  86. "Assets/Scripts/Codes/HotfixView/Client/",
  87. "Assets/Scripts/Codes/Hotfix/Server/",
  88. };
  89. break;
  90. default:
  91. throw new Exception("not found enum");
  92. }
  93. BuildAssembliesHelper.BuildMuteAssembly("Hotfix", codes, new[] { Path.Combine(Define.BuildOutputDir, "Model.dll") }, codeOptimization,
  94. globalConfig.CodeMode);
  95. File.Copy(Path.Combine(Define.BuildOutputDir, "Hotfix.dll"), Path.Combine(CodeDir, $"Hotfix.dll.bytes"), true);
  96. File.Copy(Path.Combine(Define.BuildOutputDir, "Hotfix.pdb"), Path.Combine(CodeDir, $"Hotfix.pdb.bytes"), true);
  97. File.Copy(Path.Combine(Define.BuildOutputDir, "Hotfix.dll"), Path.Combine(Define.BuildOutputDir, $"{logicFile}.dll"), true);
  98. File.Copy(Path.Combine(Define.BuildOutputDir, "Hotfix.pdb"), Path.Combine(Define.BuildOutputDir, $"{logicFile}.pdb"), true);
  99. Debug.Log("copy Hotfix.dll to Bundles/Code success!");
  100. }
  101. private static void BuildMuteAssembly(
  102. string assemblyName, List<string> CodeDirectorys,
  103. string[] additionalReferences, CodeOptimization codeOptimization, CodeMode codeMode = CodeMode.Client)
  104. {
  105. if (!Directory.Exists(Define.BuildOutputDir))
  106. {
  107. Directory.CreateDirectory(Define.BuildOutputDir);
  108. }
  109. List<string> scripts = new List<string>();
  110. for (int i = 0; i < CodeDirectorys.Count; i++)
  111. {
  112. DirectoryInfo dti = new DirectoryInfo(CodeDirectorys[i]);
  113. FileInfo[] fileInfos = dti.GetFiles("*.cs", System.IO.SearchOption.AllDirectories);
  114. for (int j = 0; j < fileInfos.Length; j++)
  115. {
  116. scripts.Add(fileInfos[j].FullName);
  117. }
  118. }
  119. string dllPath = Path.Combine(Define.BuildOutputDir, $"{assemblyName}.dll");
  120. string pdbPath = Path.Combine(Define.BuildOutputDir, $"{assemblyName}.pdb");
  121. File.Delete(dllPath);
  122. File.Delete(pdbPath);
  123. Directory.CreateDirectory(Define.BuildOutputDir);
  124. AssemblyBuilder assemblyBuilder = new AssemblyBuilder(dllPath, scripts.ToArray());
  125. if (codeMode == CodeMode.Client)
  126. {
  127. assemblyBuilder.excludeReferences = new string[]
  128. {
  129. "DnsClient.dll",
  130. "MongoDB.Driver.Core.dll",
  131. "MongoDB.Driver.dll",
  132. "MongoDB.Driver.Legacy.dll",
  133. "MongoDB.Libmongocrypt.dll",
  134. "SharpCompress.dll",
  135. "System.Buffers.dll",
  136. "System.Runtime.CompilerServices.Unsafe.dll",
  137. "System.Text.Encoding.CodePages.dll"
  138. };
  139. }
  140. //启用UnSafe
  141. assemblyBuilder.compilerOptions.AllowUnsafeCode = true;
  142. BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
  143. assemblyBuilder.compilerOptions.CodeOptimization = codeOptimization;
  144. assemblyBuilder.compilerOptions.ApiCompatibilityLevel = PlayerSettings.GetApiCompatibilityLevel(buildTargetGroup);
  145. // assemblyBuilder.compilerOptions.ApiCompatibilityLevel = ApiCompatibilityLevel.NET_4_6;
  146. assemblyBuilder.additionalReferences = additionalReferences;
  147. assemblyBuilder.flags = AssemblyBuilderFlags.None;
  148. //AssemblyBuilderFlags.None 正常发布
  149. //AssemblyBuilderFlags.DevelopmentBuild 开发模式打包
  150. //AssemblyBuilderFlags.EditorAssembly 编辑器状态
  151. assemblyBuilder.referencesOptions = ReferencesOptions.UseEngineModules;
  152. assemblyBuilder.buildTarget = EditorUserBuildSettings.activeBuildTarget;
  153. assemblyBuilder.buildTargetGroup = buildTargetGroup;
  154. assemblyBuilder.buildStarted += assemblyPath => Debug.LogFormat("build start:" + assemblyPath);
  155. assemblyBuilder.buildFinished += (assemblyPath, compilerMessages) =>
  156. {
  157. int errorCount = compilerMessages.Count(m => m.type == CompilerMessageType.Error);
  158. int warningCount = compilerMessages.Count(m => m.type == CompilerMessageType.Warning);
  159. Debug.LogFormat("Warnings: {0} - Errors: {1}", warningCount, errorCount);
  160. if (warningCount > 0)
  161. {
  162. Debug.LogFormat("有{0}个Warning!!!", warningCount);
  163. }
  164. if (errorCount > 0)
  165. {
  166. for (int i = 0; i < compilerMessages.Length; i++)
  167. {
  168. if (compilerMessages[i].type == CompilerMessageType.Error)
  169. {
  170. string filename = Path.GetFullPath(compilerMessages[i].file);
  171. Debug.LogError(
  172. $"{compilerMessages[i].message} (at <a href=\"file:///{filename}/\" line=\"{compilerMessages[i].line}\">{Path.GetFileName(filename)}</a>)");
  173. }
  174. }
  175. }
  176. };
  177. //开始构建
  178. if (!assemblyBuilder.Build())
  179. {
  180. Debug.LogErrorFormat("build fail:" + assemblyBuilder.assemblyPath);
  181. return;
  182. }
  183. while (EditorApplication.isCompiling)
  184. {
  185. // 主线程sleep并不影响编译线程
  186. Thread.Sleep(1);
  187. }
  188. }
  189. }
  190. }