private static void ScheduleEagerCompilation() { lock (EagerCompilationLockObject) { if (EagerCompilationTokenSource.IsCancellationRequested) { return; } if (_cachedCompileTargets == null) { throw new InvalidOperationException(); } if (DebuggingLevel > 2) { UnityEngine.Debug.Log($"Burst - Starting scheduling eager-compilation"); } var methodsToCompile = new List <EagerCompilationRequest>(); foreach (var compileTarget in _cachedCompileTargets) { var member = compileTarget.IsStaticMethod ? (MemberInfo)compileTarget.Method : compileTarget.JobType; if (compileTarget.Options.TryGetOptions(member, true, out var optionsString, isForEagerCompilation: true)) { var encodedMethod = BurstCompilerService.GetMethodSignature(compileTarget.Method); methodsToCompile.Add(new EagerCompilationRequest(encodedMethod, optionsString)); } } BurstCompiler.EagerCompileMethods(methodsToCompile); if (DebuggingLevel > 2) { UnityEngine.Debug.Log($"Burst - Finished scheduling eager-compilation of {methodsToCompile.Count} methods"); } } }
private void OnPostBuildPlayerScriptDLLsImpl(BuildReport report) { BurstPlatformAotSettings aotSettingsForTarget = BurstPlatformAotSettings.GetOrCreateSettings(report.summary.platform); // Early exit if burst is not activated or the platform is not supported if (aotSettingsForTarget.DisableBurstCompilation || !IsSupportedPlatform(report.summary.platform)) { return; } // Collect all method signatures var methodsToCompile = BurstReflection.FindExecuteMethods(AssembliesType.Player); if (methodsToCompile.Count == 0) { return; // Nothing to do } // Prepare options // We are grouping methods per their compiler options (float precision...etc) var methodGroups = new Dictionary <string, List <string> >(); for (var i = 0; i < methodsToCompile.Count; i++) { var burstCompileTarget = methodsToCompile[i]; if (!burstCompileTarget.IsSupported) { continue; } var methodStr = BurstCompilerService.GetMethodSignature(burstCompileTarget.Method); var methodFullSignature = methodStr + "--" + Hash128.Compute(methodStr); if (aotSettingsForTarget.DisableOptimisations) { burstCompileTarget.Options.DisableOptimizations = true; } burstCompileTarget.Options.EnableBurstSafetyChecks = !aotSettingsForTarget.DisableSafetyChecks; string optionsAsStr; if (burstCompileTarget.TryGetOptionsAsString(false, out optionsAsStr)) { List <string> methodOptions; if (!methodGroups.TryGetValue(optionsAsStr, out methodOptions)) { methodOptions = new List <string>(); methodGroups.Add(optionsAsStr, methodOptions); } methodOptions.Add(GetOption(OptionAotMethod, methodFullSignature)); } } var methodGroupOptions = new List <string>(); // We should have something like this in the end: // // --group 1st group of method with the following shared options // --float-mode=xxx // --method=... // --method=... // // --group 2nd group of methods with the different shared options // --float-mode=yyy // --method=... // --method=... if (methodGroups.Count == 1) { var methodGroup = methodGroups.FirstOrDefault(); // No need to create a group if we don't have multiple methodGroupOptions.Add(methodGroup.Key); foreach (var methodOption in methodGroup.Value) { methodGroupOptions.Add(methodOption); } } else { foreach (var methodGroup in methodGroups) { methodGroupOptions.Add(GetOption(OptionGroup)); methodGroupOptions.Add(methodGroup.Key); foreach (var methodOption in methodGroup.Value) { methodGroupOptions.Add(methodOption); } } } var commonOptions = new List <string>(); var targetCpu = TargetCpu.Auto; var targetPlatform = GetTargetPlatformAndDefaultCpu(report.summary.platform, out targetCpu); commonOptions.Add(GetOption(OptionPlatform, targetPlatform)); // TODO: Add support for configuring the optimizations/CPU // TODO: Add support for per method options var stagingFolder = Path.GetFullPath(TempStagingManaged); //Debug.Log($"Burst CompileAot - To Folder {stagingFolder}"); // Prepare assembly folder list var assemblyFolders = new List <string>(); assemblyFolders.Add(stagingFolder); var playerAssemblies = CompilationPipeline.GetAssemblies(AssembliesType.Player); foreach (var assembly in playerAssemblies) { foreach (var assemblyRef in assembly.compiledAssemblyReferences) { // Exclude folders with assemblies already compiled in the `folder` var assemblyName = Path.GetFileName(assemblyRef); if (assemblyName != null && File.Exists(Path.Combine(stagingFolder, assemblyName))) { continue; } var directory = Path.GetDirectoryName(assemblyRef); if (directory != null) { var fullPath = Path.GetFullPath(directory); if (IsMonoReferenceAssemblyDirectory(fullPath) || IsDotNetStandardAssemblyDirectory(fullPath)) { // Don't pass reference assemblies to burst because they contain methods without implementation // If burst accidentally resolves them, it will emit calls to burst_abort. fullPath = Path.Combine(EditorApplication.applicationContentsPath, "MonoBleedingEdge/lib/mono/unityaot"); fullPath = Path.GetFullPath(fullPath); // GetFullPath will normalize path separators to OS native format if (!assemblyFolders.Contains(fullPath)) { assemblyFolders.Add(fullPath); } fullPath = Path.Combine(fullPath, "Facades"); if (!assemblyFolders.Contains(fullPath)) { assemblyFolders.Add(fullPath); } } else if (!assemblyFolders.Contains(fullPath)) { assemblyFolders.Add(fullPath); } } } } commonOptions.AddRange(assemblyFolders.Select(folder => GetOption(OptionAotAssemblyFolder, folder))); var combinations = new List <BurstOutputCombination>(); if (targetPlatform == TargetPlatform.macOS) { // NOTE: OSX has a special folder for the plugin // Declared in GetStagingAreaPluginsFolder // PlatformDependent\OSXPlayer\Extensions\Managed\OSXDesktopStandalonePostProcessor.cs combinations.Add(new BurstOutputCombination("UnityPlayer.app/Contents/Plugins", targetCpu)); } else if (targetPlatform == TargetPlatform.iOS) { if (Application.platform != RuntimePlatform.OSXEditor) { Debug.LogWarning("Burst Cross Compilation to iOS for standalone player, is only supported on OSX Editor at this time, burst is disabled for this build."); } else { var targetArchitecture = (IOSArchitecture)UnityEditor.PlayerSettings.GetArchitecture(report.summary.platformGroup); if (targetArchitecture == IOSArchitecture.ARMv7 || targetArchitecture == IOSArchitecture.Universal) { // PlatformDependent\iPhonePlayer\Extensions\Common\BuildPostProcessor.cs combinations.Add(new BurstOutputCombination("StaticLibraries", TargetCpu.ARMV7A_NEON32, DefaultLibraryName + "32")); } if (targetArchitecture == IOSArchitecture.ARM64 || targetArchitecture == IOSArchitecture.Universal) { // PlatformDependent\iPhonePlayer\Extensions\Common\BuildPostProcessor.cs combinations.Add(new BurstOutputCombination("StaticLibraries", TargetCpu.ARMV8A_AARCH64, DefaultLibraryName + "64")); } } } else if (targetPlatform == TargetPlatform.Android) { //TODO: would be better to query AndroidNdkRoot (but thats not exposed from unity) string ndkRoot = null; // 2019.1 now has an embedded ndk #if UNITY_2019_1_OR_NEWER if (EditorPrefs.HasKey("NdkUseEmbedded")) { if (EditorPrefs.GetBool("NdkUseEmbedded")) { ndkRoot = Path.Combine(BuildPipeline.GetPlaybackEngineDirectory(BuildTarget.Android, BuildOptions.None), "NDK"); } else { ndkRoot = EditorPrefs.GetString("AndroidNdkRootR16b"); } } #endif // If we still don't have a valid root, try the old key if (string.IsNullOrEmpty(ndkRoot)) { ndkRoot = EditorPrefs.GetString("AndroidNdkRoot"); } // Verify the directory at least exists, if not we fall back to ANDROID_NDK_ROOT current setting if (!string.IsNullOrEmpty(ndkRoot) && !Directory.Exists(ndkRoot)) { ndkRoot = null; } // Always set the ANDROID_NDK_ROOT (if we got a valid result from above), so BCL knows where to find the Android toolchain and its the one the user expects if (!string.IsNullOrEmpty(ndkRoot)) { Environment.SetEnvironmentVariable("ANDROID_NDK_ROOT", ndkRoot); } var androidTargetArch = UnityEditor.PlayerSettings.Android.targetArchitectures; if ((androidTargetArch & AndroidArchitecture.ARMv7) != 0) { combinations.Add(new BurstOutputCombination("libs/armeabi-v7a", TargetCpu.ARMV7A_NEON32)); } if ((androidTargetArch & AndroidArchitecture.ARM64) != 0) { combinations.Add(new BurstOutputCombination("libs/arm64-v8a", TargetCpu.ARMV8A_AARCH64)); } if ((androidTargetArch & AndroidArchitecture.X86) != 0) { combinations.Add(new BurstOutputCombination("libs/x86", TargetCpu.X86_SSE2)); } } else if (targetPlatform == TargetPlatform.UWP) { // TODO: Make it configurable for x86 (sse2, sse4) combinations.Add(new BurstOutputCombination("Plugins/x64", TargetCpu.X64_SSE4)); combinations.Add(new BurstOutputCombination("Plugins/x86", TargetCpu.X86_SSE2)); combinations.Add(new BurstOutputCombination("Plugins/ARM", TargetCpu.THUMB2_NEON32)); combinations.Add(new BurstOutputCombination("Plugins/ARM64", TargetCpu.ARMV8A_AARCH64)); } else { combinations.Add(new BurstOutputCombination("Data/Plugins/", targetCpu)); } foreach (var combination in combinations) { // Gets the output folder var stagingOutputFolder = Path.GetFullPath(Path.Combine(TempStaging, combination.OutputPath)); var outputFilePrefix = Path.Combine(stagingOutputFolder, combination.LibraryName); var options = new List <string>(commonOptions); options.Add(GetOption(OptionAotOutputPath, outputFilePrefix)); options.Add(GetOption(OptionTarget, combination.TargetCpu)); if (targetPlatform == TargetPlatform.iOS) { options.Add(GetOption(OptionStaticLinkage)); } // finally add method group options options.AddRange(methodGroupOptions); var responseFile = Path.GetTempFileName(); File.WriteAllLines(responseFile, options); //Debug.Log("Burst compile with response file: " + responseFile); try { string generatedDebugInformationInOutput = ""; if ((report.summary.options & BuildOptions.Development) != 0) { // Workaround for apple clang development issue (due to latest being 7.0.0) - IOS is only affected because its a source level IR compatability issue if (targetPlatform != TargetPlatform.iOS) { generatedDebugInformationInOutput = GetOption(OptionDebug); } } BclRunner.RunManagedProgram(Path.Combine(BurstLoader.RuntimePath, BurstAotCompilerExecutable), $"{generatedDebugInformationInOutput} @{responseFile}", new BclOutputErrorParser(), report); } catch (Exception e) { // We don't expect any error, but in case we have one, we identify that it is burst and we print the details here Debug.LogError("Unexpected error while running the burst compiler: " + e); } } }
public void OnPostBuildPlayerScriptDLLs(BuildReport report) { BurstPlatformAotSettings aotSettingsForTarget = BurstPlatformAotSettings.GetOrCreateSettings(report.summary.platform); // Early exit if burst is not activated or the platform is not supported if (aotSettingsForTarget.DisableBurstCompilation || !IsSupportedPlatform(report.summary.platform)) { return; } // Collect all method signatures var methodsToCompile = BurstReflection.FindExecuteMethods(AssembliesType.Player); if (methodsToCompile.Count == 0) { return; // Nothing to do } // Prepare options var commonOptions = new List <string>(); for (var i = 0; i < methodsToCompile.Count; i++) { var burstCompileTarget = methodsToCompile[i]; if (!burstCompileTarget.SupportsBurst) { continue; } var methodStr = BurstCompilerService.GetMethodSignature(burstCompileTarget.Method); var methodFullSignature = methodStr + "--" + Hash128.Compute(methodStr); commonOptions.Add(GetOption(OptionAotMethod, methodFullSignature)); } var targetCpu = TargetCpu.Auto; var targetPlatform = GetTargetPlatformAndDefaultCpu(report.summary.platform, out targetCpu); commonOptions.Add(GetOption(OptionPlatform, targetPlatform)); if (!BurstEditorOptions.EnableBurstSafetyChecks) { commonOptions.Add(GetOption(OptionDisableSafetyChecks)); } // TODO: Add support for configuring the optimizations/CPU // TODO: Add support for per method options var stagingFolder = Path.GetFullPath(TempStagingManaged); //Debug.Log($"Burst CompileAot - To Folder {stagingFolder}"); // Prepare assembly folder list var assemblyFolders = new List <string>(); assemblyFolders.Add(stagingFolder); var playerAssemblies = CompilationPipeline.GetAssemblies(AssembliesType.Player); foreach (var assembly in playerAssemblies) { foreach (var assemblyRef in assembly.compiledAssemblyReferences) { // Exclude folders with assemblies already compiled in the `folder` var assemblyName = Path.GetFileName(assemblyRef); if (assemblyName != null && File.Exists(Path.Combine(stagingFolder, assemblyName))) { continue; } var directory = Path.GetDirectoryName(assemblyRef); if (directory != null) { var fullPath = Path.GetFullPath(directory); if (IsMonoReferenceAssemblyDirectory(fullPath) || IsDotNetStandardAssemblyDirectory(fullPath)) { // Don't pass reference assemblies to burst because they contain methods without implementation // If burst accidentally resolves them, it will emit calls to burst_abort. fullPath = Path.Combine(EditorApplication.applicationContentsPath, "MonoBleedingEdge/lib/mono/unityaot"); fullPath = Path.GetFullPath(fullPath); // GetFullPath will normalize path separators to OS native format if (!assemblyFolders.Contains(fullPath)) { assemblyFolders.Add(fullPath); } fullPath = Path.Combine(fullPath, "Facades"); if (!assemblyFolders.Contains(fullPath)) { assemblyFolders.Add(fullPath); } } else if (!assemblyFolders.Contains(fullPath)) { assemblyFolders.Add(fullPath); } } } } commonOptions.AddRange(assemblyFolders.Select(folder => GetOption(OptionAotAssemblyFolder, folder))); // Gets platform specific IL2CPP plugin folder // Only the following platforms are providing a dedicated Tools directory switch (report.summary.platform) { case BuildTarget.XboxOne: case BuildTarget.PS4: case BuildTarget.Android: case BuildTarget.iOS: var pluginFolder = BuildPipeline.GetBuildToolsDirectory(report.summary.platform); commonOptions.Add(GetOption(OptionAotIL2CPPPluginFolder, pluginFolder)); break; } var combinations = new List <BurstOutputCombination>(); if (targetPlatform == TargetPlatform.macOS) { // NOTE: OSX has a special folder for the plugin // Declared in GetStagingAreaPluginsFolder // PlatformDependent\OSXPlayer\Extensions\Managed\OSXDesktopStandalonePostProcessor.cs combinations.Add(new BurstOutputCombination("UnityPlayer.app/Contents/Plugins", targetCpu)); } else if (targetPlatform == TargetPlatform.iOS) { // Check if we are under il2cpp as we may have to force a CPU backend for it // TODO: Should use report.summary.platformGroup instead? bool isUsingIL2CPP = PlayerSettings.GetScriptingBackend(BuildTargetGroup.Standalone) == ScriptingImplementation.IL2CPP; if (!isUsingIL2CPP) { var targetArchitecture = (IOSArchitecture)UnityEditor.PlayerSettings.GetArchitecture(report.summary.platformGroup); switch (targetArchitecture) { case IOSArchitecture.ARMv7: targetCpu = TargetCpu.ARMV7A_NEON32; break; case IOSArchitecture.ARM64: targetCpu = TargetCpu.ARMV8A_AARCH64; break; case IOSArchitecture.Universal: // TODO: How do we proceed here? targetCpu = TargetCpu.ARMV7A_NEON32; break; } } // PlatformDependent\iPhonePlayer\Extensions\Common\BuildPostProcessor.cs combinations.Add(new BurstOutputCombination("Frameworks", targetCpu)); } else if (targetPlatform == TargetPlatform.Android) { // Set the ANDROID_NDK_ROOT so IL2CPP knows where to find the Android toolchain if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ANDROID_NDK_ROOT"))) { var ndkRoot = EditorPrefs.GetString("AndroidNdkRoot"); if (!string.IsNullOrEmpty(ndkRoot)) { Environment.SetEnvironmentVariable("ANDROID_NDK_ROOT", ndkRoot); } } var androidTargetArch = UnityEditor.PlayerSettings.Android.targetArchitectures; if ((androidTargetArch & AndroidArchitecture.ARMv7) != 0) { combinations.Add(new BurstOutputCombination("libs/armeabi-v7a", TargetCpu.ARMV7A_NEON32)); } if ((androidTargetArch & AndroidArchitecture.ARM64) != 0) { combinations.Add(new BurstOutputCombination("libs/arm64-v8a", TargetCpu.ARMV8A_AARCH64)); } if ((androidTargetArch & AndroidArchitecture.X86) != 0) { combinations.Add(new BurstOutputCombination("libs/x86", TargetCpu.X86_SSE2)); } } else if (targetPlatform == TargetPlatform.UWP) { // TODO: Make it configurable for x86 (sse2, sse4) combinations.Add(new BurstOutputCombination("Plugins/x64", TargetCpu.X64_SSE4)); combinations.Add(new BurstOutputCombination("Plugins/x86", TargetCpu.X86_SSE2)); combinations.Add(new BurstOutputCombination("Plugins/ARM", TargetCpu.THUMB2_NEON32)); combinations.Add(new BurstOutputCombination("Plugins/ARM64", TargetCpu.ARMV8A_AARCH64)); } else { combinations.Add(new BurstOutputCombination("Data/Plugins/", targetCpu)); } foreach (var combination in combinations) { // Gets the output folder var stagingOutputFolder = Path.GetFullPath(Path.Combine(TempStaging, combination.OutputPath)); var outputFilePrefix = Path.Combine(stagingOutputFolder, DefaultLibraryName); var options = new List <string>(commonOptions); options.Add(GetOption(OptionAotOutputPath, outputFilePrefix)); options.Add(GetOption(OptionTarget, combination.TargetCpu)); if (aotSettingsForTarget.DisableOptimisations) { options.Add(GetOption(OptionDisableOpt)); } if (aotSettingsForTarget.DisableSafetyChecks) { options.Add(GetOption(OptionDisableSafetyChecks)); } else { options.Add(GetOption(OptionSafetyChecks)); } var responseFile = Path.GetTempFileName(); File.WriteAllLines(responseFile, options); //Debug.Log("Burst compile with response file: " + responseFile); try { Runner.RunManagedProgram(Path.Combine(BurstLoader.RuntimePath, BurstAotCompilerExecutable), "--debug=true " + "@" + responseFile, Application.dataPath + "/..", new BclParser(), null); } catch (Exception e) { Debug.LogError(e.ToString()); } } }
public void OnPostBuildPlayerScriptDLLs(BuildReport report) { BurstPlatformAotSettings aotSettingsForTarget = BurstPlatformAotSettings.GetOrCreateSettings(report.summary.platform); // Early exit if burst is not activated or the platform is not supported if (aotSettingsForTarget.DisableBurstCompilation || !IsSupportedPlatform(report.summary.platform)) { return; } // Collect all method signatures var methodsToCompile = BurstReflection.FindExecuteMethods(AssembliesType.Player); if (methodsToCompile.Count == 0) { return; // Nothing to do } // Prepare options // We are grouping methods per their compiler options (float precision...etc) var methodGroups = new Dictionary <string, List <string> >(); for (var i = 0; i < methodsToCompile.Count; i++) { var burstCompileTarget = methodsToCompile[i]; if (!burstCompileTarget.IsSupported) { continue; } var methodStr = BurstCompilerService.GetMethodSignature(burstCompileTarget.Method); var methodFullSignature = methodStr + "--" + Hash128.Compute(methodStr); if (aotSettingsForTarget.DisableOptimisations) { burstCompileTarget.Options.DisableOptimizations = true; } burstCompileTarget.Options.EnableBurstSafetyChecks = !aotSettingsForTarget.DisableSafetyChecks; string optionsAsStr; if (burstCompileTarget.TryGetOptionsAsString(false, out optionsAsStr)) { List <string> methodOptions; if (!methodGroups.TryGetValue(optionsAsStr, out methodOptions)) { methodOptions = new List <string>(); methodGroups.Add(optionsAsStr, methodOptions); } methodOptions.Add(GetOption(OptionAotMethod, methodFullSignature)); } } var methodGroupOptions = new List <string>(); // We should have something like this in the end: // // --group 1st group of method with the following shared options // --float-mode=xxx // --method=... // --method=... // // --group 2nd group of methods with the different shared options // --float-mode=yyy // --method=... // --method=... if (methodGroups.Count == 1) { var methodGroup = methodGroups.FirstOrDefault(); // No need to create a group if we don't have multiple methodGroupOptions.Add(methodGroup.Key); foreach (var methodOption in methodGroup.Value) { methodGroupOptions.Add(methodOption); } } else { foreach (var methodGroup in methodGroups) { methodGroupOptions.Add(GetOption(OptionGroup)); methodGroupOptions.Add(methodGroup.Key); foreach (var methodOption in methodGroup.Value) { methodGroupOptions.Add(methodOption); } } } var commonOptions = new List <string>(); var targetCpu = TargetCpu.Auto; var targetPlatform = GetTargetPlatformAndDefaultCpu(report.summary.platform, out targetCpu); commonOptions.Add(GetOption(OptionPlatform, targetPlatform)); // TODO: Add support for configuring the optimizations/CPU // TODO: Add support for per method options var stagingFolder = Path.GetFullPath(TempStagingManaged); //Debug.Log($"Burst CompileAot - To Folder {stagingFolder}"); // Prepare assembly folder list var assemblyFolders = new List <string>(); assemblyFolders.Add(stagingFolder); var playerAssemblies = CompilationPipeline.GetAssemblies(AssembliesType.Player); foreach (var assembly in playerAssemblies) { foreach (var assemblyRef in assembly.compiledAssemblyReferences) { // Exclude folders with assemblies already compiled in the `folder` var assemblyName = Path.GetFileName(assemblyRef); if (assemblyName != null && File.Exists(Path.Combine(stagingFolder, assemblyName))) { continue; } var directory = Path.GetDirectoryName(assemblyRef); if (directory != null) { var fullPath = Path.GetFullPath(directory); if (IsMonoReferenceAssemblyDirectory(fullPath) || IsDotNetStandardAssemblyDirectory(fullPath)) { // Don't pass reference assemblies to burst because they contain methods without implementation // If burst accidentally resolves them, it will emit calls to burst_abort. fullPath = Path.Combine(EditorApplication.applicationContentsPath, "MonoBleedingEdge/lib/mono/unityaot"); fullPath = Path.GetFullPath(fullPath); // GetFullPath will normalize path separators to OS native format if (!assemblyFolders.Contains(fullPath)) { assemblyFolders.Add(fullPath); } fullPath = Path.Combine(fullPath, "Facades"); if (!assemblyFolders.Contains(fullPath)) { assemblyFolders.Add(fullPath); } } else if (!assemblyFolders.Contains(fullPath)) { assemblyFolders.Add(fullPath); } } } } commonOptions.AddRange(assemblyFolders.Select(folder => GetOption(OptionAotAssemblyFolder, folder))); var combinations = new List <BurstOutputCombination>(); if (targetPlatform == TargetPlatform.macOS) { // NOTE: OSX has a special folder for the plugin // Declared in GetStagingAreaPluginsFolder // PlatformDependent\OSXPlayer\Extensions\Managed\OSXDesktopStandalonePostProcessor.cs combinations.Add(new BurstOutputCombination("UnityPlayer.app/Contents/Plugins", targetCpu)); } else if (targetPlatform == TargetPlatform.iOS) { var targetArchitecture = (IOSArchitecture)UnityEditor.PlayerSettings.GetArchitecture(report.summary.platformGroup); if (targetArchitecture == IOSArchitecture.ARMv7 || targetArchitecture == IOSArchitecture.Universal) { // PlatformDependent\iPhonePlayer\Extensions\Common\BuildPostProcessor.cs combinations.Add(new BurstOutputCombination("StaticLibraries", TargetCpu.ARMV7A_NEON32, DefaultLibraryName + "32")); } if (targetArchitecture == IOSArchitecture.ARM64 || targetArchitecture == IOSArchitecture.Universal) { // PlatformDependent\iPhonePlayer\Extensions\Common\BuildPostProcessor.cs combinations.Add(new BurstOutputCombination("StaticLibraries", TargetCpu.ARMV8A_AARCH64, DefaultLibraryName + "64")); } } else if (targetPlatform == TargetPlatform.Android) { // Set the ANDROID_NDK_ROOT so BCL knows where to find the Android toolchain if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ANDROID_NDK_ROOT"))) { var ndkRoot = EditorPrefs.GetString("AndroidNdkRoot"); if (!string.IsNullOrEmpty(ndkRoot)) { Environment.SetEnvironmentVariable("ANDROID_NDK_ROOT", ndkRoot); } } var androidTargetArch = UnityEditor.PlayerSettings.Android.targetArchitectures; if ((androidTargetArch & AndroidArchitecture.ARMv7) != 0) { combinations.Add(new BurstOutputCombination("libs/armeabi-v7a", TargetCpu.ARMV7A_NEON32)); } if ((androidTargetArch & AndroidArchitecture.ARM64) != 0) { combinations.Add(new BurstOutputCombination("libs/arm64-v8a", TargetCpu.ARMV8A_AARCH64)); } if ((androidTargetArch & AndroidArchitecture.X86) != 0) { combinations.Add(new BurstOutputCombination("libs/x86", TargetCpu.X86_SSE2)); } } else if (targetPlatform == TargetPlatform.UWP) { // TODO: Make it configurable for x86 (sse2, sse4) combinations.Add(new BurstOutputCombination("Plugins/x64", TargetCpu.X64_SSE4)); combinations.Add(new BurstOutputCombination("Plugins/x86", TargetCpu.X86_SSE2)); combinations.Add(new BurstOutputCombination("Plugins/ARM", TargetCpu.THUMB2_NEON32)); combinations.Add(new BurstOutputCombination("Plugins/ARM64", TargetCpu.ARMV8A_AARCH64)); } else { combinations.Add(new BurstOutputCombination("Data/Plugins/", targetCpu)); } foreach (var combination in combinations) { // Gets the output folder var stagingOutputFolder = Path.GetFullPath(Path.Combine(TempStaging, combination.OutputPath)); var outputFilePrefix = Path.Combine(stagingOutputFolder, combination.LibraryName); var options = new List <string>(commonOptions); options.Add(GetOption(OptionAotOutputPath, outputFilePrefix)); options.Add(GetOption(OptionTarget, combination.TargetCpu)); if (targetPlatform == TargetPlatform.iOS) { options.Add(GetOption(OptionStaticLinkage)); } // finally add method group options options.AddRange(methodGroupOptions); var responseFile = Path.GetTempFileName(); File.WriteAllLines(responseFile, options); //Debug.Log("Burst compile with response file: " + responseFile); try { Runner.RunManagedProgram(Path.Combine(BurstLoader.RuntimePath, BurstAotCompilerExecutable), "--debug=true " + "@" + responseFile, Application.dataPath + "/..", new BclParser(), null); } catch (Exception e) { Debug.LogError(e.ToString()); } } }