dotnet / dotnet/runtime

NativeAOT: LinkNative target fails with MSB4086 when NativeLib=Static and LinkerFlavor=lld

Open
#126,978 2 comments 0 reactions 0 assignees View on GitHub
area-NativeAOT-coreclr
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.