Skip to content

Remove always searching executable directory for native libraries in single-file applications #115236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
May 22, 2025

Conversation

elinor-fung
Copy link
Member

@elinor-fung elinor-fung commented May 2, 2025

Avoid always searching the application directory for native libraries in single-file applications. The assembly directory, which is searched by default and when DllImportSearchPath.AssemblyDirectory is specified, is treated as the application directory.

  • Single-file
    • Stop adding the app directory and extraction directory to NATIVE_DLL_SEARCH_DIRECTORIES (paths which are always searched)
    • When looking for native libraries, treat assembly directory for bundled assemblies as the bundle directory
      • If the bundle has extracted assets, also look in the extraction path (if not found in the bundle directory)
  • NativeAOT
    • Update p/invoke default to search assembly directory
    • Don't set RPATH by default
    • Remove IlcRPath property

Resolves #114717

cc @dotnet/appmodel @dotnet/interop-contrib @MichalStrehovsky @jkotas

@elinor-fung elinor-fung force-pushed the singleFile-appDirSearch branch from c9d23b7 to 7e8a56c Compare May 2, 2025 18:04
@elinor-fung elinor-fung marked this pull request as ready for review May 2, 2025 20:29
@elinor-fung elinor-fung added the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label May 2, 2025
@elinor-fung elinor-fung added this to the 10.0.0 milestone May 2, 2025
@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 May 2, 2025
Copy link
Contributor

dotnet-policy-service bot commented May 2, 2025

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.

@filipnavara
Copy link
Member

You should validate the use of IlcRPath in dotnet/macios workloads. They create app boundles where it's essential to set it.

Comment on lines 234 to 235
<LinkerArg Include="-Wl,-rpath,'$(IlcRPath)'" Condition="'$(IlcRPath)' != '' and '$(StaticExecutable)' != 'true' and !$([MSBuild]::IsOSPlatform('Windows'))" />
<LinkerArg Include="-Wl,-rpath,&quot;$(IlcRPath)&quot;" Condition="'$(IlcRPath)' != '' and '$(StaticExecutable)' != 'true' and $([MSBuild]::IsOSPlatform('Windows'))" />
Copy link
Member

Choose a reason for hiding this comment

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

I think we can just delete this line; it's unlikely users will remember the correct -rpath value per platform (e.g., macOS vs. Linux). It's more simpler for them to specify <LinkerArg Include="-Wl,-rpath,..."> directly in their own projects (if they really need it for some reason), as they already do for other platform-specific linker options we don't cover.

Suggested change
<LinkerArg Include="-Wl,-rpath,'$(IlcRPath)'" Condition="'$(IlcRPath)' != '' and '$(StaticExecutable)' != 'true' and !$([MSBuild]::IsOSPlatform('Windows'))" />
<LinkerArg Include="-Wl,-rpath,&quot;$(IlcRPath)&quot;" Condition="'$(IlcRPath)' != '' and '$(StaticExecutable)' != 'true' and $([MSBuild]::IsOSPlatform('Windows'))" />

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I think we can just delete IlcRpath. It was never documented and I can't see any uses of this property outside the dotnet/runtime repo. The only remaining use is in our test tree, but we can replace that one with a direct use of LinkerArg ItemGroup.

@elinor-fung
Copy link
Member Author

You should validate the use of IlcRPath in dotnet/macios workloads. They create app boundles where it's essential to set it.

Should just template apps with NativeAOT enabled for macOS or Mac Catalyst be enough to see them fail (presumably) without rpath set? I don't have a Mac to try on right now, but will try those when I do.

@filipnavara
Copy link
Member

filipnavara commented May 5, 2025

Should just template apps with NativeAOT enabled for macOS or Mac Catalyst be enough to see them fail (presumably) without rpath set?

Yes, anything that calls into System.Native should be enough, so probably even Console.WriteLine (with netX-macos TFM).

@MichalStrehovsky
Copy link
Member

Should just template apps with NativeAOT enabled for macOS or Mac Catalyst be enough to see them fail (presumably) without rpath set?

Yes, anything that calls into System.Native should be enough, so probably even Console.WriteLine (with netX-macos TFM).

It might not be necessary to test this - I don't see how this could affect things. Xamarin targets don't seem to use IlcRpath or the LinkerArg ItemGroup and I don't see anything else affected by this.

@filipnavara
Copy link
Member

Xamarin targets don't seem to use IlcRpath or the LinkerArg ItemGroup and I don't see anything else affected by this.

It doesn't seem to use it (anymore?). There were some issues referencing it in the past. Most likely it's going to be fine but I think a simple smoke test would be worth it since the macOS/iOS bundles are easy to break with changes like this one.

@elinor-fung
Copy link
Member Author

I validated that the template macOS and Mac Catalyst apps with PublishAot=true publish / run fine without IlcRPath. They do set rpath (it was set to @executable_path/../MonoBundle in my app), but looks like it is handled in their own targets without relying on the NativeAOT ones: https://github.com/dotnet/macios/blob/06b5b841bdb35ed1f42e6bb73bab331b53b92877/dotnet/targets/Xamarin.Shared.Sdk.targets#L1127-L1128

@elinor-fung elinor-fung reopened this May 20, 2025
@elinor-fung elinor-fung merged commit f0230db into dotnet:main May 22, 2025
156 checks passed
@elinor-fung elinor-fung removed the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label May 22, 2025
SimaTian pushed a commit that referenced this pull request May 27, 2025
…single-file applications (#115236)

Avoid always searching the application directory for native libraries in single-file applications. The assembly directory, which is searched by default and when `DllImportSearchPath.AssemblyDirectory` is specified, is treated as the application directory.
- Single-file
  - Stop adding the app directory and extraction directory to `NATIVE_DLL_SEARCH_DIRECTORIES` (paths which are always searched)
  - When looking for native libraries, treat assembly directory for bundled assemblies as the bundle directory
    - If the bundle has extracted assets, also look in the extraction path (if not found in the bundle directory)
- NativeAOT
  - Update p/invoke default to search assembly directory
  - Don't set RPATH by default
  - Remove `IlcRPath` property
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Single-File breaking-change Issue or PR that represents a breaking API or functional change over a prerelease.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Remove always searching executable directory for native libraries in single-file applications
5 participants