Abstract: We practically show examples of 15 different .NET8/9 build modes, including Framework-Dependent and Framework-Independent, how to bundle an app into a single file, how to trim app bundles from unused libraries, and how to build an Ahead-of-time (AOT) precompiled app.
1. .NET8/9 toolset supports different build/publish/deployment modes
I was experimenting with different project properties/flags, and I developed several proof-of-concept build projects showcasing different build/publish/deployment modes available in .NET8/9, using Microsoft tools.
1.2. Articles in this series
For technical reasons, I will organize this text into several articles.
- .NET8/9 – Testing different Build/Deployment modes – Part 1
- .NET8/9 – Testing different Build/Deployment modes – Part 2
- .NET8/9 – Testing different Build/Deployment modes – Part 3
- .NET8/9 – Testing different Build/Deployment modes – Part 4
- .NET8/9 – Testing different Build/Deployment modes – Part 5
- .NET8/9 – Testing different Build/Deployment modes – Part 6
2. New build configurations for NET 8.0.11 and NET 9.0.0
New build configurations/scripts for NET_8.0.11/SDK_8.0.404 and NET_9.0.0/SDK_9.0.101 environments are here. Build types and the rationale are as before, just some new build tricks were made. Any better C# developer should be able to understand these build settings.
These are builds in NET_8.0.11/SDK_8.0.404 environment.
All these builds worked also in NET_9.0.0/SDK_9.0.101 environment.
===Build 1=======================================================================
Location:
->\ConsoleApp1\bin\Release\net8.0-windows\win-x64\
Publish mode:
1)Release; 2)framework-dependent; 3)Platform-specific-win-x64; 4)Un-bundled; 5)Untrimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesNotInSingleFile; 9)assembliesNotCompressed; 10)NotAot
Works! App started and it runs properly.
Content:
-47 files
-13.3 MB
-----Here is project file---------------
<!--ConsoleApp1.csproj +++++++++++++++++++++++++++++++++++++-->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>x64</PlatformTarget>
<Platforms>AnyCPU;x64</Platforms>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>embedded</DebugType>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary1\ClassLibraryA.csproj" />
</ItemGroup>
<Target Name="RunAfterBuild1" AfterTargets="Build">
<Exec Command="call Framework_SingleFile_Win-X64.cmd" Condition=" '$(BuildingInsideVisualStudio)' == 'true' "/>
</Target>
</Project>
===Build 2=======================================================================
Location:
->\ConsoleApp1\Framework_SingleFile_Win-X64\
Publish mode:
1)Release; 2)framework-dependent; 3)Platform-specific-win-x64; 4)Single-file; 5)Untrimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesNotInSingleFile; 9)assembliesNotCompressed; 10)NotAot
Works! App started and it runs properly.
Content:
-2 files
-13.3 MB
----Use previous project file and this script-------------------
Framework_SingleFile_Win-X64.cmd
echo .NET SDK version:
dotnet --version
dotnet publish ConsoleApp1.csproj --nologo --no-restore --runtime win-x64 --use-current-runtime --configuration Release -p:PublishSingleFile=true --no-self-contained --output ./Framework_SingleFile_Win-X64
===Build 3-Build that I was not able to make==================================================
Location:
->\ConsoleApp4\Framework_SingleFile_Win-X64_Trimmed\
Publish mode:
1)Release; 2)framework-dependent; 3)Platform-specific-win-x64; 4)Single-file; 5)Trimmed; 6)Not-precompiled; 7)PdbEmbeded; 8)binariesNotInSingleFile; 9)assembliesNotCompressed
I was looking into options, but was not able to make "Framework-dependent_Single-file_Trimmed" build.
It looks like Trimmed builds are possible with Microsoft tools in .NET8 only for self-contained (which is opposite to framework-dependent) mode builds.
I was getting this when tried:
Error (active) NETSDK1102 Optimizing assemblies for size is not supported for the selected publish configuration. Please ensure that you are publishing a self-contained app.
-----Here is project file---------------
<!--ConsoleApp1.csproj +++++++++++++++++++++++++++++++++++++-->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>x64</PlatformTarget>
<Platforms>AnyCPU;x64</Platforms>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>embedded</DebugType>
<PublishTrimmed>true</PublishTrimmed>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary1\ClassLibraryA.csproj" />
</ItemGroup>
<Target Name="RunAfterBuild1" AfterTargets="Build">
<Exec Command="Framework_SingleFile_Win-X64_Trimmed.cmd" Condition=" '$(BuildingInsideVisualStudio)' == 'true' "/>
</Target>
</Project>
----Use previous project file and this script-------------------
Framework_SingleFile_Win-X64_Trimmed.cmd
echo .NET SDK version:
dotnet --version
dotnet publish ConsoleApp4.csproj --nologo --no-restore --runtime win-x64 --use-current-runtime --configuration Release -p:PublishSingleFile=true --no-self-contained -p:PublishTrimmed=true --output ./Framework_SingleFile_Win-X64_Trimmed
===Build 4=======================================================================
Location:
->\ConsoleApp2\bin\Release\net8.0-windows\win-x64\
Publish mode:
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Un-bundled; 5)Untrimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesNotInSingleFile; 9)assembliesNotCompressed ; 10)NotAot
Works! App started and it runs properly.
Content:
-255 files
-90 MB
-----Here is project file---------------
<!--ConsoleApp2.csproj +++++++++++++++++++++++++++++++++++++-->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>x64</PlatformTarget>
<Platforms>AnyCPU;x64</Platforms>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>embedded</DebugType>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
<IsTrimmable>true</IsTrimmable>
<SelfContained>true</SelfContained>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary1\ClassLibraryA.csproj" />
</ItemGroup>
<Target Name="RunAfterBuild1" AfterTargets="Build">
<Exec Command="call SelfContained_SingleFile_win-x64.cmd" Condition=" '$(BuildingInsideVisualStudio)' == 'true' "/>
</Target>
<Target Name="RunAfterBuild2" AfterTargets="Build">
<Exec Command="call SelfContained_SingleFile_win-x64_Trimmed.cmd" Condition=" '$(BuildingInsideVisualStudio)' == 'true' "/>
</Target>
</Project>
===Build 5=======================================================================
Location:
->\ConsoleApp2\SelfContained_SingleFile_win-x64\
Publish mode:
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Single-file; 5)Untrimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesNotInSingleFile; 9)assembliesNotCompressed ; 10)NotAot
Works! App started and it runs properly.
Content:
-2 files
-75 MB
----Use previous project file and this script-------------------
SelfContained_SingleFile_win-x64.cmd
echo .NET SDK version:
dotnet --version
dotnet publish ConsoleApp2.csproj --nologo --no-restore --runtime win-x64 --configuration Release -p:PublishSingleFile=true -p:SelfContained=true -p:PublishReadyToRun=false -p:PublishTrimmed=false --output ./SelfContained_SingleFile_win-x64
===Build 6=======================================================================
Location:
->\ConsoleApp2\SelfContained_SingleFile_win-x64_Trimmed\
Publish mode:
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Single-file; 5)Trimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesNotInSingleFile; 9)assembliesNotCompressed ; 10)NotAot
Works! App started and it runs properly.
Content:
-2 files
-12 MB
----Use previous project file and this script-------------------
SelfContained_SingleFile_win-x64_Trimmed.cmd
echo .NET SDK version:
dotnet --version
dotnet publish ConsoleApp2.csproj --nologo --no-restore --runtime win-x64 --configuration Release -p:PublishSingleFile=true -p:SelfContained=true -p:PublishReadyToRun=false -p:PublishTrimmed=true --output ./SelfContained_SingleFile_win-x64_Trimmed
===Build 7=======================================================================
Location:
->\ConsoleApp3\bin\Release\net8.0-windows\win-x64\
Publish mode :
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Un-bundled; 5)Untrimmed; 6)Not-precompiled; 7)PdbEmbeded; 8)binariesNotInSingleFile; 9)assembliesNotCompressed ; 10)NotAot
(I think above is correct interpretation. I am not sure because there are many flags/properties in
the project file, but it seems they do not have effect until "dotnet publish" is called)
Works! App started and it runs properly.
Content:
-255 files
-90 MB
-----Here is project file---------------
<!--ConsoleApp3.csproj +++++++++++++++++++++++++++++++++++++-->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>x64</PlatformTarget>
<Platforms>AnyCPU;x64</Platforms>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>embedded</DebugType>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
<IsTrimmable>true</IsTrimmable>
<SelfContained>true</SelfContained>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary1\ClassLibraryA.csproj" />
</ItemGroup>
<Target Name="RunAfterBuild1" AfterTargets="Build">
<Exec Command="call SelfContained_SingleFile_win-x64_ReadyToRun.cmd" Condition=" '$(BuildingInsideVisualStudio)' == 'true' "/>
</Target>
<Target Name="RunAfterBuild2" AfterTargets="Build">
<Exec Command="call SelfContained_SingleFile_win-x64_Trimmed_ReadyToRun.cmd" Condition=" '$(BuildingInsideVisualStudio)' == 'true' "/>
</Target>
</Project>
===Build 8=======================================================================
Location:
->\ConsoleApp3\SelfContained_SingleFile_win-x64_ReadyToRun\
Publish mode :
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Single-file; 5)Untrimmed; 6)ReadyToRun; 7)PdbEmbeded; 8)binariesNotInSingleFile; 9)assembliesNotCompressed ; 10)NotAot
Works! App started and it runs properly.
Content:
-2 files
-108 MB
----Use previous project file and this script-------------------
SelfContained_SingleFile_win-x64_ReadyToRun.cmd
echo .NET SDK version:
dotnet --version
dotnet publish ConsoleApp3.csproj --nologo --no-restore --runtime win-x64 --configuration Release -p:PublishSingleFile=true -p:SelfContained=true -p:PublishTrimmed=false -p:PublishReadyToRun=true --output ./SelfContained_SingleFile_win-x64_ReadyToRun
===Build 9=======================================================================
Location:
->\ConsoleApp3\SelfContained_SingleFile_win-x64_Trimmed_ReadyToRun\
Publish mode :
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Single-file; 5)Trimmed; 6)ReadyToRun; 7)PdbEmbeded; 8)binariesNotInSingleFile; 9)assembliesNotCompressed ; 10)NotAot
Works! App started and it runs properly.
Content:
-2 files
-15 MB
----Use previous project file and this script-------------------
SelfContained_SingleFile_win-x64_Trimmed_ReadyToRun.cmd
echo .NET SDK version:
dotnet --version
dotnet publish ConsoleApp3.csproj --nologo --no-restore --runtime win-x64 --configuration Release -p:PublishSingleFile=true -p:SelfContained=true -p:PublishReadyToRun=true -p:PublishTrimmed=true --output ./SelfContained_SingleFile_win-x64_Trimmed_ReadyToRun
===Build 10=======================================================================
Location:
->\ConsoleApp1C\bin\Release\net8.0-windows\win-x64\
Publish mode:
1)Release; 2)framework-dependent; 3)Platform-specific-win-x64; 4)Un-bundled; 5)Untrimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesNotInSingleFile ; 9)assembliesNotCompressed ; 10)NotAot
Works! App started and it runs properly.
Content:
-47 files
-13 MB
(flags do not work on this level of build)
-----Here is project file---------------
<!--ConsoleApp1C.csproj +++++++++++++++++++++++++++++++++++++-->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>x64</PlatformTarget>
<Platforms>AnyCPU;x64</Platforms>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>embedded</DebugType>
<PublishSingleFile>true</PublishSingleFile>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary1\ClassLibraryA.csproj" />
</ItemGroup>
<Target Name="RunAfterBuild1" AfterTargets="Build">
<Exec Command="Framework_SingleFile_Win-X64.cmd" Condition=" '$(BuildingInsideVisualStudio)' == 'true' "/>
</Target>
</Project>
===Build 11=======================================================================
Location:
->\ConsoleApp1C\Framework_SingleFile_Win-X64\
Publish mode:
1)Release; 2)framework-dependent; 3)Platform-specific-win-x64; 4)Single-file; 5)Untrimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesInSingleFile ; 9)assembliesNotCompressed ; 10)NotAot
Works! App started and it runs properly.
Content:
-1 file
-14 MB
----Use previous project file and this script-------------------
Framework_SingleFile_Win-X64.cmd
echo .NET SDK version:
dotnet --version
dotnet publish ConsoleApp1C.csproj --nologo --no-restore --runtime win-x64 --use-current-runtime --configuration Release -p:PublishSingleFile=true --no-self-contained --output ./Framework_SingleFile_Win-X64
===Build 12=======================================================================
Location:
->\ConsoleApp2C\bin\Release\net8.0-windows\win-x64\
Publish mode:
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Un-bundled; 5)Untrimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesInSingleFile; 9)assembliesCompressed ; 10)NotAot
Works! App started and it runs properly.
Content:
-255 files
-90 MB
-----Here is project file---------------
<!--ConsoleApp2C.csproj +++++++++++++++++++++++++++++++++++++-->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>x64</PlatformTarget>
<Platforms>AnyCPU;x64</Platforms>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>embedded</DebugType>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
<IsTrimmable>true</IsTrimmable>
<SelfContained>true</SelfContained>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary1\ClassLibraryA.csproj" />
</ItemGroup>
<Target Name="RunAfterBuild1" AfterTargets="Build">
<Exec Command="call SelfContained_SingleFile_win-x64.cmd" Condition=" '$(BuildingInsideVisualStudio)' == 'true' "/>
</Target>
<Target Name="RunAfterBuild2" AfterTargets="Build">
<Exec Command="call SelfContained_SingleFile_win-x64_Trimmed.cmd" Condition=" '$(BuildingInsideVisualStudio)' == 'true' "/>
</Target>
</Project>
===Build 13=======================================================================
Location:
->\ConsoleApp2C\SelfContained_SingleFile_win-x64\
Publish mode:
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Single-file; 5)Untrimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesInSingleFile; 9)assembliesCompressed; 10)NotAot
Works! App started and it runs properly.
Content:
-1 file
-39 MB
----Use previous project file and this script-------------------
SelfContained_SingleFile_win-x64.cmd
echo .NET SDK version:
dotnet --version
dotnet publish ConsoleApp2C.csproj --nologo --no-restore --runtime win-x64 --configuration Release -p:PublishSingleFile=true -p:SelfContained=true -p:PublishReadyToRun=false -p:PublishTrimmed=false --output ./SelfContained_SingleFile_win-x64
===Build 14=======================================================================
Location:
->\ConsoleApp2C\SelfContained_SingleFile_win-x64_Trimmed\
Publish mode:
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Single-file; 5)Trimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesInSingleFile; 9)assembliesCompressed ; 10)NotAot
Works! App started and it runs properly.
Content:
-1 file
-10 MB
----Use previous project file and this script-------------------
SelfContained_SingleFile_win-x64_Trimmed.cmd
echo .NET SDK version:
dotnet --version
dotnet publish ConsoleApp2C.csproj --nologo --no-restore --runtime win-x64 --configuration Release -p:PublishSingleFile=true -p:SelfContained=true -p:PublishReadyToRun=false -p:PublishTrimmed=true --output ./SelfContained_SingleFile_win-x64_Trimmed
===Build 15=======================================================================
Location:
->\ConsoleApp3C\bin\Release\net8.0-windows\win-x64\
Publish mode :
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Un-bundled; 5)Untrimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesNotInSingleFile; 9)assembliesNotCompressed ; 10)NotAot
(I think above is correct interpretation. I am not sure because there are many flags/properties in
the project file, but it seems they do not have effect until "dotnet publish" is called)
Works! App started and it runs properly.
Content:
-255 files
-90 MB
-----Here is project file---------------
<!--ConsoleApp3C.csproj +++++++++++++++++++++++++++++++++++++-->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>x64</PlatformTarget>
<Platforms>AnyCPU;x64</Platforms>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>embedded</DebugType>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
<IsTrimmable>true</IsTrimmable>
<SelfContained>true</SelfContained>
<PublishReadyToRun>true</PublishReadyToRun>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary1\ClassLibraryA.csproj" />
</ItemGroup>
<Target Name="RunAfterBuild1" AfterTargets="Build">
<Exec Command="call SelfContained_SingleFile_win-x64_ReadyToRun.cmd" Condition=" '$(BuildingInsideVisualStudio)' == 'true' "/>
</Target>
<Target Name="RunAfterBuild2" AfterTargets="Build">
<Exec Command="call SelfContained_SingleFile_win-x64_Trimmed_ReadyToRun.cmd" Condition=" '$(BuildingInsideVisualStudio)' == 'true' "/>
</Target>
</Project>
===Build 16=======================================================================
Location:
->\ConsoleApp3C\SelfContained_SingleFile_win-x64_ReadyToRun\
Publish mode :
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Single-file; 5)Untrimmed; 6)ReadyToRun; 7)PdbEmbeded; 8)binariesInSingleFile; 9)assembliesCompressed ; 10)NotAot
Works! App started and it runs properly.
Content:
-1 file
-51 MB
----Use previous project file and this script-------------------
SelfContained_SingleFile_win-x64_ReadyToRun.cmd
echo .NET SDK version:
dotnet --version
dotnet publish ConsoleApp3C.csproj --nologo --no-restore --runtime win-x64 --configuration Release -p:PublishSingleFile=true -p:SelfContained=true -p:PublishTrimmed=false -p:PublishReadyToRun=true --output ./SelfContained_SingleFile_win-x64_ReadyToRun
===Build 17=======================================================================
Location:
->\ConsoleApp3C\SelfContained_SingleFile_win-x64_Trimmed_ReadyToRun\
Publish mode :
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Single-file; 5)Trimmed; 6)ReadyToRun; 7)PdbEmbeded; 8)binariesInSingleFile; 9)assembliesCompressed ; 10)NotAot
Works! App started and it runs properly.
Content:
-1 file
-12 MB
----Use previous project file and this script-------------------
SelfContained_SingleFile_win-x64_Trimmed_ReadyToRun.cmd
echo .NET SDK version:
dotnet --version
dotnet publish ConsoleApp3C.csproj --nologo --no-restore --runtime win-x64 --configuration Release -p:PublishSingleFile=true -p:SelfContained=true -p:PublishReadyToRun=true -p:PublishTrimmed=true --output ./SelfContained_SingleFile_win-x64_Trimmed_ReadyToRun
===Build 18=======================================================================
Location:
->\ConsoleApp5\bin\Release\net8.0-windows\win-x64\
Publish mode :
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Un-bundled; 5)Untrimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesNotInSingleFile; 9)assembliesNotCompressed; 10)PublishAot
Works! App started and it runs properly.
Content:
-228 file
-90 MB
-----Here is project file---------------
<!--ConsoleApp5.csproj +++++++++++++++++++++++++++++++++++++-->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PlatformTarget>x64</PlatformTarget>
<Platforms>AnyCPU;x64</Platforms>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<!--<DebugType>embedded</DebugType>
<PublishTrimmed>true</PublishTrimmed>
<IsTrimmable>true</IsTrimmable>
<SelfContained>true</SelfContained>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
<PublishSingleFile>true</PublishSingleFile>-->
<PublishAot>true</PublishAot>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary1\ClassLibraryA.csproj" />
</ItemGroup>
<Target Name="RunAfterBuild1" AfterTargets="Build">
<Exec Command="win-x64_Trimmed_AOT.cmd" Condition=" '$(BuildingInsideVisualStudio)' == 'true' "/>
</Target>
</Project>
===Build 19=======================================================================
Location:
->\ConsoleApp5\win-x64_Trimmed_AOT\
Publish mode :
1)Release; 2)self-contained; 3)Platform-specific-win-x64; 4)Un-bundled; 5)Trimmed; 6)NotR2R; 7)PdbEmbeded; 8)binariesNotInSingleFile; 9)assembliesNotCompressed; 10)PublishAot
Works! App started and it runs properly.
Content:
-3 file
-9 MB
----Use previous project file and this script-------------------
win-x64_Trimmed_AOT.cmd
echo .NET SDK version:
dotnet --version
dotnet publish ConsoleApp5.csproj --nologo --no-restore --runtime win-x64 --configuration Release -p:SelfContained=true -p:PublishTrimmed=true --output ./win-x64_Trimmed_AOT
==============================================================
3. Code on GitHub
I am putting example build projects on GitHub [99]. There are three solutions.
- BundleExample01_NET_8.0.0_SDK_8.0.100.sln (read comments; this is broken in .NET 8.0.11)
- BundleExample01_NET_8.0.11_SDK_8.0.404.sln (locked to SDK_8.0.404)
- BundleExample01_NET_9.0.0_SDK_9.0.101.sln (locked to SDK_9.0.101)
4. Conclusion
In this series of articles, we showed 15 different ways to build a .NET8/9 application, depending on the options wanted. There are probably more options or combinations of build properties/flags, but we can call this proof-of-concept testing successful and broad enough. We got most of the build/publish options working properly, according to the documentation.
I was in these articles aiming for some “intermediate level of practical skills” that a modern C#/.NET developer should have. Of course, this is a very interesting topic for every software engineer to get familiar with.
It was a bit of a surprise to discover that build settings are a bit of a “moving target”, and that build tools behavior changed between .NET 8.0.0 and .NET 8.0.11 and that I needed to change my build scripts accordingly.
One very interesting technology offered as a part of .NET8/9 environment is a “ReadyToRun” build option, which is a form of ahead-of-time (AOT) compilation. More details can be found at [7]. Looks to me like a complicated and serious topic, to really understand how it works from the inside. But I do not see the point of really studying it in detail unless you work in Microsoft in their .NET runtime/core department. An average C#/.NET engineer just needs to know how to activate properly the build options and benefits of it.
We also showed how to do a native Ahead-Of-Time compilation (AOT) deployment model. That can be attractive in some cases too.
5. References
[1] .NET application publishing overview
https://learn.microsoft.com/en-us/dotnet/core/deploying/
[2] Self-contained deployment runtime roll forward
https://learn.microsoft.com/en-us/dotnet/core/deploying/runtime-patch-selection
[3] https://www.red-gate.com/products/smartassembly/
[4] https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview?tabs=cli#api-incompatibility
[5] https://www.jetbrains.com/decompiler/
[7] https://devblogs.microsoft.com/dotnet/conversation-about-ready-to-run/
[99] https://github.com/MarkPelf/ArticlesCode , folder 86_Net8BuildModes_Part6