Skip to content

NativeAOT: Use lib prefix by default on Unix for native library outputs#124611

Open
Copilot wants to merge 8 commits intomainfrom
copilot/use-lib-prefix-default-unix
Open

NativeAOT: Use lib prefix by default on Unix for native library outputs#124611
Copilot wants to merge 8 commits intomainfrom
copilot/use-lib-prefix-default-unix

Conversation

Copy link
Contributor

Copilot AI commented Feb 19, 2026

Description

On Unix, the lib prefix (e.g., libfoo.so, libfoo.dylib, libfoo.a) is the standard convention for shared and static libraries. Previously, NativeAOT only applied this prefix when the internal _UseNativeLibPrefix property was explicitly set — Android tests required it, but other Unix targets didn't get it by default.

This change makes the lib prefix the default for non-executable NativeAOT outputs on all non-Windows targets, and introduces a public UseNativeLibPrefix property for opting out.

Changes

  • Microsoft.NETCore.Native.targets: Replace the private _UseNativeLibPrefix check with a new public UseNativeLibPrefix property. The condition uses != 'false' so the prefix is on by default for non-Windows non-executable outputs without requiring an explicit opt-in.
  • Microsoft.NETCore.Native.Publish.targets: Fix ComputeLinkedFilesToPublish to include $(NativeBinaryPrefix) in all symbol file paths — source path, target path, recursive glob, and both RelativePath metadata values (flat .dbg and dSYM bundle cases).
  • Microsoft.NETCore.Native.Unix.targets: Include $(NativeBinaryPrefix) in the SharedLibraryInstallName (@rpath/...) for Apple platforms.
  • native-library.targets: Include $(NativeBinaryPrefix) in strip source/destination paths and the StripLibraryLikeCoreCLRBuild inputs/outputs.
  • eng/testing/tests.android.targets: Remove the now-redundant <_UseNativeLibPrefix>true</_UseNativeLibPrefix> — the default behavior covers this.

Opt-out

Projects that need to suppress the prefix can set:

<UseNativeLibPrefix>false</UseNativeLibPrefix>

Changes to public API surface

None — MSBuild property changes only. UseNativeLibPrefix is the new public opt-out property.

Testing

Existing Android NativeAOT test infra validates the lib-prefixed output; no behavior change there. The main impact is that Unix NativeAOT library outputs now follow the platform convention by default, including correct propagation of the prefix into symbol file paths during publish.

Original prompt

This section details on the original issue you should resolve

<issue_title>Use correct native lib prefix in native AOT for android</issue_title>
<issue_description>#118299 introduced _UseNativeLibPrefix as an underscored property. Looks like android may need to set this: dotnet/android#10822.

At the time we didn't want to change the default to avoid breaking existing scenarios, but I wonder - could we try using the lib prefix by default on unix and take this breaking change? AFAIK this is a very common convention on unix so it would probably be a good default.

We could also introduce a public property to allow opting out for scenarios that don't want this.

@jtschuster @MichalStrehovsky </issue_description>

<agent_instructions>Use the native 'lib' prefix by default on unix.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

…ibPrefix opt-out

Co-authored-by: sbomer <787361+sbomer@users.noreply.github.com>
Copilot AI changed the title [WIP] Use correct native lib prefix in native AOT for Android NativeAOT: Use lib prefix by default on Unix for native library outputs Feb 19, 2026
Copilot AI requested a review from sbomer February 19, 2026 18:47
sbomer added 3 commits March 6, 2026 12:36
Remove $(LibPrefix) from mscordaccore_universal AssemblyName and let
NativeBinaryPrefix handle the prefix consistently, avoiding the double-prefix
(liblibmscordaccore_universal.so) that broke bootstrapped CI builds.

Add $(NativeBinaryPrefix) to all path constructions in native-library.targets,
Microsoft.NETCore.Native.Publish.targets, and Microsoft.NETCore.Native.Unix.targets
so strip/copy/install steps use the correct prefixed filename.

Opt out of UseNativeLibPrefix in SharedLibrary and CustomMainWithStubExe tests
whose C++ drivers derive the library path from argv[0] via dlopen.
# Conflicts:
#	src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets
@jkotas jkotas added the breaking-change Issue or PR that represents a breaking API or functional change over a previous release. label Mar 6, 2026
@dotnet-policy-service dotnet-policy-service bot added the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Mar 6, 2026
@dotnet-policy-service
Copy link
Contributor

Added needs-breaking-change-doc-created label because this PR has the breaking-change label.

When you commit this breaking change:

  1. Create and link to this PR and the issue a matching issue in the dotnet/docs repo using the breaking change documentation template, then remove this needs-breaking-change-doc-created label.
  2. Ask a committer to mail the .NET Breaking Change Notification DL.

Tagging @dotnet/compat for awareness of the breaking change.

Remove the explicit UseNativeLibPrefix default property and instead check
!= 'false' on the NativeBinaryPrefix condition. The _targetOS != 'win'
guard on NativeBinaryPrefix already prevents the prefix on Windows,
making the separate default-setting line redundant.
@sbomer
Copy link
Member

sbomer commented Mar 12, 2026

/azp run runtime-extra-platforms

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

This was referenced Mar 12, 2026
@sbomer sbomer marked this pull request as ready for review March 12, 2026 20:41
Copilot AI review requested due to automatic review settings March 12, 2026 20:41
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes the lib prefix the default for non-executable NativeAOT library outputs on Unix platforms, aligning with standard Unix naming conventions (libfoo.so, libfoo.dylib, libfoo.a). Previously this required explicitly setting the internal _UseNativeLibPrefix property.

Changes:

  • Default NativeBinaryPrefix to lib on non-Windows for non-executable outputs, with a public UseNativeLibPrefix property to opt out.
  • Update all file path references in native-library.targets and Microsoft.NETCore.Native.Unix.targets to include $(NativeBinaryPrefix).
  • Opt out existing tests and projects (SharedLibrary, CustomMainWithStubExe, mscordaccore_universal) that expect no prefix, and remove the now-redundant Android-specific _UseNativeLibPrefix setting.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
Microsoft.NETCore.Native.targets Change condition from _UseNativeLibPrefix == 'true' to UseNativeLibPrefix != 'false' (default on)
Microsoft.NETCore.Native.Unix.targets Add $(NativeBinaryPrefix) to SharedLibraryInstallName
native-library.targets Add $(NativeBinaryPrefix) to all native output file path references
tests.android.targets Remove redundant _UseNativeLibPrefix setting
SharedLibrary.csproj Opt out of new default with UseNativeLibPrefix=false
CustomMainWithStubExe.csproj Opt out of new default with UseNativeLibPrefix=false
mscordaccore_universal.csproj Opt out to avoid double-prefix (AssemblyName already includes LibPrefix)

Comment on lines +103 to +104
<CopyFinalFiles Include="$(NativeOutputPath)$(NativeBinaryPrefix)$(TargetName)$(NativeBinaryExt)" />
<CopyFinalFilesPDB Include="$(NativeOutputPath)$(NativeBinaryPrefix)$(TargetName).pdb" />
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: These two lines are inside a Condition="'$(TargetsWindows)' == 'true'" block, where NativeBinaryPrefix will always be empty. Adding $(NativeBinaryPrefix) here is harmless but unnecessary and could confuse future readers into thinking the prefix might apply on Windows.

Suggested change
<CopyFinalFiles Include="$(NativeOutputPath)$(NativeBinaryPrefix)$(TargetName)$(NativeBinaryExt)" />
<CopyFinalFilesPDB Include="$(NativeOutputPath)$(NativeBinaryPrefix)$(TargetName).pdb" />
<CopyFinalFiles Include="$(NativeOutputPath)$(TargetName)$(NativeBinaryExt)" />
<CopyFinalFilesPDB Include="$(NativeOutputPath)$(TargetName).pdb" />

Copilot uses AI. Check for mistakes.
@MichalStrehovsky
Copy link
Member

@copilot do we miss taking NativeBinaryPrefix into account in ComputeLinkedFilesToPublish around where symbol files are handled?

…FilesToPublish

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 12, 2026

@copilot do we miss taking NativeBinaryPrefix into account in ComputeLinkedFilesToPublish around where symbol files are handled?

Yes, good catch! All the symbol-related paths in ComputeLinkedFilesToPublish were missing $(NativeBinaryPrefix) — the source path (_symbolSourcePath), the target path (_symbolTargetPath), the recursive glob path, and both RelativePath metadata values (for flat .dbg and dSYM bundle cases). Fixed in ba4370f.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-NativeAOT-coreclr breaking-change Issue or PR that represents a breaking API or functional change over a previous release. needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Use correct native lib prefix in native AOT for android

5 participants