I use dotnet
on macOS and want to build an application for Linux. To achive this, I use the following commands:
dotnet --version # 3.0.101 dotnet new console -n HelloWorld dotnet publish --self-contained --runtime linux-x64 -o ./linux-publish
According to this article, the dotnet
command should support a command-line flag to pack the application into a single executable:
dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true
My question is two-fold:
- Why is there no
PublishSingleFile
option fordotnet
on macOS? - Why does
dotnet
both create a HelloWorld executable and a HelloWorld.dll?
Advertisement
Answer
Re: Why is there no
PublishSingleFile
option for dotnet on macOS?
There is, at least in version 3.1.100
, so maybe try updating.
Why does
dotnet
both create a HelloWorld executable and a HelloWorld.dll?
The important concepts here are that of a portable app (which is what you get by default) and self-contained apps (in which a single executable file is produced).
A portable app is an application that runs independently of the platform and requires that the .NET
shared framework is installed. When published, the shared framework is not copied to the publish
folder — including the native host. In order to run it, dotnet <path_to_your_dll>
would be invoked. dotnet in this case is the native piece, the host (which isn’t what you are wanting here).
For self-contained apps, an RID
needs to be specified (which you have done correctly in your example). I’m thinking that the main reason you might be having an issue with things not working correctly is that you are running an older version of the SDK
, so I would recommend updating to the current release version.
When you invoke the dotnet publish
command it should end up being similar to the following:
$ dotnet publish -r osx.10.13-x64 /p:PublishSingleFile=true Microsoft (R) Build Engine version 16.4.0+e901037fe for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 39.77 ms for /usr/local/share/dotnet/myApp/myApp.csproj. myApp -> /usr/local/share/dotnet/myApp/bin/Debug/netcoreapp3.1/osx.10.13-x64/myApp.dll myApp -> /usr/local/share/dotnet/myApp/bin/Debug/netcoreapp3.1/osx.10.13-x64/publish/
(I use osx.10.13-x64
because that’s what shows with the output of this command):
$ dotnet --info .NET Core SDK (reflecting any global.json): Version: 3.1.100 Commit: cd82f021f4 Runtime Environment: OS Name: Mac OS X OS Version: 10.13 OS Platform: Darwin RID: osx.10.13-x64 Base Path: /usr/local/share/dotnet/sdk/3.1.100/ Host (useful for support): Version: 3.1.0 Commit: 65f04fb6db .NET Core SDKs installed: 3.1.100 [/usr/local/share/dotnet/sdk] .NET Core runtimes installed: Microsoft.AspNetCore.App 3.1.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 3.1.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App] To install additional .NET Core runtimes or SDKs: https://aka.ms/dotnet-download
In file myApp.csproj
include the RID
(s) aka RunTimeIndentifers
you are building against:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.1</TargetFramework> <RuntimeIdentifiers>osx.10.13-x64</RuntimeIdentifiers> </PropertyGroup> </Project>
Now back to the matter at hand regarding the two directories resulting from the publish
command. The myApp.dll
directory is essentially all of the parts that make up your application.
It can be executed by the following:
$ cd /usr/local/share/dotnet/myApp/bin/Debug/netcoreapp3.1/osx.10.13-x64 $ ls (tons of files which comprise the app) $ dotnet myApp.dll Hello World!
However, you want the single file of all that junk, the standalone executable file located in publish
:
$ cd /usr/local/share/dotnet/myApp/bin/Debug/netcoreapp3.1/osx.10.13-x64/publish/ $ ls myApp myApp.pdb $ ./myApp Hello World!
There’s a lengthy discussion linked below if you want further insight:
↳ https://github.com/dotnet/cli/issues/6237
This official tutorial might also be helpful:
↳ https://dotnet.microsoft.com/learn/dotnet/hello-world-tutorial/intro?sdk-installed=true