筆記 - 在 Linux 平台使用 .NET Native AOT
0 |
接續前一篇用 .NET Native AOT 編譯程式庫給 Python 呼叫的實驗。
下一步我打算搬到 Linux 執行,過程有些小波折,編譯原生二進位檔案有優點,但領教過比較複雜繁瑣的編譯程序,倒也襯托出 .NET Runtime 的好處。
參考官方文件 Native AOT deployment,先簡單整理重點。
- .NET 8 對 Native AOT 的支援比較完整,反正 Native AOT 不涉及目標主機安裝的 .NET Runtime 版本,建議用 .NET 8。
- 在 .csproj 加入
<PublishAot>true</PublishAot>
後dotnet publish
將改編譯成 Native AOT,並會啟動編輯及編譯階段動態程式碼使用分析 (Dynamic Code-Usage Analysis)。 - 原生二進位檔對平台版本的依賴很深,如果你用 Ubuntu 20.04 編譯的 Native AOT 檔案,只能在 Ubuntu 20.04 以後的作業系統執行,無法在 Ubuntu 18.04 用。
- .csproj 加入
<IsAotCompatible>true</IsAotCompatible>
可標示程式庫相容 Native AOT (等同啟用以下設定:IsTrimmable、EnableTrimAnalyzer、EnableSingleFileAnalyzer、EnableAotAnalyzer) - Native AOT 編譯後會產生偵錯檔 .dbg(Linux)/.pdb(Windows)/.dSYM(macOS) 可協助 Crash Dump 偵錯,在非 Windows 平台,設定
<StripSymbols>false</StripSymbols>
可將其併入原生二進位檔。 - .NET Native AOT 支援以下平台
- 作業系統必須安裝 C++ 編譯工具才能編譯 Native AOT,Winows 要安裝 VS2022 Desktop Development with C++,Ubuntu 要
sudo apt-get install clang zlib1g-dev
、macOS 要安裝 Command Line Tools for XCode。參考
要編譯 Linux 用的 Native AOT 原生程式庫需要用 Linux 平台上編譯(編譯平台與目標平台需相同),嘗試在 Windows 平台執行 dotnet publish -r linux-x64
會得到 error : Cross-OS native compilation is not supported.
我是將專案原始檔複製到 Debian,一開始忘了裝安裝 gcc 或 clang,dotnet publish /p:NativeLib=Shared --use-current-runtime
會發生 collect2 : error : ld returned 1 exit status
錯誤 參考),安裝 clang、zlib1g-dev 後成功編譯出 .so 檔:
在 Linux 平台跑 test.py,有三處要修改:1) Windows 載入 .dll,Linux 要載入 .so 2) .NET 端用 Marshal.StringToHGlobalAnsi(result) 傳回字串,在 Windows 是 BIG5 編碼,在 Linux 則是 UTF-8 3) Python 呼叫 .NET Marshal.FreeHGlobal() 釋放 Unmanaged 記憶體配置的做法在 Linux 會出錯,出現 munmap_chunk(): invalid pointer in linux
(這部分超出我的知識範圍,期待具相關經驗的前輩指點解惑)
以上就是本次的 Native AOT 登陸 Linux 經驗分享。
(串接 Managed 及 Unmanaged 世界這塊水頗深,我目前還在新手村打史萊姆... )
Tips of how to publish Native AOT library on Linux.
Comments
Be the first to post a comment