Mac 上的“dotnet publish”创建一个 .dll,但在 Linux 上生成一个可执行文件?

Posted

技术标签:

【中文标题】Mac 上的“dotnet publish”创建一个 .dll,但在 Linux 上生成一个可执行文件?【英文标题】:"dotnet publish" on Mac creates a .dll, but on Linux produces an executable? 【发布时间】:2021-02-17 16:56:45 【问题描述】:

当我使用我的 Mac 在控制台应用程序上运行 dotnet publish 时,结果是 bin/Debug/<framework>/publish 目录中的 .dll

当我使用 Microsoft .NET SDK Docker 容器对相同的源代码运行相同的命令时,除了.dll,结果是一个可执行的二进制文件。

为什么不一样?为什么dotnet publish 不在 macOS 上生成可执行二进制文件?

我已经使用 .NET Core 3.1 和 .NET 5.0 进行了尝试,并得到了相同的结果。这是我的 .NET 5.0 进程:

首先,我运行dotnet new console 从头开始​​生成一个新项目。我在生成的输出中没有更改任何内容。生成的.csproj 如下所示:

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

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

</Project>

从 macOS 运行 dotnet publish 会产生以下结果:

$ 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

在 Docker 容器内运行 dotnet publish 会产生以下结果:

$ 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

所以我的问题是:为什么一个输出可执行二进制文件,而另一个不输出,给定同一个项目?

【问题讨论】:

【参考方案1】:

由于 macOS 公证要求,app host executable generation is turned off by default on macOS

您可以通过将UseAppHost 属性设置为True 作为构建属性-p:UseAppHost=True 或在csproj 文件中手动覆盖此设置:

<PropertyGroup>
  <UseAppHost>True</UseAppHost>
</PropertyGroup>

【讨论】:

为了完整起见,还有第三个选项:“当您发布应用程序self-contained 时,始终会创建一个appHost。” 解释和文档链接很有意义。谢谢!

以上是关于Mac 上的“dotnet publish”创建一个 .dll,但在 Linux 上生成一个可执行文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何覆盖 dotnet publish 的目标文件夹

dotnet publish 在预发布完成之前运行

使用 dotnet publish 发布多个 web.config

“dotnet publish”命令行跳过部署到 Azure Functions

在 asp.net 核心的构建后事件中运行 dotnet publish

dotnet publish 有时会将 appsettings.Development.json 复制为 appsettings.development.json