Skip to content

Conversation

elinor-fung
Copy link
Member

@elinor-fung elinor-fung commented Aug 1, 2025

Currently, when resolving RID-agnostic assets from an application itself (that is, those in the app's .deps.json), any subdirectory specified in the file path is ignored. We just take the file name and expect it to be next to the .deps.json.

#117682 added an optional localPath property for assets. If set, this represents the path on disk relative to the .deps.json. This change updates the host to consume that property. When resolving assets from an application itself:

  1. localPath property is set: use <deps_dir>/<localPath>
  2. asset is from a runtimepack: use <deps_dir>/<file_path>
    • runtimepack assets are always generated with the actual destination path in the file path
  3. otherwise (this is the existing behaviour):
    • RID-specific assets: use <deps_dir>/<file_path>
    • RID-agnostic assets:
      • runtime: take only the file name, use <deps_dir>/<file_name>
      • resources: take parent directory name of the file path, use <deps_dir>/<dir_name>/<file_name>
Example .deps.json resolution

With the following package in a .deps.json:

"MyPackage/1.0.0": {
  "runtime": {
    // resolves to <deps_dir>/pkg/lib.dll
    "lib/net10.0/lib.dll": {
      "localPath": "pkg/lib.dll"
    },
    // resolves to <deps_dir>/lib2.dll
    "lib/net10.0/lib2.dll": { },
    "resources": {
      // resolves to <deps_dir>/pkg/fr/lib.resources.dll
      "lib/net10.0/fr/lib.resources.dll": {
        "localPath": "pkg/fr/lib.resources.dll"
      },
      // resolves to <deps_dir>/de/lib.resources.dll
      "lib/net10.0/de/lib.resources.dll": { },
    }
  },
 "runtimeTargets": {
    // resolves to <deps_dir>/pkg/runtimes/win-x64/native/libnative.dll
    "runtimes/win-x64/native/libnative.dll": {
      "localPath": "pkg/runtimes/win-x64/native/libnative.dll"
    },
    // resolves to <deps_dir>/runtimes/win-x64/native/libnative2.dll
    "runtimes/win-x64/native/libnative2.dll": { }
  }
}

The paths would be:

  • TPA: <deps_dir>/pkg/lib.dll, <deps_dir>/lib2.dll
  • Resource roots: <deps_dir>/pkg
  • Native search directories: <deps_dir>/pkg/runtimes/win-x64/native

With this change, usage of app-relative .NET search, and some msbuild hackery, it is possible to publish a self-contained application and stick the runtimepack in a subdirectory:

<PropertyGroup>
  <AppHostRelativeDotNet>runtimepack</AppHostRelativeDotNet>
</PropertyGroup>
<Target Name="UpdateRuntimePackAssets" AfterTargets="ResolveRuntimePackAssets">
  <ItemGroup>
    <RuntimePackAsset Update="@(RuntimePackAsset)->WithMetadataValue('CopyLocal', 'true')"
      DestinationSubPath="$(AppHostRelativeDotNet)\%(FileName)%(Extension)"
      DestinationSubDirectory="$(AppHostRelativeDotNet)\" />
    <ReferenceCopyLocalPaths Remove="@(RuntimePackAsset)" />
    <ReferenceCopyLocalPaths Include="@(RuntimePackAsset)" />
  </ItemGroup>
</Target>

Resolves #3525
cc @dotnet/appmodel @AaronRobinsonMSFT

@Copilot Copilot AI review requested due to automatic review settings August 1, 2025 23:38
Copy link
Contributor

@Copilot 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 implements support for the optional localPath property in .deps.json files to allow more flexible asset resolution in the .NET host. The host now uses the localPath property when available to determine the actual file location relative to the application directory, providing better control over asset placement.

Key changes:

  • Updated asset resolution logic to prioritize localPath when available
  • Modified path computation to handle different asset types and library types appropriately
  • Added comprehensive test coverage for the new functionality

Reviewed Changes

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

Show a summary per file
File Description
src/native/corehost/hostpolicy/deps_resolver.cpp Updated asset resolution logic to use localPath and refactored method names
src/native/corehost/hostpolicy/deps_format.cpp Added parsing and tracing for the localPath property
src/native/corehost/hostpolicy/deps_entry.h Added local_path field to deps_asset_t struct and updated method signatures
src/native/corehost/hostpolicy/deps_entry.cpp Implemented new path resolution logic using localPath with fallback behavior
src/native/corehost/fxr/standalone/hostpolicy_resolver.cpp Fixed a bug where version string was not being returned
src/installer/tests/TestUtils/NetCoreAppBuilder.cs Added support for localPath in test infrastructure
src/installer/tests/TestUtils/DotNetBuilder.cs Updated test builders to use new WithLocalPath method
src/installer/tests/HostActivation.Tests/SelfContainedAppLaunch.cs Added test for custom runtime location using app-relative paths
src/installer/tests/HostActivation.Tests/DependencyResolution/ResolveComponentDependencies.cs Updated test to use new WithLocalPath method
src/installer/tests/HostActivation.Tests/DependencyResolution/LocalPath.cs New comprehensive test file covering all asset types with and without localPath
src/installer/tests/HostActivation.Tests/DependencyResolution/DependencyResolutionCommandResultExtensions.cs Added helper methods for testing resource root path resolution

@elinor-fung elinor-fung merged commit bb71812 into dotnet:main Aug 13, 2025
143 of 146 checks passed
@elinor-fung elinor-fung deleted the host-deps-localPath branch August 13, 2025 20:07
@github-actions github-actions bot locked and limited conversation to collaborators Sep 13, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Relative path in deps.json is ignored for assemblies from the app
2 participants