构建独立的 Mono 应用程序

问题描述 投票:0回答:1

我正在管理的 Linux 工具链包含旧版 .Net 应用程序。这在 Ubuntu 上很好,因为可以使用官方的 Mono 运行时环境来运行 .Net 应用程序。但我想在没有官方 Mono 支持的其他 Linux 发行版(例如 RHEL/Rocky Linux)上运行我的工具链。我宁愿保持 runtime 依赖项列表尽可能小,即我既不想依赖第 3 方 Mono 构建,也不想依赖 Docker。

理论上,我的场景得到了很好的支持:Mono 的

mkbundle
能够将任何 .Net 应用程序打包到特定于平台的二进制文件中,该二进制文件不依赖于已安装的 Mono 运行时。但是,它确实引入了对
libmono-native.so
的依赖(这是动态依赖,因此它不会出现在
ldd
的输出中),而我无法实现这一点。

最小示例:

测试.cs

using System;

public class HelloWorld
{
    public static void Main(string[] args)
    {
        Console.WriteLine ("Hello Mono World");
    }
}

我通过

csc hello.cs
将其编译为 .Net 可执行文件到
test.exe
。这个可执行文件可以在 Mono 上正常运行,但是 - 显然 - 没有 Mono 运行时就不行。

方法一:交叉编译

mkbundle --cross mono-6.6.0-ubuntu-18.04-x64 -o test test.exe

这会创建一个本机

test
ELF 二进制文件(我几乎只是选择了任意 x64 交叉编译目标,因为 RHEL/Rocky Linux 和任何较新的 Ubuntu 目标都不可用)。当安装了 Mono 运行时时,此
test
在 Ubuntu 上运行(我测试了“Jammy”22.04),但在没有 Mono 运行时的系统上失败并显示
System.DllNotFoundException: /libmono-native.so

因此,我也尝试通过

mkbundle --cross mono-6.6.0-ubuntu-18.04-x64 --library /usr/lib/libmono-native.so -o test test.exe
嵌入该库,但这在所有经过测试的系统(Ubuntu 和 Rocky Linux)上都失败了

Error loading shared library: /tmp/mono-bundle-SSDDWc/libmono-native.so /tmp/mono-bundle-SSDDWc/libmono-native.so: cannot open shared object file: No such file or directory

方法2:通用静态编译

mkbundle --static -L /usr/lib/mono/4.8-api -o test test.exe

这同样会创建一个

test
ELF 二进制文件,但执行它会崩溃,并且 Ubuntu 主机系统上已经存在 SEGFAULT。
gdb
输出:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x000055555556c314 in mono_mkbundle_init () at temp.c:147
#2  0x000055555556c652 in main (argc=1, argv=0x7fffffffddd8) at temp.c:224

我做错了什么,还是我的方法根本不可能?

.net ubuntu mono rhel mkbundle
1个回答
0
投票

不要使用 Mono,使用 .NET Core

.NET 框架有两代完全独立的实现:

  1. Microsoft 用于 Windows 的旧版“.NET Framework”,其功能由开源 Mono 项目独立重新实现,以支持非 Windows 平台。
  2. 微软新推出的“.NET Core”,开源且直接支持多平台(例如Windows、Linux、MacOS)。

Mono 目前几乎没有获得开发支持,并且在 Mono 中构建本机应用程序可能会出现问题并且无法修复。然而,.Net Core 本质上取代了它,并且可以在许多 Linux 发行版的官方软件包存储库中使用(例如 Ubuntu 的

dotnet-sdk-7.0
)。

使用.NET Core,可以构建主机平台的本机应用程序 通过从应用程序的源代码根文件夹(包含 Visual Studio 解决方案

1
的文件夹)执行 dotnet publish --configuration=release --self-contained。可以通过附加
-r <platform>
参数来生成不同平台的二进制文件。通过添加

,本机应用程序可以打包为单个可执行文件(而不是一组库和可执行文件)
<PublishSingleFile>true</PublishSingleFile>

配置行添加到相应的

.csproj
/
.vbproj
项目文件中。或者,还可以通过添加

来修剪此单个可执行文件以减小其大小
<PublishTrimmed>true</PublishTrimmed>

配置行 - 但这仅适用于 .NET 语言功能的子集。


1如果解决方案仍采用旧版 .NET Framework 的格式,则必须首先迁移它,例如使用微软的“升级助手”工具。
© www.soinside.com 2019 - 2024. All rights reserved.