NativeAOT: LinkNative target fails with MSB4086 when NativeLib=Static and LinkerFlavor=lld
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
*This content was created with assistance from AI.*
## Description
When `NativeLib=Static` is set (to have ILC produce a `.a` archive instead of a shared library), the `LinkNative` target in `Microsoft.NETCore.Native.targets` fails with:
```
Microsoft.NETCore.Native.targets(351,96): error MSB4086: A numeric comparison was attempted on "$(_LinkerVersion)" that evaluates to "" instead of a number, in condition '$(LinkerFlavor)' == 'lld' and '$(_LinkerVersion)' > '12'"
```
## Root Cause
In `Microsoft.NETCore.Native.Unix.targets`, the `_LinkerVersion` detection is correctly skipped when `NativeLib=Static`:
```xml
```
However, in `Microsoft.NETCore.Native.targets`, the `CustomLinkerArg` item group inside `LinkNative` evaluates `_LinkerVersion` without the same `NativeLib` guard:
```xml
```
The same issue exists on line ~368:
```xml
```
Since `_LinkerVersion` is empty (detection was skipped), the numeric comparison `'' > '12'` causes MSBuild error MSB4086.
## When This Triggers
This triggers when:
1. `NativeLib=Static` (so version detection is skipped), AND
2. `LinkerFlavor=lld` (set automatically for `android`, `linux-bionic`, and `freebsd` targets)
This combination occurs when Android or other platforms set `NativeLib=Static` to take ownership of the final native link step (producing their own shared library from the ILC `.o` output), following the same pattern used by [xamarin-macios](https://github.com/dotnet/macios).
## Suggested Fix
Add `'$(NativeLib)' != 'Static'` to the conditions on lines ~351 and ~368, consistent with the guard on the version detection itself:
```xml
```
Alternatively, the version detection could default `_LinkerVersion` to `0` when skipped, so the comparison always succeeds safely.
## Workaround
Clear `LinkerFlavor` before `LinkNative` runs:
```xml
```
This must be done inside a target (not a static PropertyGroup) because the ILC Unix targets set `LinkerFlavor` in a static PropertyGroup that evaluates after the consumer's import.
Contributor guide
Assessment
This issue has not been assessed yet.