Instead of publishing your dotnet application for each platform separately, there is a way to publish your app once as platform agnostic and run it on every platform easily.
We all know, dotnet applications can be run on any platform. Be it a windows machine, macOS (both x64 and arm64 architectures) and linux, dotnet can run our application. Although I will explain how to publish an executable of your application for any platform, there is a way to publish your app platform agnostic. A platform agnostic is when you publish your application once and you can run it on every platform. This is similar to the same approach npm has been doing since the beginning.
How to publish a dotnet application for different platforms?
dotnet cli has a nice parameter for that:
dotnet publish -r <runtime-ID>
runtime-ID tells dotnet which platform this application is going to run on. Common IDs are win-x64 , osx-x64 , osx-arm64 and linux-x64. To see the full list of all runtime IDs you can publish to, check here.
A few examples I usually use, are:
dotnet publish -r win-x64 -p:Configuration=Release -p:DebugType=None -p:DebugSymbols=false -p:Version=1.0.1
dotnet publish -r osx-x64 -p:Configuration=Release -p:DebugType=None -p:DebugSymbols=false -p:Version=1.1.25
How to publish platform-agnostic?
That’s a good question. There is a simple way to do that, but there is an issue with that. So, you can publish the app in platform agnostic way, by not mentioning -r option in dotnet publish. Here is an example:
dotnet publish -p:Configuration=Release -p:DebugType=None -p:DebugSymbols=false -p:Version=1.0.1
When you don’t mention a specific runtime platform, dotnet publish generates an executable for the current platform you are on as well as the dll file for the app. Even if it is a console application, it still generates a dll for it. The executable file is platform-dependant but the dll file is not. But as you know, you cannot run a dll file directly by clicking on it. So how do end users get to run the application by using its dll file? here is how:
dotnet <dll filename>
This is a very similar pattern to how npm applications and packages are run via npm run <package or filename>
How and What to Release to end users?
What I like to do is that I publish my app in runtime-agnostic way, then I remove any executable it might have generated and keep only dll files. Then I can easily zip this folder and ship it to end users or other developers. I tend to put a small README.md file to explain how they should run it.
What would make it better?
As you’ve seen, when we publish our .NET application in runtime agnostic manner, it generates a dll file. In order to run it we have to give the whole filename and its extensions to the dotnet CLI. This is a little bit bothersome, as a .dll file is not usually an executable file and this can confuse users or developers. I wish there was a way to remove this extension completely and just use the filename.
I haven’t been able to find any solution for that, if you know, please share it with us in the comment section.