什么是 .Net 的 AOT
简言之,就是类似 Golang 将代码编译成一个独立的二进制文件,直接扔到服务器上就能运行,也不需要任何的 runtime 依赖。
Publishing your app as Native AOT produces an app that's self-contained and that has been ahead-of-time (AOT) compiled to native code. Native AOT apps have faster startup time and smaller memory footprints. These apps can run on machines that don't have the .NET runtime installed.
新建一个 AOT 的项目
> dotnet.exe new console -o HelloWorldAot --aot
运行
> dotnet.exe run
Hello, World!
编译成 AOT 目标文件
> dotnet.exe publish
Determining projects to restore...
Restored D:\work\test\HelloWorldAot\HelloWorldAot.csproj (in 32.13 sec).
HelloWorldAot -> D:\work\test\HelloWorldAot\bin\Release\net8.0\win-x64\HelloWorldAot.dll
Generating native code
HelloWorldAot -> D:\work\test\HelloWorldAot\bin\Release\net8.0\win-x64\publish\
查看生成的 publish 目录:
zhongwei@DESKTOP-FST75GU /m/d/w/t/HelloWorldAot> ls -lah bin/Release/net8.0/win-x64/publish/
total 8.0M
drwxrwxrwx 1 zhongwei zhongwei 4.0K Jul 9 15:20 ./
drwxrwxrwx 1 zhongwei zhongwei 4.0K Jul 9 15:20 ../
-rwxrwxrwx 1 zhongwei zhongwei 1.2M Jul 9 15:20 HelloWorldAot.exe*
-rwxrwxrwx 1 zhongwei zhongwei 6.8M Jul 9 15:20 HelloWorldAot.pdb*
把 HelloWorldAot.exe 复制出来即可。扔到其他目录,是可以直接执行的。
xxx.csproj 配置
下面的配置是默认生成的。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
</Project>
会看到 PublishAot 被设置为了 True.
Cross-compilation 交叉编译
.Net 8 并不能像 golang 一样实现完美的交叉编译。所以,如果要开发在 Ubuntu Server 上运行的程序,还是需要在 WSL Ubuntu 中编译。这个让人打退堂鼓。 感觉直接 docker 解决。
Since there's no standardized way to obtain native macOS SDK for use on Windows/Linux, or Windows SDK for use on Linux/macOS, or a Linux SDK for use on Windows/macOS, Native AOT does not support cross-OS compilation. Cross-OS compilation with Native AOT requires some form of emulation, like a virtual machine or Windows WSL.
Ubuntu Server 测试
我在一个 Ubuntu Server 22.04 的机器上,又新建一个 AOT 的测试项目:
> dotnet new console -o TestAOT --aot
> dotnet publish
> ls -lah bin/Release/net8.0/linux-x64/publish
drwxr-xr-x 2 root root 4.0K Jul 9 16:11 .
drwxr-xr-x 4 root root 12K Jul 9 16:11 ..
-rwxr-xr-x 1 root root 1.4M Jul 9 16:11 TestAOT
-rwxr-xr-x 1 root root 2.4M Jul 9 16:11 TestAOT.dbg
在 Ubuntu 22.04 上编译,然后 scp 到 Ubuntu 20.04 上执行。报错!
> ./TestAOT
./TestAOT: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by ./TestAOT)
./TestAOT: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./TestAOT)
而在相同版本上的 Ubuntu Server 上,就能正常执行。。。
Ubuntu Server 版本号查看方法:
> cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
> cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
参考
- https://github.com/dotnet/samples/blob/main/core/nativeaot/HelloWorld/README.md
- https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/cross-compile
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式