123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- using UnityEditor;
- using UnityEngine;
- namespace SingularityGroup.HotReload.Editor {
- struct BuildInfoInput {
- public readonly string allDefineSymbols;
- public readonly BuildTarget activeBuildTarget;
- public readonly string[] omittedProjects;
- public readonly bool batchMode;
- public BuildInfoInput(string allDefineSymbols, BuildTarget activeBuildTarget, string[] omittedProjects, bool batchMode) {
- this.allDefineSymbols = allDefineSymbols;
- this.activeBuildTarget = activeBuildTarget;
- this.omittedProjects = omittedProjects;
- this.batchMode = batchMode;
- }
- }
-
- static class BuildInfoHelper {
- public static async Task<BuildInfoInput> GetGenerateBuildInfoInput() {
- var buildTarget = EditorUserBuildSettings.activeBuildTarget;
- var activeDefineSymbols = EditorUserBuildSettings.activeScriptCompilationDefines;
- var batchMode = Application.isBatchMode;
- var allDefineSymbols = await Task.Run(() => {
- return GetAllAndroidMonoBuildDefineSymbolsThreaded(activeDefineSymbols);
- });
- // cached so unexpensive most of the time
- var omittedProjects = AssemblyOmission.GetOmittedProjects(allDefineSymbols);
- return new BuildInfoInput(
- allDefineSymbols: allDefineSymbols,
- activeBuildTarget: buildTarget,
- omittedProjects: omittedProjects,
- batchMode: batchMode
- );
- }
- public static BuildInfo GenerateBuildInfoMainThread() {
- return GenerateBuildInfoMainThread(EditorUserBuildSettings.activeBuildTarget);
- }
-
- public static BuildInfo GenerateBuildInfoMainThread(BuildTarget buildTarget) {
- var allDefineSymbols = GetAllAndroidMonoBuildDefineSymbolsThreaded(EditorUserBuildSettings.activeScriptCompilationDefines);
- return GenerateBuildInfoThreaded(new BuildInfoInput(
- allDefineSymbols: allDefineSymbols,
- activeBuildTarget: buildTarget,
- omittedProjects: AssemblyOmission.GetOmittedProjects(allDefineSymbols),
- batchMode: Application.isBatchMode
- ));
- }
- public static BuildInfo GenerateBuildInfoThreaded(BuildInfoInput input) {
- var omittedProjectRegex = String.Join("|", input.omittedProjects.Select(name => Regex.Escape(name)));
- var shortCommitHash = GitUtil.GetShortCommitHashOrFallback();
- var hostname = IsHumanControllingUs(input.batchMode) ? IpHelper.GetIpAddress() : null;
-
- // Note: add a string to uniquely identify the Unity project. Could use filepath to /MyProject/Assets/ (editor Application.dataPath)
- // or application identifier (com.company.appname).
- // Do this when supporting multiple projects: SG-28807
- // The matching code is in Runtime assembly which compares server response with built BuildInfo.
- return new BuildInfo {
- projectIdentifier = "SG-29580",
- commitHash = shortCommitHash,
- defineSymbols = input.allDefineSymbols,
- projectOmissionRegex = omittedProjectRegex,
- buildMachineHostName = hostname,
- buildMachinePort = RequestHelper.port,
- activeBuildTarget = input.activeBuildTarget.ToString(),
- buildMachineRequestOrigin = RequestHelper.origin,
- };
- }
- public static bool IsHumanControllingUs(bool batchMode) {
- if (batchMode) {
- return false;
- }
- var isCI = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CI"));
- return !isCI;
- }
- private static readonly string[] editorSymbolsToRemove = {
- "PLATFORM_ARCH_64",
- "UNITY_64",
- "UNITY_INCLUDE_TESTS",
- "UNITY_EDITOR",
- "UNITY_EDITOR_64",
- "UNITY_EDITOR_WIN",
- "ENABLE_UNITY_COLLECTIONS_CHECKS",
- "ENABLE_BURST_AOT",
- "RENDER_SOFTWARE_CURSOR",
- "PLATFORM_STANDALONE_WIN",
- "PLATFORM_STANDALONE",
- "UNITY_STANDALONE_WIN",
- "UNITY_STANDALONE",
- "ENABLE_MOVIES",
- "ENABLE_OUT_OF_PROCESS_CRASH_HANDLER",
- "ENABLE_WEBSOCKET_HOST",
- "ENABLE_CLUSTER_SYNC",
- "ENABLE_CLUSTERINPUT",
- };
- private static readonly string[] androidSymbolsToAdd = {
- "CSHARP_7_OR_LATER",
- "CSHARP_7_3_OR_NEWER",
- "PLATFORM_ANDROID",
- "UNITY_ANDROID",
- "UNITY_ANDROID_API",
- "ENABLE_EGL",
- "DEVELOPMENT_BUILD",
- "ENABLE_CLOUD_SERVICES_NATIVE_CRASH_REPORTING",
- "PLATFORM_SUPPORTS_ADS_ID",
- "UNITY_CAN_SHOW_SPLASH_SCREEN",
- "UNITY_HAS_GOOGLEVR",
- "UNITY_HAS_TANGO",
- "ENABLE_SPATIALTRACKING",
- "ENABLE_RUNTIME_PERMISSIONS",
- "ENABLE_ENGINE_CODE_STRIPPING",
- "UNITY_ASTC_ONLY_DECOMPRESS",
- "ANDROID_USE_SWAPPY",
- "ENABLE_ONSCREEN_KEYBOARD",
- "ENABLE_UNITYADS_RUNTIME",
- "UNITY_UNITYADS_API",
- };
-
- // Currently there is no better way. Alternatively we could hook into unity's call to csc.exe and parse the /define: arguments.
- // Hardcoding the differences was less effort and is less error prone.
- // I also looked into it and tried all the Build interfaces like this one https://docs.unity3d.com/ScriptReference/Build.IPostBuildPlayerScriptDLLs.html
- // and logging EditorUserBuildSettings.activeScriptCompilationDefines in the callbacks - result: all same like editor, so I agree that hardcode is best.
- public static string GetAllAndroidMonoBuildDefineSymbolsThreaded(string[] defineSymbols) {
- var defines = new HashSet<string>(defineSymbols);
- defines.ExceptWith(editorSymbolsToRemove);
- defines.UnionWith(androidSymbolsToAdd);
- // sort for consistency, must be deterministic
- var definesArray = defines.OrderBy(def => def).ToArray();
- return String.Join(";", definesArray);
- }
- }
- }
|