Skip to content

Code-Only Development on Linux (Ubuntu) Requires Manual File Copying #2596

@VaclavElias

Description

@VaclavElias

Release Type: Official Release

Version: 4.2.0.2293

Platform(s): Linux

Describe the bug
I am able to build and run code-only on Linux but I have to manually copy files here: /home/vaso/.nuget/packages/stride.core.assets.compilerapp/4.2.0.2293/lib/net8.0, see the step 8 below.

To Reproduce
Steps to reproduce the behavior: Steps are below

Expected behavior
There shouldn't be a manual fiddling with Stride files.

Screenshots
Below

Log and callstacks
N/a

Additional context

This test was done on Ubuntu 24.04.3 LTS.

Optional step:

  • sudo apt update # Fetches the list of available updates
  • sudo apt upgrade # Installs some updates; does not remove packages
  • sudo apt full-upgrade # Installs updates; may also remove some packages, if needed
  • sudo apt autoremove # Removes any old packages that are no longer needed

Important

Last tested on 4th September 2025 with Stride 4.2.1.2442 and Stride.CommunityToolkit 1.0.0-preview.59

Warning

Make sure you use the latest Stride NuGet packages paired with correct Stride.CommunityToolkit NuGet packages and you replace the paths below accordingly.

Setup:

  1. Ensure your Linux distribution is up to date and has an IDE like VS Code or Rider installed.
  2. Install the .NET 8 SDK:
    sudo apt-get install -y dotnet-sdk-8.0
  3. Verify the .NET SDK installation:
    dotnet --list-sdks
  4. Install the required native libraries as outlined in Stride Linux Setup Requirements:
    sudo apt install libfreetype6-dev libopenal-dev libsdl2-dev libfreeimage-dev
  5. Create a simple code-only project:
    • Add the Stride.CommunityToolkit NuGet package instead of Stride.CommunityToolkit.Windows (We should create probably a package called Stride.CommunityToolkit.Linux).
      dotnet add package Stride.CommunityToolkit --prerelease
      
    • If you use Bepu, don't forget
      dotnet add package Stride.CommunityToolkit.Bepu --prerelease
      
    • Add the Stride.Core.Assets.CompilerApp NuGet package.
      dotnet add package Stride.Core.Assets.CompilerApp --prerelease
      
    • Add a sample code or your code to Program.cs
    • Do not build the project yet.
  6. Update your project file (.csproj) to include the following properties:
    • Add RuntimeIdentifier
    • Add StrideGraphicsApi
    • Add IncludeAssets to the PackageReference
    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
        <StrideGraphicsApi>OpenGL</StrideGraphicsApi>
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Include="Stride.CommunityToolkit" Version="1.0.0-preview.49" />
        <PackageReference Include="Stride.Core.Assets.CompilerApp" Version="4.2.0.2293" IncludeAssets="build;buildTransitive" />
      </ItemGroup>
    </Project>
  7. You should be able to build the project successfully with dotnet build, you have to do step 8 before you do dotnet build
  8. Manual Step: Copy the following four (4) .so files to stride.core.assets.compilerapp/4.2.0.2293/lib/net8.0:
    • From: /home/vaso/.nuget/packages/stride.physics/4.2.0.2293/runtimes/linux-x64/native/libbulletc.so
    • From: /home/vaso/.nuget/packages/stride.assets/4.2.0.2293/runtimes/linux-x64/native/VHACD.so
    • From: /home/vaso/.nuget/packages/stride.textureconverter/4.2.0.2293/runtimes/linux-x64/native/DxtWrapper.so
    • From: /home/vaso/.nuget/packages/stride.textureconverter/4.2.0.2293/runtimes/linux-x64/native/PVRTextLib.so
    • To: /home/vaso/.nuget/packages/stride.core.assets.compilerapp/4.2.0.2293/lib/net8.0:
  9. You should be able to run application dotnet run and see this below (The black debug text is another issue..)
Image

If you skip step 8, you might get this error:

vaso@vaso-stride:~/Projects/Project01$ dotnet build
MSBuild version 17.8.5+b5265ef37 for .NET
  Determining projects to restore...
  Restored /home/vaso/Projects/Project01/Project01.csproj (in 1.14 sec).
  Patch for assembly [Project01, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]
  Project01 -> /home/vaso/Projects/Project01/bin/Debug/net8.0/linux-x64/Project01.dll
  Unhandled exception. System.TypeInitializationException: The type initializer for '<Module>' threw an exception.
   ---> System.TypeInitializationException: The type initializer for '<Module>' threw an exception.
   ---> System.TypeInitializationException: The type initializer for '<Module>' threw an exception.
   ---> System.InvalidOperationException: Could not load native library libbulletc using CPU architecture x64.
     at Stride.Core.NativeLibraryHelper.PreloadLibrary(String libraryName, Type owner) in C:\BuildAgent\work\b5f46e3c4829a09e\sources\core\Stride.Core\Native\NativeLibraryHelper.cs:line 123
     at Stride.Engine.Module.Initialize() in C:\BuildAgent\work\b5f46e3c4829a09e\sources\engine\Stride.Physics\Module.cs:line 18
     at Stride.Core.CompilerServices.AutoGenerated.ModuleInitializer.<ModuleInitializer>F5D91558074716FFC11AFA8A899C97D0B6F82A81622FFA2C3017C0F689B8C9D8E__ModuleInitializer.Initialize() in C:\BuildAgent\work\b5f46e3c4829a09e\sources\engine\Stride.Physics\obj\Release\net8.0\Stride.Core.CompilerServices\Stride.Core.CompilerServices.Generators.ModuleInitializerGenerator\ModuleInitializer.cs:line 9
     at .cctor()
     --- End of inner exception stack trace ---
     at UpdateEngineAutoGenerated.UpdateMain0()
     at .cctor()
     --- End of inner exception stack trace ---
     at Stride.Core.DataSerializers.Stride_Core_Assets_CompilerAppSerializerFactory.Initialize()
     at .cctor()
     --- End of inner exception stack trace ---
  Aborted (core dumped)
/home/vaso/.nuget/packages/stride.core.assets.compilerapp/4.2.0.2293/buildTransitive/Stride.Core.Assets.CompilerApp.targets(154,5): error MSB3073: The command "dotnet "/home/vaso/.nuget/packages/stride.core.assets.compilerapp/4.2.0.2293/buildTransitive/../lib/net8.0/Stride.Core.Assets.CompilerApp.dll"  --disable-auto-compile --project-configuration "Debug" --platform=Linux --project-configuration=Debug --compile-property:StrideGraphicsApi=OpenGL --output-path="/home/vaso/Projects/Project01/bin/Debug/net8.0/linux-x64/data" --build-path="/home/vaso/Projects/Project01/obj/stride/assetbuild/data" --package-file="/home/vaso/Projects/Project01/Project01.csproj" --msbuild-uptodatecheck-filebase="/home/vaso/Projects/Project01/obj/Debug/net8.0/linux-x64/stride/assetcompiler-uptodatecheck"" exited with code 134. [/home/vaso/Projects/Project01/Project01.csproj]

Build FAILED.

/home/vaso/.nuget/packages/stride.core.assets.compilerapp/4.2.0.2293/buildTransitive/Stride.Core.Assets.CompilerApp.targets(154,5): error MSB3073: The command "dotnet "/home/vaso/.nuget/packages/stride.core.assets.compilerapp/4.2.0.2293/buildTransitive/../lib/net8.0/Stride.Core.Assets.CompilerApp.dll"  --disable-auto-compile --project-configuration "Debug" --platform=Linux --project-configuration=Debug --compile-property:StrideGraphicsApi=OpenGL --output-path="/home/vaso/Projects/Project01/bin/Debug/net8.0/linux-x64/data" --build-path="/home/vaso/Projects/Project01/obj/stride/assetbuild/data" --package-file="/home/vaso/Projects/Project01/Project01.csproj" --msbuild-uptodatecheck-filebase="/home/vaso/Projects/Project01/obj/Debug/net8.0/linux-x64/stride/assetcompiler-uptodatecheck"" exited with code 134. [/home/vaso/Projects/Project01/Project01.csproj]
    0 Warning(s)
    1 Error(s)
    <!-- Automatically copy Linux native libraries to CompilerApp directory -->
    <Target Name="CopyLinuxNativeLibraries" BeforeTargets="Build" Condition="'$(RuntimeIdentifier)' == 'linux-x64'">
        <PropertyGroup>
            <NuGetPackagesPath>$(NUGET_PACKAGES)</NuGetPackagesPath>
            <NuGetPackagesPath Condition="'$(NuGetPackagesPath)' == ''">$(UserProfile)\.nuget\packages</NuGetPackagesPath>
            <NuGetPackagesPath Condition="'$(NuGetPackagesPath)' == '' AND '$(OS)' != 'Windows_NT'">$(HOME)/.nuget/packages</NuGetPackagesPath>
            <StrideVersion>4.2.1.2442</StrideVersion>
            <CompilerAppPath>$(NuGetPackagesPath)/stride.core.assets.compilerapp/$(StrideVersion)/lib/net8.0</CompilerAppPath>
        </PropertyGroup>
        
        <ItemGroup>
            <NativeLibrariesToCopy Include="$(NuGetPackagesPath)/stride.physics/$(StrideVersion)/runtimes/linux-x64/native/libbulletc.so" />
            <NativeLibrariesToCopy Include="$(NuGetPackagesPath)/stride.assets/$(StrideVersion)/runtimes/linux-x64/native/VHACD.so" />
            <NativeLibrariesToCopy Include="$(NuGetPackagesPath)/stride.textureconverter/$(StrideVersion)/runtimes/linux-x64/native/DxtWrapper.so" />
            <NativeLibrariesToCopy Include="$(NuGetPackagesPath)/stride.textureconverter/$(StrideVersion)/runtimes/linux-x64/native/PVRTextLib.so" />
        </ItemGroup>
        
        <Copy SourceFiles="@(NativeLibrariesToCopy)" 
              DestinationFolder="$(CompilerAppPath)" 
              SkipUnchangedFiles="true"
              Condition="Exists('$(CompilerAppPath)')" />
        
        <Message Text="Copied Linux native libraries to $(CompilerAppPath)" Importance="high" />
    </Target>

v2

<Target Name="CopyLinuxNativeLibraries" BeforeTargets="Build" Condition="'$(RuntimeIdentifier)' == 'linux-x64'">
    <PropertyGroup>
        <NuGetPackagesPath>$(NUGET_PACKAGES)</NuGetPackagesPath>
        <NuGetPackagesPath Condition="'$(NuGetPackagesPath)' == ''">$(UserProfile)\.nuget\packages</NuGetPackagesPath>
        <NuGetPackagesPath Condition="'$(NuGetPackagesPath)' == '' AND '$(OS)' != 'Windows_NT'">$(HOME)/.nuget/packages</NuGetPackagesPath>
        <StrideVersion>4.2.1.2442</StrideVersion>
        <CompilerAppPath>$(NuGetPackagesPath)/stride.core.assets.compilerapp/$(StrideVersion)/lib/net8.0</CompilerAppPath>
    </PropertyGroup>
    
    <!-- Debug: Show resolved paths -->
    <Message Text="=== CopyLinuxNativeLibraries Debug Info ===" Importance="high" />
    <Message Text="NuGet Packages Path: $(NuGetPackagesPath)" Importance="high" />
    <Message Text="Stride Version: $(StrideVersion)" Importance="high" />
    <Message Text="Compiler App Path: $(CompilerAppPath)" Importance="high" />
    <Message Text="Compiler App Path Exists: $([System.IO.Directory]::Exists('$(CompilerAppPath)'))" Importance="high" />
    
    <ItemGroup>
        <NativeLibrariesToCopy Include="$(NuGetPackagesPath)/stride.physics/$(StrideVersion)/runtimes/linux-x64/native/libbulletc.so" />
        <NativeLibrariesToCopy Include="$(NuGetPackagesPath)/stride.assets/$(StrideVersion)/runtimes/linux-x64/native/VHACD.so" />
        <NativeLibrariesToCopy Include="$(NuGetPackagesPath)/stride.textureconverter/$(StrideVersion)/runtimes/linux-x64/native/DxtWrapper.so" />
        <NativeLibrariesToCopy Include="$(NuGetPackagesPath)/stride.textureconverter/$(StrideVersion)/runtimes/linux-x64/native/PVRTextLib.so" />
    </ItemGroup>
    
    <!-- Debug: Show each file to be copied and whether it exists -->
    <Message Text="Files to copy:" Importance="high" />
    <Message Text="  - %(NativeLibrariesToCopy.Identity) [Exists: $([System.IO.File]::Exists('%(NativeLibrariesToCopy.Identity)'))]" Importance="high" />
    
    <!-- Warning if destination doesn't exist -->
    <Warning Text="Destination folder does not exist: $(CompilerAppPath)" Condition="!Exists('$(CompilerAppPath)')" />
    
    <Copy SourceFiles="@(NativeLibrariesToCopy)" 
          DestinationFolder="$(CompilerAppPath)" 
          SkipUnchangedFiles="true"
          Condition="Exists('$(CompilerAppPath)')">
        <Output TaskParameter="CopiedFiles" ItemName="SuccessfullyCopiedFiles" />
    </Copy>
    
    <!-- Debug: Show what was actually copied -->
    <Message Text="Successfully copied $(SuccessfullyCopiedFiles->Count()) files:" Importance="high" Condition="'@(SuccessfullyCopiedFiles)' != ''" />
    <Message Text="  - %(SuccessfullyCopiedFiles.Filename)%(SuccessfullyCopiedFiles.Extension)" Importance="high" />
    <Message Text="No files were copied (already up-to-date or destination missing)" Importance="high" Condition="'@(SuccessfullyCopiedFiles)' == ''" />
    <Message Text="=======================================" Importance="high" />
</Target>

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions