Skip to content

Instantly share code, notes, and snippets.

@DasSkelett
Last active July 1, 2021 14:50
Show Gist options
  • Save DasSkelett/5d87afc99ed8442603fd5e2856f3f489 to your computer and use it in GitHub Desktop.
Save DasSkelett/5d87afc99ed8442603fd5e2856f3f489 to your computer and use it in GitHub Desktop.
Building & publishing .NET 5 applications for Linux

Building & publishing .NET 5 applications for Linux

In contrast to Mono with .NET Framework .exes, you can't run .NET 5 .exe files on Linux even with the runtime installed.

So while for the .NET Framework you only needed to compile a single .exe which could run on all platforms thanks to Mono, with .NET 5 you need to build one executable/binary for each platform...

On the plus side, this binary is basically just a small starter binary (if you don't compile in single file mode), which then loads all the real application and all its endencies as DLLs, which should be the same for all platforms. This means that it should be possible to combine the outputs of these builds into a single folder, containing all starter binaries for all platforms. Didn't try this out yet, though. This did not work :(

Explanations:

  • self-contained: The output comes with all .NET system DLLs, the user doesn't need .NET Runtime installed on their system
  • single file: The output is a single file instead of a directory full of separate (DLL) files
  • trimmed: The output is trimmed, that means unused code gets removed from the DLLs. Only applicable to self-contained builds.

These two options can be toggled on and off independently – you can publish a runtime-dependent single binary, you can also publish a runtime-independent file bundle, or the other two combinations.

Additionally self-contained outputs can be trimmed, which reduces the total size. Only applicable to self-contained builds.

The defaults when building for Linux is --self-contained true -p:PublishSingleFile=false -p:PublishTrimmed=false.

More information:

Build commands

Runtime-dependent + multiple files

dotnet publish -c release -r linux-x64 --self-contained false

Lowest size, users need the .NET 5 runtime installed on their system.

Self-contained + multiple files

dotnet publish -c release -r linux-x64 --self-contained true

Highest size, users don't need the .NET 5 runtime installed on their system.

Runtime-dependent + single file

dotnet publish -c release -r linux-x64 --self-contained false -p:PublishSingleFile=true

Easy to install for users, still need the .NET 5 runtime installed on their system.

Self-contained + single file

dotnet publish -c release -r linux-x64 --self-contained true -p:PublishSingleFile=true

Easiest to install for users, just a single file in total, no runtime needed.

Self-contained + multiple files + trimmed

dotnet publish -c release -r linux-x64 --self-contained yes -p:PublishSingleFile=false -p:PublishTrimmed=true

Slightly smaller binaries thanks to link-time trimming.

Self-contained + single file + trimmed

dotnet publish -c release -r linux-x64 --self-contained yes -p:PublishSingleFile=true -p:PublishTrimmed=true

Slightly smaller binaries thanks to link-time trimming.

Output

The relevant output will always be in the ./bin/release/net5/linux-x64/publish/ folder. It's either a single big executable file (together with a few *.pdb files for debugging, they don't need to be distributed), or a whole bunch of files with a smaller executable file (starter).

Launch

To start the program, run the file named after the project. In the case of the LunaMultiplayer server, it's Server (and Server.exe on Windows).

Size comparison

Using https://github.com/LunaMultiplayer/LunaMultiplayer/tree/master/Server

This compares the size of the final folders, excluding *.pdb files. Sizes in MegaBytes = 1 000 000 Bytes.

dotnet: 5.0.301
LunaMultiplayer: 0.28.0 / cb8cabd
Size Runtime-dependent Self-contained SC + Trimmed
Multi-file 4,1M 76M 46M
Single file 4,0M 64M 34M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment