Open peq42 opened 1 year ago
@peq42 would you be able to give me some additional info and I'll try and track it down? Main things being:
I've run into that issue in some Unity versions when building for Android due to an issue with some of the pipelines so it may be similar.
Unity version: 2022.1.20f1 Render pipeline: URP Running on Windows 10, but I had the android platform selected for the build target
I ran into a similar issue when building for android(if I didnt have the android platform selected, it wouldnt build, saying the android SDK wasnt installed) but I made a fix and will make a pull request for it
I've tried a few times with a couple of different projects (UTP ones as as well as the base repo) but I haven't been able to reproduce either of the issues so far. It manages to build in each case for all of the platforms regardless of the starting platform. Would it be possible to paste in the full text of the error message? That might give me some leads.
I get the following 4 errors thrown when trying to build for linux through the script(through unity's default window, it works just fine):
Error 1:
error: Could not set up a toolchain for Architecture x64. Make sure you have the right build tools installed for il2cpp builds. Details:
UnityEditor.BuildPipeline:BuildPlayer (UnityEditor.BuildPlayerOptions)
BuildTools:BuildIndividualTarget (UnityEditor.BuildTarget) (at Assets/Plugins/editor/BuildTools.cs:176)
BuildTools/
Error 2:
Internal build system error. BuildProgram exited with code -2146233088.
error: Could not set up a toolchain for Architecture x64. Make sure you have the right build tools installed for il2cpp builds. Details:
Could not find a clang compiler at /usr/bin/clang.exe
Unity.IL2CPP.Bee.BuildLogic.ToolchainNotFoundException: Could not find a clang compiler at /usr/bin/clang.exe
at Unity.IL2CPP.Bee.BuildLogic.Linux.LinuxBuildLogic.UserAvailableToolchainFor(Architecture architecture, NPath toolChainPath, NPath sysRootPath)
at PlayerBuildProgramLibrary.PlayerBuildProgramBase.GetIl2CppToolChain(PlatformBuildLogic platform, Architecture architecture, NPath toolChainPath, NPath sysrootPath)
at PlayerBuildProgramLibrary.PlayerBuildProgramBase.SetupIl2CppBuild()
at PlayerBuildProgramLibrary.PlayerBuildProgramBase.SetupPlayerBuild()
at LinuxPlayerBuildProgram.SetupPlayerBuild()
at PlayerBuildProgramLibrary.PlayerBuildProgramBase.RunBuildProgram()
at PlayerBuildProgramTypeWrapper.Run(String[] args)
at Program.Main(String[] args)
UnityEditor.BuildPipeline:BuildPlayer (UnityEditor.BuildPlayerOptions)
BuildTools:BuildIndividualTarget (UnityEditor.BuildTarget) (at Assets/Plugins/editor/BuildTools.cs:176)
BuildTools/
Error 3: BuildFailedException: Incremental Player build failed! UnityEditor.Modules.BeeBuildPostprocessor.PostProcess (UnityEditor.Modules.BuildPostProcessArgs args) (at <686f40992bed4a6ebc158b4beb1e91db>:0) UnityEditor.Modules.DefaultBuildPostprocessor.PostProcess (UnityEditor.Modules.BuildPostProcessArgs args, UnityEditor.BuildProperties& outProperties) (at <686f40992bed4a6ebc158b4beb1e91db>:0) UnityEditor.PostprocessBuildPlayer.Postprocess (UnityEditor.BuildTargetGroup targetGroup, UnityEditor.BuildTarget target, System.Int32 subtarget, System.String installPath, System.String companyName, System.String productName, System.Int32 width, System.Int32 height, UnityEditor.BuildOptions options, UnityEditor.RuntimeClassRegistry usedClassRegistry, UnityEditor.Build.Reporting.BuildReport report) (at <686f40992bed4a6ebc158b4beb1e91db>:0) UnityEditor.BuildPipeline:BuildPlayer(BuildPlayerOptions) BuildTools:BuildIndividualTarget(BuildTarget) (at Assets/Plugins/editor/BuildTools.cs:176)
also, my buildtools.cs looks like this(I've modified it slightly):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using Unity.EditorCoroutines.Editor;
public class BuildTools : EditorWindow
{
[MenuItem("Tools/Build Tools")]
public static void OnShowTools()
{
EditorWindow.GetWindow<BuildTools>();
}
private BuildTargetGroup GetTargetGroupForTarget(BuildTarget target) => target switch
{
BuildTarget.Android => BuildTargetGroup.Android,
BuildTarget.StandaloneWindows64 => BuildTargetGroup.Standalone,
BuildTarget.WebGL => BuildTargetGroup.WebGL,
BuildTarget.StandaloneLinux64 => BuildTargetGroup.Standalone,
_ => BuildTargetGroup.Unknown
};
Dictionary<BuildTarget, bool> TargetsToBuild = new Dictionary<BuildTarget, bool>();
List<BuildTarget> AvailableTargets = new List<BuildTarget>();
private void OnEnable()
{
AvailableTargets.Clear();
var buildTargets = System.Enum.GetValues(typeof(BuildTarget));
foreach(var buildTargetValue in buildTargets)
{
BuildTarget target = (BuildTarget)buildTargetValue;
// skip if unsupported
if (!BuildPipeline.IsBuildTargetSupported(GetTargetGroupForTarget(target), target))
continue;
AvailableTargets.Add(target);
// add the target if not in the build list
if (!TargetsToBuild.ContainsKey(target))
TargetsToBuild[target] = false;
}
// check if any targets have gone away
if (TargetsToBuild.Count > AvailableTargets.Count)
{
// build the list of removed targets
List<BuildTarget> targetsToRemove = new List<BuildTarget>();
foreach(var target in TargetsToBuild.Keys)
{
if (!AvailableTargets.Contains(target))
targetsToRemove.Add(target);
}
// cleanup the removed targets
foreach(var target in targetsToRemove)
TargetsToBuild.Remove(target);
}
}
private void OnGUI()
{
GUILayout.Label("Platforms to Build", EditorStyles.boldLabel);
// display the build targets
int numEnabled = 0;
foreach(var target in AvailableTargets)
{
TargetsToBuild[target] = EditorGUILayout.Toggle(target.ToString(), TargetsToBuild[target]);
if (TargetsToBuild[target])
numEnabled++;
}
if (numEnabled > 0)
{
// attempt to build?
string prompt = numEnabled == 1 ? "Build 1 Platform" : $"Build {numEnabled} Platforms";
if (GUILayout.Button(prompt))
{
List<BuildTarget> selectedTargets = new List<BuildTarget>();
foreach (var target in AvailableTargets)
{
if (TargetsToBuild[target])
selectedTargets.Add(target);
}
EditorCoroutineUtility.StartCoroutine(PerformBuild(selectedTargets), this);
}
}
}
IEnumerator PerformBuild(List<BuildTarget> targetsToBuild)
{
// show the progress display
int buildAllProgressID = Progress.Start("Build All", "Building all selected platforms", Progress.Options.Sticky);
Progress.ShowDetails();
yield return new EditorWaitForSeconds(1f);
BuildTarget originalTarget = EditorUserBuildSettings.activeBuildTarget;
// build each target
for (int targetIndex = 0; targetIndex < targetsToBuild.Count; ++targetIndex)
{
var buildTarget = targetsToBuild[targetIndex];
Progress.Report(buildAllProgressID, targetIndex + 1, targetsToBuild.Count);
int buildTaskProgressID = Progress.Start($"Build {buildTarget.ToString()}", null, Progress.Options.Sticky, buildAllProgressID);
yield return new EditorWaitForSeconds(1f);
// perform the build
if (!BuildIndividualTarget(buildTarget))
{
Progress.Finish(buildTaskProgressID, Progress.Status.Failed);
Progress.Finish(buildAllProgressID, Progress.Status.Failed);
if (EditorUserBuildSettings.activeBuildTarget != originalTarget)
EditorUserBuildSettings.SwitchActiveBuildTargetAsync(GetTargetGroupForTarget(originalTarget), originalTarget);
yield break;
}
Progress.Finish(buildTaskProgressID, Progress.Status.Succeeded);
yield return new EditorWaitForSeconds(1f);
}
Progress.Finish(buildAllProgressID, Progress.Status.Succeeded);
if (EditorUserBuildSettings.activeBuildTarget != originalTarget)
EditorUserBuildSettings.SwitchActiveBuildTargetAsync(GetTargetGroupForTarget(originalTarget), originalTarget);
yield return null;
}
bool BuildIndividualTarget(BuildTarget target)
{
BuildPlayerOptions options = new BuildPlayerOptions();
// get the list of scenes
List<string> scenes = new List<string>();
foreach (var scene in EditorBuildSettings.scenes)
scenes.Add(scene.path);
// configure the build
options.scenes = scenes.ToArray();
options.target = target;
options.targetGroup = GetTargetGroupForTarget(target);
// set the location path name
EditorUserBuildSettings.SwitchActiveBuildTarget(GetTargetGroupForTarget(target), target);
if (target == BuildTarget.Android)
{
string apkName = PlayerSettings.productName + ".apk";
options.locationPathName = System.IO.Path.Combine("Builds", target.ToString(), apkName);
}else if (target == BuildTarget.StandaloneWindows64)
{
options.locationPathName = System.IO.Path.Combine("Builds", target.ToString(), PlayerSettings.productName+".exe");
}else if (target == BuildTarget.StandaloneLinux64)
{
options.locationPathName = System.IO.Path.Combine("Builds", target.ToString(), PlayerSettings.productName+".x86_64");
}
else
options.locationPathName = System.IO.Path.Combine("Builds", target.ToString(), PlayerSettings.productName);
if (BuildPipeline.BuildCanBeAppended(target, options.locationPathName) == CanAppendBuild.Yes)
options.options = BuildOptions.AcceptExternalModificationsToPlayer;
else
options.options = BuildOptions.None;
// start the build
BuildReport report = BuildPipeline.BuildPlayer(options);
// was the build successful?
if (report.summary.result == BuildResult.Succeeded)
{
Debug.Log($"Build for {target.ToString()} completed in {report.summary.totalTime.Seconds} seconds");
return true;
}
Debug.LogError($"Build for {target.ToString()} failed");
return false;
}
}
It looks like the root cause may be the same issue as the one being described here.
The gist seems to be that while BuildPlayer does switch platform, it doesn't run the logic to setup the sysroot modules (needed for the build). And manually calling the function to initialise them isn't an option because it will kill editor coroutines. That tallies with what I've been able to reproduce in testing.
I'll have a try with other approaches and see if I can find a solution but it'll likely need a fix from Unity for it.
Knowing unity this might never be fixed... that post is over a year old
Hopefully not but potentially. I have a possible workaround I want to try with using C# tasks instead of editor coroutines but it'll depend on how Unity resets things from a scripting point of view, they may also not persist. But if I can get that to work then it may be able to be worked around.
When trying to compile for that platform, the build fails saying that the toolchain may not be installed(it is). It works normally when manually building using unity's default build window