Skip to content
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

[mono] new Sdk that selects mono runtime components #54432

Merged
49 commits merged into from
Jul 8, 2021

Conversation

lambdageek
Copy link
Member

@lambdageek lambdageek commented Jun 18, 2021

Related to #54417

The contract is:

  • The runtime defines _MonoRuntimeAvailableComponents which is an item list like "hot_reload;diagnostic_tracing"
  • The workoad defines _MonoComponent which is some subset of the items that makes sense in the current configuration of the user app
  • The workload calls the _MonoSelectRuntimeComponents target
    • The target returns _MonoRuntimeSelectedComponents (and _MonoRuntimeSelectedStubComponents if static linking) which are the names of the comopnents that will be available (or stubbed out, if static linking)
    • The target returns _MonoRuntimeComponentLink which is a list of filenames (relative to the runtime pack native/ subdirectory) of the libraries that must be either copied (for dynamic loading) or statically linked (for static linking) with the runtime. The items also have some metadata such as IsStub, ComponentName and Linking
    • The target also returns a _MonoRuntimeComponentDontLink list of filenames to exclude from linking for workloads which would rather take everything from native/ and just exclude what we tell them to exclude.

@ghost
Copy link

ghost commented Jun 18, 2021

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Related to #54417

The contract is:

  • The runtime defines _MonoRuntimeAvailableComponents which is an item list like "hot_reload;diagnostic_tracing"
  • The workoad defines _MonoComponent which is some subset of the times that makes sense in the current configuration of the user app
  • The workload calls the _MonoSelectRuntimeComponents target
    • The target returns _MonoRuntimeSelectedComponents (and _MonoRuntimeSelectedStubComponents if static linking) which are the names of the comopnents that will be available (or stubbed out, if static linking)
    • The target returns _MonoRuntimeComponentLink which is a list of filenames (relative to the runtime pack native/ subdirectory) of the libraries that must be either copied (for dynamic loading) or statically linked (for static linking) with the runtime. The items also have some metadata such as IsStub, ComponentName and Linking

TODO

  • Right now the component-manifest.props is generated from component-manifest.props.in when the nuget is built. this is wrong:
    • the component-manifest.props file is RID-dependent for two reasons: whether we do static or dynamic linking of components depends on the target platform, and the file extensions also depend on the platform.
    • the list of components is currently hardcoded in the pkgproj, but it should really come from the source of truth: src/mono/mono/component/CMakeLists.txt
Author: lambdageek
Assignees: -
Labels:

area-System.Net

Milestone: -

@lambdageek

This comment has been minimized.

@lambdageek

This comment has been minimized.

@lambdageek

This comment has been minimized.

@lambdageek
Copy link
Member Author

Ok, added a workload manifest.

One thing that is surprising to me is that we have apparently an iossimulator-x86 runtime pack? Is that right? I didn't add the workload manifest for the Sdk for it. We need one, right?

@lambdageek lambdageek marked this pull request as ready for review June 23, 2021 15:37
@lambdageek lambdageek changed the title [draft] new Sdk that selects mono runtime components [mono] new Sdk that selects mono runtime components Jun 23, 2021
@lambdageek
Copy link
Member Author

Is this actually going to work? because of the indirection of going through pack IDs, only a build targeting, let's say... android-arm64 will load the Microsoft.NETCore.App.Runtime.Mono.android-arm64.Sdk nuget's Sdk.props and from there the component-manifest.props, right? And so that build will get the mono components for android-arm64.

@steveisok
Copy link
Member

Is this actually going to work? because of the indirection of going through pack IDs, only a build targeting, let's say... android-arm64 will load the Microsoft.NETCore.App.Runtime.Mono.android-arm64.Sdk nuget's Sdk.props and from there the component-manifest.props, right? And so that build will get the mono components for android-arm64.

You need to add the right imports in https://github.com/dotnet/runtime/blob/4615e06d531d10cb0c4347173718ee30620fda9a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets

@lambdageek
Copy link
Member Author

Is this actually going to work? because of the indirection of going through pack IDs, only a build targeting, let's say... android-arm64 will load the Microsoft.NETCore.App.Runtime.Mono.android-arm64.Sdk nuget's Sdk.props and from there the component-manifest.props, right? And so that build will get the mono components for android-arm64.

You need to add the right imports in https://github.com/dotnet/runtime/blob/4615e06d531d10cb0c4347173718ee30620fda9a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets

@steveisok Can I just do it like this? is TargetArchitecture defined?

    <ImportGroup>
        <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.$(TargetPlatformIdentifier)-$(TargetArchitecture).Sdk" />
        <Import Project="Sdk.targets" Sdk="Microsoft.NETCore.App.Runtime.$(TargetPlatformIdentifier)-$(TargetArchitecture).Sdk" />
   </ImportGroup>

@lambdageek
Copy link
Member Author

Ok, so the plan here is twofold:

  1. Make the mono-component.props include the host RID in the metadata. So we can include Sdk.props from multiple architectures without conflict.
  2. Make a new nuget that just has the mono-components.targets in it that has the single target that is RID-independent. Update the target to pick from the components for the current target only.
  3. Update the workload manifest for each workload to bring in all the props and the single target

@marek-safar
Copy link
Contributor

@steveisok would be better to extract the plan to separate issue for tracking?

@lambdageek
Copy link
Member Author

I updated the related issue #54417 with the notes from here. I also plan to update the design doc as part of this PR.

@lewing
Copy link
Member

lewing commented Jun 24, 2021

I think this could be simplified a lot if we handled it the way the Cross runtimes do? - which sound like roughly the plan from #54432 (comment)

@steveisok
Copy link
Member

steveisok commented Jun 24, 2021

I think this could be simplified a lot if we handled it the way the Cross runtimes do? - which sound like roughly the plan from #54432 (comment)

Yep, the difference is that we also want to include a .targets file. We can only import that once, so it has to be in another pack.

@lewing
Copy link
Member

lewing commented Jun 24, 2021

I think this could be simplified a lot if we handled it the way the Cross runtimes do? - which sound like roughly the plan from #54432 (comment)

Yep, the difference is that we also want to include a .targets file. We can only import that once, so it has to be in another pack.

I think we could probably combine at least the runtime config and this into a single pack with targets that we enable appropriately. There isn't much need to have everything in a separate pack is there?

@steveisok
Copy link
Member

No, there's not a real need to have them in a separate pack.

@lambdageek
Copy link
Member Author

think we could probably combine at least the runtime config and this into a single pack with targets that we enable appropriately. There isn't much need to have everything in a separate pack is there?

Yea I think we should have a single Mono Targeting SDK nuget that has all tasks and targets that are portable across all host and target architectures. (At the moment it's the runtime config parser and this component selector)

@lambdageek lambdageek force-pushed the mono-runtime-component-manifest branch from fd2c306 to 4492230 Compare June 25, 2021 03:33
@lambdageek

This comment has been minimized.

@marek-safar marek-safar requested a review from radical June 25, 2021 12:27
@steveisok steveisok requested a review from lewing June 25, 2021 13:48
@lambdageek lambdageek force-pushed the mono-runtime-component-manifest branch from c09d837 to 756e5a6 Compare July 7, 2021 14:47
Copy link
Member

@steveisok steveisok left a comment

Choose a reason for hiding this comment

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

LGTM - nice work!

Copy link
Member

@lewing lewing left a comment

Choose a reason for hiding this comment

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

nit: could we s/component-manifest/RuntimeComponentManifest/ or something, adding yet another naming format is painful

instead of TargetsMobile.  We want the build files (mono-components.json)
in every mono runtime pack, not just on mobile targets
src/mono/mono.proj Outdated Show resolved Hide resolved
src/mono/mono/component/component-manifest.json.in Outdated Show resolved Hide resolved
src/tasks/JsonToItemsTaskFactory/JsonToItemsTaskFactory.cs Outdated Show resolved Hide resolved
{
var dict = JsonSerializer.Deserialize<Dictionary<string, string>>(ref reader, options);
if (dict == null)
return null!;
Copy link
Member

Choose a reason for hiding this comment

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

Should the uses of JsonSerializer.Deserialize* also catch JsonException?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think so - we want it to propagate

Copy link
Member

Choose a reason for hiding this comment

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

Ok, then we should catch this up the chain somewhere, so we can log it as an error with the filename.

src/tasks/JsonToItemsTaskFactory/JsonToItemsTaskFactory.cs Outdated Show resolved Hide resolved
src/tasks/JsonToItemsTaskFactory/JsonToItemsTaskFactory.cs Outdated Show resolved Hide resolved
@radical
Copy link
Member

radical commented Jul 7, 2021

Don't wanna block you, but would it be possible to add a sample for this? In future we will be able to test this, at least on wasm. But for now, a sample would help validate it. Not sure if that makes sense though!

from MonoRuntimeComponentsReadManifestTask
Build doesn't like it for some reason (probably net472)
@lambdageek
Copy link
Member Author

Don't wanna block you, but would it be possible to add a sample for this? In future we will be able to test this, at least on wasm. But for now, a sample would help validate it. Not sure if that makes sense though!

@radical
It's hard to test the workloads end to end. Here's a gist of what I use for testing (but as you noticed, I didn't test every time). Not sure where's a good place to check this in. https://gist.github.com/lambdageek/7bb9672fa0a95bb232926aa7630962f4

Also improve nullability a bit by making the properties immutable
@radical
Copy link
Member

radical commented Jul 7, 2021

It's hard to test the workloads end to end. Here's a gist of what I use for testing (but as you noticed, I didn't test every time). Not sure where's a good place to check this in. gist.github.com/lambdageek/7bb9672fa0a95bb232926aa7630962f4

Makes sense. I have a PR open that will add some E2E(almost) testing in runtime, and I can add a test for this after that.

We get nice error messages now like

```
src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/RuntimeComponentManifest.targets(8,5): error : Failed to deserialize json from file 'artifacts/bin/mono/iOSSimulator.x64.Release/build/RuntimeComponentManifest.json', JSON Path: $.items._MonoRuntimeAvailableComponents[2], Line: 14, Position: 1 [component-manifest.sample.proj]
src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/RuntimeComponentManifest.targets(8,5): error : JsonException: The JSON value could not be converted to System.Collections.Generic.Dictionary`2[System.String,System.String]. Path: $.identity | LineNumber: 0 | BytePositionInLine: 16. Path: $.items._MonoRuntimeAvailableComponents[2] | LineNumber: 14 | BytePositionInLine: 1. [component-manifest.sample.proj]
src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/RuntimeComponentManifest.targets(8,5): error : InvalidOperationException: Cannot get the value of a token type 'Number' as a string. [component-manifest.sample.proj]
src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/RuntimeComponentManifest.targets(8,5):
error :
[component-manifest.sample.proj]
```
@ghost
Copy link

ghost commented Jul 7, 2021

Hello @lambdageek!

Because this pull request has the auto-merge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

else
idict.Remove("Identity");
return new JsonModelItem(identity, metadata: idict);
default:
throw new Exception();
throw new NotSupportedException();
Copy link
Member

Choose a reason for hiding this comment

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

token type in the message might be useful for debugging

Copy link
Member Author

Choose a reason for hiding this comment

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

The JsonSerializer catches and decorates NotSupportedException with location and type info https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?pivots=dotnet-5-0#notsupportedexception

@ghost ghost merged commit 893739f into dotnet:main Jul 8, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Aug 7, 2021
This pull request was closed.
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.

8 participants