ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Turso .NET NativeAOT 静态链接实战:将 turso_sdk_kit 原生库直接编入单文件可执行程序

Turso .NET NativeAOT 静态链接实战:将 turso_sdk_kit 原生库直接编入单文件可执行程序 Turso .NET NativeAOT 静态链接实战将 turso_sdk_kit 原生库直接编入单文件可执行程序【免费下载链接】tursoA SQL database in Rust: SQLite-compatible, now also speaking Postgres (experimental). The LLVM of databases.项目地址: https://gitcode.com/GitHub_Trending/tu/turso本指南基于 Turso 仓库中 bindings/dotnet/samples/NativeAot/README.md 展开讲解如何通过Turso.Data.NativeAot.ridRID 专用静态包把 Turso 原生同步引擎turso_sdk_kit以静态链接方式编入 NativeAOT 发布产物使最终可执行文件不再携带.dll/.so/.dylib侧车动态库。你将掌握静态包与动态包的选型逻辑、工程属性与包引用的完整配置、六个受支持 RID 的发布命令、离线嵌入式副本全链路冒烟验证以及本地未发布包的 restore 源配置方法。示例工程总览示例位于bindings/dotnet/samples/NativeAot/由三个文件组成NativeAotSample.csproj启用了PublishAot、SelfContained与TursoUseStaticNativeLibrary的发布工程Program.cs入口程序负责创建临时目录并驱动冒烟流程ReplicaPackageSmoke.cs通过Compile Include链接进工程的核心冒烟逻辑完整覆盖创建嵌入式副本→连接→写读→同步统计→检查点→释放全链路。其中Program.cs的完整逻辑如下using Turso.Samples; var directory Path.Combine(Path.GetTempPath(), $turso-nativeaot-{Guid.NewGuid():N}); Directory.CreateDirectory(directory); try { var result ReplicaPackageSmoke.Run(Path.Combine(directory, replica.db)); Console.WriteLine($Rows: {result.Rows}); Console.WriteLine($Stats revision: {result.Revision}); Console.WriteLine(Checkpoint: complete); Console.WriteLine(Disposed: complete); } finally { Directory.Delete(directory, recursive: true); }它在系统临时目录下生成一个带随机 GUID 的独立目录避免多进程/多次运行互相干扰把冒烟数据库放在该目录下运行结束后连同数据库文件一并递归删除保证测试无残留。为什么需要静态链接发布产物的两种形态Turso .NET 的托管层由Turso.Data.Common共享 ADO.NET 类型与原生互操作程序集和Turso.Data.Native各平台原生运行时资产组成应用只需引用Turso.Data.Sqlite.Provider即可见 bindings/dotnet/Readme.md。默认情况下动态原生资产以侧车文件形式随发布输出部署Windowsturso_sdk_kit.dllLinuxlibturso_sdk_kit.somacOSlibturso_sdk_kit.dylib这在常规非 AOT 应用与移动端目标是默认形态。但 NativeAOT 应用可以选择退出侧车动态库——通过引用 RID 专用的Turso.Data.NativeAot.*静态包并开启静态链接开关turso_sdk_kit的.libWindows或.aLinux/macOS归档会被直接链接进最终可执行文件。这一机制对应的 MSBuild 实现位于 Turso.Data.Common.targets_TursoDataNativeStaticEnabled Condition$(PublishAot) true and $(TursoUseStaticNativeLibrary) truetrue/_TursoDataNativeStaticEnabled _TursoDataNativeStaticSupportedRid Condition$(RuntimeIdentifier) win-x64 or $(RuntimeIdentifier) win-arm64 or $(RuntimeIdentifier) linux-x64 or $(RuntimeIdentifier) linux-arm64 or $(RuntimeIdentifier) osx-x64 or $(RuntimeIdentifier) osx-arm64true/_TursoDataNativeStaticSupportedRid即静态链接仅在同时满足PublishAottrue与TursoUseStaticNativeLibrarytrue时被激活且只有上述六个 RID 受支持。激活后该 targets 文件还会把turso_sdk_kit加入DirectPInvoke、把静态库加入NativeLibrary并在发布阶段移除NativeCopyLocalItems中所有turso_sdk_kit动态库文件见 Turso.Data.Common.targets确保输出目录中既不出现侧车动态库、也不出现重复的静态符号。静态库资产如何被打包Turso.Data.NativeAot.rid是一个纯资产包IncludeBuildOutputfalse、SuppressDependenciesWhenPackingtrue其打包逻辑在 Turso.Data.Sqlite.NativeAot.csproj 中定义PackageId为Turso.Data.NativeAot.$(NativeAotRid)即包名与 RID 一一对应NativeAotTarget将 RID 映射为 Rust 交叉编译目标如win-x64→x86_64-pc-windows-msvc、linux-arm64→aarch64-unknown-linux-gnu、osx-arm64→aarch64-apple-darwin静态归档取自rs_compiled\target\release-official\回退releaseWindows 使用turso_sdk_kit.lib其余平台使用libturso_sdk_kit.a静态库被打包进buildTransitive\native\rid\Windows 平台还会额外收集native-static-libs目录下的windows*.lib依赖库打包前通过ValidateNativeAotStaticPackage目标强制校验 RID、目标三元组、静态库及 Windows 依赖库是否齐全缺失即报错。包内的 Turso.Data.NativeAot.targets 按RuntimeIdentifier为六个 RID 分别解析静态库路径Windows 为turso_sdk_kit.libLinux/macOS 为libturso_sdk_kit.a。结合 Makefile 中的pack-nativeaot-static目标可以看出六个 RID 的静态包是逐一通过-p:NativeAotRidrid独立打包的pack-nativeaot-static: dotnet pack -c Release ./src/Turso.Data.Sqlite.NativeAot/Turso.Data.Sqlite.NativeAot.csproj -p:NativeAotRidwin-x64 dotnet pack -c Release ./src/Turso.Data.Sqlite.NativeAot/Turso.Data.Sqlite.NativeAot.csproj -p:NativeAotRidwin-arm64 # ... linux-x64 / linux-arm64 / osx-x64 / osx-arm64 同理工程配置逐项拆解 NativeAotSample.csproj示例工程文件 NativeAotSample.csproj 的核心配置如下Project SdkMicrosoft.NET.Sdk PropertyGroup OutputTypeExe/OutputType TargetFrameworknet10.0/TargetFramework ImplicitUsingsenable/ImplicitUsings Nullableenable/Nullable PublishAottrue/PublishAot SelfContainedtrue/SelfContained TursoUseStaticNativeLibrarytrue/TursoUseStaticNativeLibrary /PropertyGroup ItemGroup Compile Include..\ReplicaPackageSmoke.cs LinkReplicaPackageSmoke.cs / /ItemGroup ItemGroup Condition$(TursoUseProjectReferences) ! true PackageReference IncludeTurso.Data.Sqlite.Provider Version$(TursoPackageVersion) / PackageReference IncludeTurso.Data.NativeAot.$(RuntimeIdentifier) Version$(TursoPackageVersion) PrivateAssetsall Condition$(PublishAot) true and $(TursoUseStaticNativeLibrary) true and $(RuntimeIdentifier) ! / /ItemGroup ItemGroup Condition$(TursoUseProjectReferences) true ProjectReference Include..\..\src\Turso.Data.Sqlite\Turso.Data.Sqlite.csproj / /ItemGroup /Project各要素作用如下配置项作用与说明PublishAottrue/PublishAot启用 NativeAOT 发布是静态链接激活的前置条件之一SelfContainedtrue/SelfContained自包含发布把 .NET 运行时一并编入可执行文件TursoUseStaticNativeLibrarytrue/TursoUseStaticNativeLibraryTurso 自定义开关配合PublishAottrue才会真正激活静态链接见 Turso.Data.Common.targetsTurso.Data.Sqlite.Provider应用唯一需要引用的提供程序包版本由TursoPackageVersion属性注入Turso.Data.NativeAot.$(RuntimeIdentifier)RID 专用静态包PrivateAssetsall表示仅编译期消费、不传递给上层项目其引用条件同时要求PublishAottrue、TursoUseStaticNativeLibrarytrue且已指定RuntimeIdentifierCompile Include..\ReplicaPackageSmoke.cs /复用仓库中 ReplicaPackageSmoke.cs 的冒烟逻辑TursoUseProjectReferences可选切换开关为true时改用ProjectReference指向src\Turso.Data.Sqlite\Turso.Data.Sqlite.csproj适合本地源码联调如调试原生互操作层而非消费 NuGet 包需要强调RuntimeIdentifier是必填项。从 Turso.Data.Common.targets 可以确认未指定 RID、RID 不受支持、或缺少对应静态包引用时MSBuild 会分别抛出明确错误TursoUseStaticNativeLibrary requires a RuntimeIdentifier、does not support RuntimeIdentifier、requires a PackageReference。Windows 与 Linux 的系统库依赖差异静态链接后Turso 原生层依赖的系统库由 targets 自动补齐见 Turso.Data.Common.targetsWindowswin-x64/win-arm64注入bcrypt.lib、advapi32.lib、kernel32.lib、ntdll.lib、userenv.lib、ws2_32.lib、dbghelp.lib并追加/NODEFAULTLIB:MSVCRT链接参数Linuxlinux-x64/linux-arm64追加系统库utilmacOS 未额外注入系统库依赖系统自带 SDK 框架。发布命令六个受支持的 RID示例 README 给出的核心发布命令为dotnet publish -c Release -r win-x64六个受支持的运行时标识符Runtime Identifier为win-x64、win-arm64、linux-x64、linux-arm64、osx-x64、osx-arm64。因此同一份代码可以针对任意目标平台发布例如# Windows x64 dotnet publish -c Release -r win-x64 # Linux ARM64如树莓派、ARM 云主机 dotnet publish -c Release -r linux-arm64 # macOS Apple Silicon dotnet publish -c Release -r osx-arm64-r rid会被 MSBuild 解析为RuntimeIdentifier进而决定引用哪个Turso.Data.NativeAot.rid静态包、驱动 Turso.Data.NativeAot.targets 选择对应静态库、并在 Windows 平台补齐原生静态依赖。发布产物为单文件可执行程序目录中不再出现turso_sdk_kit侧车动态库。注意NativeAOT 发布天然带有目标平台限制——Linux 上的发布产物不能在 Windows 上运行反之亦然。交叉发布如 Windows 上构建linux-x64依赖对应平台的 Rust 静态库已就绪即rs_compiled产物或已发布的 NuGet 静态包并受目标平台工具链如 Linux 交叉链接器约束。离线嵌入式副本冒烟验证ReplicaPackageSmoke 全链路示例的目的不仅是能发布更要用离线嵌入式副本完整跑一遍同步相关导出从而验证 NativeAOT 发布正确链接了同步导出而不仅是本地数据库导出。冒烟逻辑位于 ReplicaPackageSmoke.cs其流程为构造离线同步数据库选项使用TursoSyncDatabaseOptions(path, new Uri(https://example.invalid))并设置BootstrapIfEmpty false与自定义HttpClientexample.invalid是保留的不可解析域名保证任何网络请求都会失败——这正是离线冒烟的设计点按需创建副本若目标文件不存在则调用TursoSyncDatabase.Create(options)创建嵌入式副本不会发起网络引导打开并读写本地数据TursoSyncDatabase.Open(options)后通过database.Connect()取得本地连接依次执行建表CREATE TABLE IF NOT EXISTS items、清空DELETE FROM items、写入三行INSERT INTO items VALUES (native), (sync), (turso)、查询行数SELECT COUNT(*)读取同步统计database.GetStats()获取Revision等同步元数据执行检查点database.Checkpoint()触发同步引擎的本地检查点操作返回并释放通过using依次释放连接与数据库句柄Program.cs打印 Rows、Revision、Checkpoint: complete、Disposed: complete 并清理临时目录。其中UnexpectedHttpHandler是一个关键的自检装置private sealed class UnexpectedHttpHandler : HttpMessageHandler { protected override TaskHttpResponseMessage SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) throw new InvalidOperationException( $BootstrapIfEmptyfalse must not make an HTTP request ({request.Method} {request.RequestUri}).); }一旦BootstrapIfEmptyfalse的副本尝试发起任何 HTTP 请求冒烟立即失败并抛出必须不发起 HTTP 请求的异常从而证明整个流程确实在离线状态下完成。这也印证了 bindings/dotnet/Readme.md 中TursoSyncDatabaseOptions的语义BootstrapIfEmptyfalse时不执行引导拉取本地写入通过显式PushAsync才会上传pull-only 副本不应调用 push。最终Program.cs期望输出类似Rows: 3 Stats revision: 十六进制 revision Checkpoint: complete Disposed: completeRows: 3验证写入与查询均经过静态链接的原生引擎执行Stats revision验证同步统计导出可用Checkpoint: complete与Disposed: complete验证检查点与资源释放路径无异常。使用本地未发布包Restore 源配置当静态包或整个Turso.Data.*包族尚未发布到 NuGet 时可以把本地打包产物目录作为 restore 源。示例给出的命令是dotnet publish -c Release -r win-x64 -p:RestoreAdditionalProjectSources..\..\artifacts\nuget-packages要点说明RestoreAdditionalProjectSources会在默认源之外追加一个本地目录作为 NuGet 包源..\..\artifacts\nuget-packages相对于示例工程目录bindings/dotnet/samples/NativeAot/即指向仓库根下的artifacts/nuget-packages目录在该目录中应同时存在Turso.Data.Sqlite.Provider、Turso.Data.NativeAot.rid等包的.nupkg可用 Makefile 的pack目标依次打包运行库、Sqlite 提供程序、EF Core 提供程序与六个 RID 的静态包多个源可重复追加RestoreAdditionalProjectSources或用分号分隔本地目录中的包版本必须与TursoPackageVersion指定版本一致否则 restore 会解析失败。该开关同时适用于dotnet restore与dotnet publishpublish 内部会执行 restore因此直接追加到 publish 命令即可完成端到端验证。小结与常见错误排查关键结论Turso .NET 的 NativeAOT 静态链接 PublishAottrueSelfContainedtrueTursoUseStaticNativeLibrarytrue 与RuntimeIdentifier完全一致的Turso.Data.NativeAot.rid包引用PrivateAssetsall。发布产物为单文件可执行程序turso_sdk_kit原生同步引擎被静态编入无需侧车动态库动态原生资产仍是移动端与非 AOT 应用的默认形态见 bindings/dotnet/Readme.md。常见错误根因与修复TursoUseStaticNativeLibrary requires a RuntimeIdentifier未传-r rid补充-r win-x64等受支持 RIDdoes not support RuntimeIdentifier rid该 RID 不在六个受支持列表中改用win-x64/win-arm64/linux-x64/linux-arm64/osx-x64/osx-arm64requires a PackageReference to Turso.Data.NativeAot.rid静态开关已开但漏引静态包补充对应 RID 的包引用restore 失败 / 找不到包使用未发布版本时需通过RestoreAdditionalProjectSources指向本地artifacts\nuget-packages目录且版本需与TursoPackageVersion匹配运行期出现DllNotFoundException: turso_sdk_kit说明走的是动态加载路径未开启或未生效静态链接检查PublishAot与TursoUseStaticNativeLibrary是否同时为true若需深入源码可继续阅读 Turso.Data.Common.targets静态链接激活与系统库注入、Turso.Data.Sqlite.NativeAot.csproj静态包打包以及 bindings/dotnet/Readme.md完整连接字符串与同步 API 参考。【免费下载链接】tursoA SQL database in Rust: SQLite-compatible, now also speaking Postgres (experimental). The LLVM of databases.项目地址: https://gitcode.com/GitHub_Trending/tu/turso创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表