Summary
build/LightningDB.targets (target LightningDBIncludeNativeDll) selects which native liblmdb/lmdb.dll binary to copy into the output directory based on $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) — i.e. the architecture of the machine running the build — rather than the target RuntimeIdentifier (RID) being published for.
This breaks cross-architecture publishing, e.g.:
dotnet publish -r linux-arm64
run on an x64 build host. The target's conditions only check IsOsPlatform(Linux) + OSArchitecture == X64, so it copies the x64
native binary regardless of the -r linux-arm64 RID passed to publish. That wrong-architecture binary can then win NuGet's publish asset conflict resolution over the correct RID-specific binary (which the SDK's own runtimes/{rid}/native + .deps.json runtimeTargets mechanism already resolves correctly), resulting in an app that ships with the wrong-arch native library and fails at runtime on the target platform.
Repro
- On a linux-x64 (or any) host, add
PackageReference Include="LightningDB" to a project (no RuntimeIdentifier set on the project itself — e.g. a library referenced via ProjectReference).
- Publish a consuming app with a different target RID:
dotnet publish -r linux-arm64
- Inspect the publish output — the
liblmdb.so present is built for the host architecture (x64), not linux-arm64.
Expected
The native binary copied (or excluded, deferring to normal SDK runtime asset resolution) should be based on the target RuntimeIdentifier of the publish/build, not the host machine's architecture.
Suggested fix
Two options that would both fix this:
- Change the
Conditions in LightningDBIncludeNativeDll to key off $(RuntimeIdentifier) (when set) instead of RuntimeInformation.OSArchitecture, falling back to host-arch detection only when RuntimeIdentifier is empty (e.g. plain dotnet build with no RID).
- Alternatively, drop this custom copy target entirely and rely on the standard NuGet
runtimes/{rid}/native convention, which the .NET SDK already resolves correctly per target RID during both build and publish (including RID-less ProjectReference builds, via .deps.json runtimeTargets entries). This target appears to predate reliable SDK support for that convention, but it's fully handled by the SDK today.
Workaround
We currently work around this downstream with:
<ItemGroup>
<PackageReference Update="LightningDB" ExcludeAssets="build" />
</ItemGroup>
which disables this target and lets the SDK's built-in RID-based runtime asset resolution take over. This resolves cross-arch publishing for us, but ideally shouldn't be necessary.
Environment
- LightningDB NuGet package version: 0.21.0
- .NET SDK: (fill in your SDK version, e.g. 8.0.x / 6.0.x)
- Host OS/Arch: linux-x64 (also reproducible cross-compiling from Windows)
- Target RID: linux-arm64
Summary
build/LightningDB.targets(targetLightningDBIncludeNativeDll) selects which nativeliblmdb/lmdb.dllbinary to copy into the output directory based on$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)— i.e. the architecture of the machine running the build — rather than the targetRuntimeIdentifier(RID) being published for.This breaks cross-architecture publishing, e.g.:
run on an x64 build host. The target's conditions only check
IsOsPlatform(Linux)+OSArchitecture == X64, so it copies the x64native binary regardless of the
-r linux-arm64RID passed topublish. That wrong-architecture binary can then win NuGet's publish asset conflict resolution over the correct RID-specific binary (which the SDK's ownruntimes/{rid}/native+.deps.jsonruntimeTargetsmechanism already resolves correctly), resulting in an app that ships with the wrong-arch native library and fails at runtime on the target platform.Repro
PackageReference Include="LightningDB"to a project (noRuntimeIdentifierset on the project itself — e.g. a library referenced viaProjectReference).liblmdb.sopresent is built for the host architecture (x64), notlinux-arm64.Expected
The native binary copied (or excluded, deferring to normal SDK runtime asset resolution) should be based on the target
RuntimeIdentifierof the publish/build, not the host machine's architecture.Suggested fix
Two options that would both fix this:
Conditions inLightningDBIncludeNativeDllto key off$(RuntimeIdentifier)(when set) instead ofRuntimeInformation.OSArchitecture, falling back to host-arch detection only whenRuntimeIdentifieris empty (e.g. plaindotnet buildwith no RID).runtimes/{rid}/nativeconvention, which the .NET SDK already resolves correctly per target RID during both build and publish (including RID-less ProjectReference builds, via.deps.jsonruntimeTargetsentries). This target appears to predate reliable SDK support for that convention, but it's fully handled by the SDK today.Workaround
We currently work around this downstream with:
which disables this target and lets the SDK's built-in RID-based runtime asset resolution take over. This resolves cross-arch publishing for us, but ideally shouldn't be necessary.
Environment