Windows/Linux Toolchain to build to Linux does not work in script

Hello, I am using the Toolchain Win Linux package to build a Linux IL2CPP player from my Windows PC. This package works when I manually change my Target Platform to Linux in the Build Settings and then hit “Build”. However the package does not work when I try and build via my custom C# script that builds Windows (32 and 64 bit) and Linux all at once.

You can see the script below. It just calls BuildPipeline.BuildPlayer(options); with the specific options for each platform.

When I try and run it I get the following error Exception: Exception: C++ code builder is unable to build C++ code for Linux: Could not find valid clang executable at clang.exe
(let me know if you need to see the whole stack trace)

It seems like the package does something extra when manually switching to Linux that my script is not doing. Is there any workaround for this? Having to manually wait for each platform to build every time I make an update is very time consuming.

public class Build
    {

        static string[] scenes = {
            "Assets/Scenes/Menu.unity",
            "Assets/Scenes/Game.unity",
            "Assets/Scenes/Admin.unity",
            "Assets/Scenes/Builder.unity",
        };

        public static void PerformBuild()
        {
            Windows64Build();
            Windows32Build();
            LinuxBuild();
        }

        public static void Windows64Build()
        {
            Debug.Log($"Starting Windows 64 bit build");

            BuildPlayerOptions options = new BuildPlayerOptions();
            options.scenes = scenes;
            options.locationPathName = "Build/Windows64/Skullborn.exe";
            options.target = BuildTarget.StandaloneWindows64;
            options.targetGroup = BuildTargetGroup.Standalone;
            options.options = BuildOptions.None;
            BuildReport report = BuildPipeline.BuildPlayer(options);

            BuildSummary summary = report.summary;

            if (summary.result == BuildResult.Succeeded)
            {
                Debug.Log($"Windows 64 bit succeeded: {summary.totalSize} bytes. path {summary.outputPath}");
            }

            if (summary.result == BuildResult.Failed)
            {
                Debug.Log("Windows 64 bit failed");
            }
        }

        public static void Windows32Build()
        {
            Debug.Log($"Starting Windows 32 bit build");

            BuildPlayerOptions options = new BuildPlayerOptions();
            options.scenes = scenes;
            options.locationPathName = "Build/Windows32/Skullborn.exe";
            options.target = BuildTarget.StandaloneWindows;
            options.targetGroup = BuildTargetGroup.Standalone;
            options.options = BuildOptions.None;
            BuildReport report = BuildPipeline.BuildPlayer(options);

            BuildSummary summary = report.summary;

            if (summary.result == BuildResult.Succeeded)
            {
                Debug.Log($"Windows 32 bit build succeeded: {summary.totalSize} bytes. path {summary.outputPath}");
            }

            if (summary.result == BuildResult.Failed)
            {
                Debug.Log("Windows 32 bit build failed");
            }
        }

        public static void LinuxBuild()
        {
            Debug.Log($"Starting Linux 64 bit build");

            BuildPlayerOptions options = new BuildPlayerOptions();
            options.scenes = scenes;
            options.locationPathName = "Build/Linux/Skullborn";
            options.target = BuildTarget.StandaloneLinux64;
            options.targetGroup = BuildTargetGroup.Standalone;
            options.options = BuildOptions.None;
            BuildReport report = BuildPipeline.BuildPlayer(options);

            BuildSummary summary = report.summary;

            if (summary.result == BuildResult.Succeeded)
            {
                Debug.Log($"Linux build succeeded: {summary.totalSize} bytes. path {summary.outputPath}");
            }

            if (summary.result == BuildResult.Failed)
            {
                Debug.Log("Linux build failed");
            }
        }
    }

Hi Snubber,

Would you be able to post the stack trace as well ? Thank you.

Exception: C++ code builder is unable to build C++ code for Linux: Could not find valid clang executable at clang.exe
UnityEditorInternal.Runner.RunProgram (UnityEditor.Utils.Program p, System.String exe, System.String args, System.String workingDirectory, UnityEditor.Scripting.Compilers.CompilerOutputParserBase parser) (at <55729f52d042492e9efc384182ae2feb>:0)
UnityEditorInternal.Runner.RunManagedProgram (System.String exe, System.String args, System.String workingDirectory, UnityEditor.Scripting.Compilers.CompilerOutputParserBase parser, System.Action`1[T] setupStartInfo) (at <55729f52d042492e9efc384182ae2feb>:0)
UnityEditorInternal.IL2CPPBuilder.RunIl2CppWithArguments (System.Collections.Generic.List`1[T] arguments, System.Action`1[T] setupStartInfo) (at <55729f52d042492e9efc384182ae2feb>:0)
UnityEditorInternal.IL2CPPBuilder.ConvertPlayerDlltoCpp (UnityEditor.Il2Cpp.Il2CppBuildPipelineData data) (at <55729f52d042492e9efc384182ae2feb>:0)
UnityEditorInternal.IL2CPPBuilder.Run () (at <55729f52d042492e9efc384182ae2feb>:0)
UnityEditorInternal.IL2CPPUtils.RunIl2Cpp (System.String stagingAreaData, UnityEditorInternal.IIl2CppPlatformProvider platformProvider, System.Action`1[T] modifyOutputBeforeCompile, UnityEditor.RuntimeClassRegistry runtimeClassRegistry) (at <55729f52d042492e9efc384182ae2feb>:0)
DesktopStandalonePostProcessor.RunIL2CPP (UnityEditor.Modules.BuildPostProcessArgs args, UnityEditorInternal.IIl2CppPlatformProvider il2cppPlatformProvider, System.Collections.Generic.List`1[T] cppPlugins) (at <55729f52d042492e9efc384182ae2feb>:0)
DesktopStandalonePostProcessor.SetupStagingArea (UnityEditor.Modules.BuildPostProcessArgs args, System.Collections.Generic.HashSet`1[T] filesToNotOverwrite) (at <55729f52d042492e9efc384182ae2feb>:0)
DesktopStandalonePostProcessor.PostProcess (UnityEditor.Modules.BuildPostProcessArgs args) (at <55729f52d042492e9efc384182ae2feb>:0)
Rethrow as BuildFailedException: Exception of type 'UnityEditor.Build.BuildFailedException' was thrown.
DesktopStandalonePostProcessor.PostProcess (UnityEditor.Modules.BuildPostProcessArgs args) (at <55729f52d042492e9efc384182ae2feb>:0)
UnityEditor.Modules.DefaultBuildPostprocessor.PostProcess (UnityEditor.Modules.BuildPostProcessArgs args, UnityEditor.BuildProperties& outProperties) (at <55729f52d042492e9efc384182ae2feb>:0)
UnityEditor.PostprocessBuildPlayer.Postprocess (UnityEditor.BuildTargetGroup targetGroup, UnityEditor.BuildTarget target, 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 <55729f52d042492e9efc384182ae2feb>:0)
UnityEditor.BuildPipeline:BuildPlayer(BuildPlayerOptions)
Deployment.Build:LinuxBuild() (at Assets/Scripts/Editor/Deployment/Build.cs:87)
Deployment.Build:PerformBuild() (at Assets/Scripts/Editor/Deployment/Build.cs:24)
MetaEditor:OnInspectorGUI() (at Assets/Scripts/Editor/MetaEditor.cs:42)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)

Hey, did you find a solution to this issue? I am running into exactly the same problem, if I switch platforms manually to Linux, it works fine, if I try to build from script, while still in the Windows target, it fails. The only difference is that for me it says:
Could not find a clang compiler at /usr/bin/clang.exe

The path is different. The only clang.exe I have is the one that comes with Unity, and since I am building from windows that is not the path its in. Switching the editor build target from my script fails as well since then I guess the whole editor reloads, so my script pretty much interrupts itself, so that is not an option.

1 Like

Nope

I'm also starting to see this. Using Windows to build Linux IL2CPP build. Same error as @AllanGameSmithing according to the path.

@kalanasahabandu my game and build is open source, so you can link you to my stack trace and build log: https://boundfoxstudios.teamcity.com/buildConfiguration/FairyTaleDefender_Build_Linux/911?buildTab=log&focusLine=19927&logView=flowAware&linesState=520

I have the same issue.

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>b__94_0()
   at Bee.Core.TinyProfiler2Base.Section[T](String label, Func`1 func, Dictionary`2 metadata)
   at PlayerBuildProgramLibrary.PlayerBuildProgramBase.SetupPlayerBuild()
   at LinuxPlayerBuildProgram.SetupPlayerBuild()
   at PlayerBuildProgramLibrary.PlayerBuildProgramBase.RunBuildProgram()
   at PlayerBuildProgramTypeWrapper.Run(String[] args)
   at Program.Main(String[] args)
UnityEngine.Debug:ExtractStackTraceNoAlloc (byte*,int,string)
UnityEngine.StackTraceUtility:ExtractStackTrace ()
UnityEngine.DebugLogHandler:Internal_Log (UnityEngine.LogType,UnityEngine.LogOption,string,UnityEngine.Object)
UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
UnityEngine.Logger:Log (UnityEngine.LogType,object)
UnityEngine.Debug:LogError (object)
UnityEditor.Modules.BeeBuildPostprocessor:ReportBuildResults ()
UnityEditor.Modules.BeeBuildPostprocessor:PostProcess (UnityEditor.Modules.BuildPostProcessArgs)
UnityEditor.Modules.BeeBuildPostprocessor:PostProcess (UnityEditor.Modules.BuildPostProcessArgs,UnityEditor.BuildProperties&)
UnityEditor.PostprocessBuildPlayer:Postprocess (UnityEditor.BuildTargetGroup,UnityEditor.BuildTarget,int,string,string,string,UnityEditor.BuildOptions,UnityEditor.RuntimeClassRegistry,UnityEditor.Build.Reporting.BuildReport)
UnityEditor.BuildPipeline:BuildPlayerInternalNoCheck (string[],string,string,UnityEditor.BuildTargetGroup,UnityEditor.BuildTarget,int,UnityEditor.BuildOptions,string[],bool)
UnityEditor.BuildPipeline:BuildPlayerInternal (string[],string,string,UnityEditor.BuildTargetGroup,UnityEditor.BuildTarget,int,UnityEditor.BuildOptions,string[])
UnityEditor.BuildPipeline:BuildPlayer (string[],string,string,UnityEditor.BuildTargetGroup,UnityEditor.BuildTarget,int,UnityEditor.BuildOptions,string[])
UnityEditor.BuildPipeline:BuildPlayer (UnityEditor.BuildPlayerOptions)
Editor.Build:BuildPlatform<Editor.Platforms.Linux> () (at Assets/Scripts/Editor/Build.cs:38)
Editor.Build:Linux () (at Assets/Scripts/Editor/Build.cs:18)

I got around it by specifying the build target in the Unity command, even though I also set it in the C# code:

Unity.exe -quit -batchmode -nographics -executeMethod BuildLinux -buildTarget linux64

I have created a Powershell script to build a Windows and Linux build. Each calls its own Unity build command. Meaning, I don't build both targets in the same Unity command.

Scratch that, I was talking too fast. Turns out, what fixed it for me was upgrading to Unity 2023.2.14f1. I had previously used 2023.2.12f1.

Nevermind. I did manage to compile a Linux build using my tiny C# build system but now I'm back to the same error. Unity chooses the right version sometimes. I can't figure out when though.

this is exactly the same problem im having, on unity 2022.12
did you ever find a solution?