BuildInfoHelper.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text.RegularExpressions;
  5. using System.Threading.Tasks;
  6. using UnityEditor;
  7. using UnityEngine;
  8. namespace SingularityGroup.HotReload.Editor {
  9. struct BuildInfoInput {
  10. public readonly string allDefineSymbols;
  11. public readonly BuildTarget activeBuildTarget;
  12. public readonly string[] omittedProjects;
  13. public readonly bool batchMode;
  14. public BuildInfoInput(string allDefineSymbols, BuildTarget activeBuildTarget, string[] omittedProjects, bool batchMode) {
  15. this.allDefineSymbols = allDefineSymbols;
  16. this.activeBuildTarget = activeBuildTarget;
  17. this.omittedProjects = omittedProjects;
  18. this.batchMode = batchMode;
  19. }
  20. }
  21. static class BuildInfoHelper {
  22. public static async Task<BuildInfoInput> GetGenerateBuildInfoInput() {
  23. var buildTarget = EditorUserBuildSettings.activeBuildTarget;
  24. var activeDefineSymbols = EditorUserBuildSettings.activeScriptCompilationDefines;
  25. var batchMode = Application.isBatchMode;
  26. var allDefineSymbols = await Task.Run(() => {
  27. return GetAllAndroidMonoBuildDefineSymbolsThreaded(activeDefineSymbols);
  28. });
  29. // cached so unexpensive most of the time
  30. var omittedProjects = AssemblyOmission.GetOmittedProjects(allDefineSymbols);
  31. return new BuildInfoInput(
  32. allDefineSymbols: allDefineSymbols,
  33. activeBuildTarget: buildTarget,
  34. omittedProjects: omittedProjects,
  35. batchMode: batchMode
  36. );
  37. }
  38. public static BuildInfo GenerateBuildInfoMainThread() {
  39. return GenerateBuildInfoMainThread(EditorUserBuildSettings.activeBuildTarget);
  40. }
  41. public static BuildInfo GenerateBuildInfoMainThread(BuildTarget buildTarget) {
  42. var allDefineSymbols = GetAllAndroidMonoBuildDefineSymbolsThreaded(EditorUserBuildSettings.activeScriptCompilationDefines);
  43. return GenerateBuildInfoThreaded(new BuildInfoInput(
  44. allDefineSymbols: allDefineSymbols,
  45. activeBuildTarget: buildTarget,
  46. omittedProjects: AssemblyOmission.GetOmittedProjects(allDefineSymbols),
  47. batchMode: Application.isBatchMode
  48. ));
  49. }
  50. public static BuildInfo GenerateBuildInfoThreaded(BuildInfoInput input) {
  51. var omittedProjectRegex = String.Join("|", input.omittedProjects.Select(name => Regex.Escape(name)));
  52. var shortCommitHash = GitUtil.GetShortCommitHashOrFallback();
  53. var hostname = IsHumanControllingUs(input.batchMode) ? IpHelper.GetIpAddress() : null;
  54. // Note: add a string to uniquely identify the Unity project. Could use filepath to /MyProject/Assets/ (editor Application.dataPath)
  55. // or application identifier (com.company.appname).
  56. // Do this when supporting multiple projects: SG-28807
  57. // The matching code is in Runtime assembly which compares server response with built BuildInfo.
  58. return new BuildInfo {
  59. projectIdentifier = "SG-29580",
  60. commitHash = shortCommitHash,
  61. defineSymbols = input.allDefineSymbols,
  62. projectOmissionRegex = omittedProjectRegex,
  63. buildMachineHostName = hostname,
  64. buildMachinePort = RequestHelper.port,
  65. activeBuildTarget = input.activeBuildTarget.ToString(),
  66. buildMachineRequestOrigin = RequestHelper.origin,
  67. };
  68. }
  69. public static bool IsHumanControllingUs(bool batchMode) {
  70. if (batchMode) {
  71. return false;
  72. }
  73. var isCI = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CI"));
  74. return !isCI;
  75. }
  76. private static readonly string[] editorSymbolsToRemove = {
  77. "PLATFORM_ARCH_64",
  78. "UNITY_64",
  79. "UNITY_INCLUDE_TESTS",
  80. "UNITY_EDITOR",
  81. "UNITY_EDITOR_64",
  82. "UNITY_EDITOR_WIN",
  83. "ENABLE_UNITY_COLLECTIONS_CHECKS",
  84. "ENABLE_BURST_AOT",
  85. "RENDER_SOFTWARE_CURSOR",
  86. "PLATFORM_STANDALONE_WIN",
  87. "PLATFORM_STANDALONE",
  88. "UNITY_STANDALONE_WIN",
  89. "UNITY_STANDALONE",
  90. "ENABLE_MOVIES",
  91. "ENABLE_OUT_OF_PROCESS_CRASH_HANDLER",
  92. "ENABLE_WEBSOCKET_HOST",
  93. "ENABLE_CLUSTER_SYNC",
  94. "ENABLE_CLUSTERINPUT",
  95. };
  96. private static readonly string[] androidSymbolsToAdd = {
  97. "CSHARP_7_OR_LATER",
  98. "CSHARP_7_3_OR_NEWER",
  99. "PLATFORM_ANDROID",
  100. "UNITY_ANDROID",
  101. "UNITY_ANDROID_API",
  102. "ENABLE_EGL",
  103. "DEVELOPMENT_BUILD",
  104. "ENABLE_CLOUD_SERVICES_NATIVE_CRASH_REPORTING",
  105. "PLATFORM_SUPPORTS_ADS_ID",
  106. "UNITY_CAN_SHOW_SPLASH_SCREEN",
  107. "UNITY_HAS_GOOGLEVR",
  108. "UNITY_HAS_TANGO",
  109. "ENABLE_SPATIALTRACKING",
  110. "ENABLE_RUNTIME_PERMISSIONS",
  111. "ENABLE_ENGINE_CODE_STRIPPING",
  112. "UNITY_ASTC_ONLY_DECOMPRESS",
  113. "ANDROID_USE_SWAPPY",
  114. "ENABLE_ONSCREEN_KEYBOARD",
  115. "ENABLE_UNITYADS_RUNTIME",
  116. "UNITY_UNITYADS_API",
  117. };
  118. // Currently there is no better way. Alternatively we could hook into unity's call to csc.exe and parse the /define: arguments.
  119. // Hardcoding the differences was less effort and is less error prone.
  120. // I also looked into it and tried all the Build interfaces like this one https://docs.unity3d.com/ScriptReference/Build.IPostBuildPlayerScriptDLLs.html
  121. // and logging EditorUserBuildSettings.activeScriptCompilationDefines in the callbacks - result: all same like editor, so I agree that hardcode is best.
  122. public static string GetAllAndroidMonoBuildDefineSymbolsThreaded(string[] defineSymbols) {
  123. var defines = new HashSet<string>(defineSymbols);
  124. defines.ExceptWith(editorSymbolsToRemove);
  125. defines.UnionWith(androidSymbolsToAdd);
  126. // sort for consistency, must be deterministic
  127. var definesArray = defines.OrderBy(def => def).ToArray();
  128. return String.Join(";", definesArray);
  129. }
  130. }
  131. }