3

When I run dotnet publish on a Console app using my Mac, the result is a .dll in the bin/Debug/<framework>/publish directory.

When I run the same command on the same source code using the Microsoft .NET SDK Docker container, the result is an executable binary, in addition to the .dll.

Why the difference? Why doesn't dotnet publish produce an executable binary on macOS?

I have tried this using both .NET Core 3.1 and .NET 5.0 and got the same results. Here is my .NET 5.0 process:

First, I ran dotnet new console to generate a new project from scratch. I changed nothing in the generated output. The generated .csproj looks like this:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <RootNamespace>MyApp</RootNamespace>
  </PropertyGroup>

</Project>

Running dotnet publish from macOS yields the following:

$ dotnet publish
Microsoft (R) Build Engine version 16.8.3+39993bd9d for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  Restored /src/my-app.csproj (in 68 ms).
  my-app -> /src/bin/Debug/net5.0/my-app.dll
  my-app -> /src/bin/Debug/net5.0/publish/

$ ls -al bin/Debug/net5.0/publish/
total 56
drwxr-xr-x  6 user  staff   192B Feb 17 09:49 ./
drwxr-xr-x  9 user  staff   288B Feb 17 09:49 ../
-rw-r--r--  1 user  staff   409B Feb 17 09:49 my-app.deps.json
-rw-r--r--  1 user  staff   4.5K Feb 17 09:49 my-app.dll
-rw-r--r--  1 user  staff   9.2K Feb 17 09:49 my-app.pdb
-rw-r--r--  1 user  staff   139B Feb 17 09:49 my-app.runtimeconfig.json

Running dotnet publish from inside a Docker container yields the following:

$ docker run -it --mount src="$(pwd)",target=/src,type=bind mcr.microsoft.com/dotnet/sdk:5.0

root@d143004612a8:/src# dotnet publish
Microsoft (R) Build Engine version 16.8.3+39993bd9d for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  Restored /src/my-app.csproj (in 99 ms).
  my-app -> /src/bin/Debug/net5.0/my-app.dll
  my-app -> /src/bin/Debug/net5.0/publish/

root@d143004612a8:/src# ls -al bin/Debug/net5.0/publish/
total 164
drwxr-xr-x  7 root root    224 Feb 17 16:53 .
drwxr-xr-x 10 root root    320 Feb 17 16:53 ..
-rwxr-xr-x  1 root root 138736 Feb 17 16:53 my-app
-rw-r--r--  1 root root    409 Feb 17 16:53 my-app.deps.json
-rw-r--r--  1 root root   4608 Feb 17 16:53 my-app.dll
-rw-r--r--  1 root root   9304 Feb 17 16:53 my-app.pdb
-rw-r--r--  1 root root    139 Feb 17 16:53 my-app.runtimeconfig.json

So my question is: Why does one output an executable binary, and the other does not, given the same project?

Jarrod Carlson
  • 1,967
  • 4
  • 16
  • 20

1 Answers1

5

Due to macOS notarization requirements, app host executable generation is turned off by default on macOS

You can manually override this by setting the UseAppHost property to True either as a build property -p:UseAppHost=True or in the csproj file:

<PropertyGroup>
  <UseAppHost>True</UseAppHost>
</PropertyGroup>
Martin Ullrich
  • 94,744
  • 25
  • 252
  • 217