Skip to content

Commit 893739f

Browse files
lambdageekrolfbjarneradical
authored
[mono] new Sdk that selects mono runtime components (#54432)
* Work in progress: new Sdk that selects mono runtime components * Add props and targets description to the components doc * condition the _MonoRuntimeAvailableComponents by RuntimeIdentifier * [cmake] Write a component-manifest.props file during build If we're not building a mono aot cross compiler, generate a component-manifest.props file in artifacts/obj/mono/<host>/ that indicates if the host will use static or dynamic components, and a list of the available components, and the properties for constructing their names. * Build Microsoft.NETCore.App.Runtime.Mono.<RID>.Sdk shared framework nuget It seems to also generate a symbols nuget. And in the nuget there's a tools/mono-sdk-what-is-this.deps.json file from the SharedFrameworkHostFileNameOverride property. It would be nice to exclude that stuff. * put the compoonent-manifest.targets into the Sdk * delete WIP in mono/nuget/ * fixup static component names in component-manifest.targets * delete fixed fixme * add missing $ * fix whitespace * [cmake] switch to configure_file instead of file(CONFIGURE) * add missing trailing slashes in .props.in file * Add new Sdk packs to the workload manifest * rework component-manifest.targets to use ItemGroups; move to new SDK * Rename shared framework to Microsoft.NETCore.App.Runtime.Mono.<RID>.Props.Sdk And only include component-manifest.props, not the targets * Update manifest to include the new Props.Sdk and MonoTargets.Sdk * Move RuntimeConfigParserTask into Microsoft.NET.Runtime.MonoTargets.Sdk Consolidate all platform-independent tasks and targets into a single Sdk * Add iossimulator-x86 props * update components design doc * Fix typo * improve docs * Add _MonoRuntimeComponentDontLink target output * Drop component-manifest.props into runtime pack build/ directory Remove from the Microsoft.NETCore.App.Mono.Props.Sdk workload nuget * remove Microsoft.NETCore.App.Mono.Props.Sdk * Import component-manifest.props from the runtime pack Move the MonoTargets.Sdk import to each target platform that we support * Fix typos Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com> * Apply suggestions from code review Co-authored-by: Ankit Jain <radical@gmail.com> * Add JsonToItemsTaskFactory * fix whitespace * Do some validation earlier in _MonoComputeAvailableComponentDefinitions * Read component-manifest.json using the JsonToItemsTaskFactory and bundle it in Microsoft.NET.Runtime.MonoTargets.Sdk * remove ResolvedRuntimePack import from WorkloadManifest.targets it's too early, and we have the JsonToItemsTaskFactory now to read the manifest * Generate component-manifest.json in CMakeLists.txt * Fix some copy-paste nits * Use RuntimeFlavor==mono for runtime pack build directory instead of TargetsMobile. We want the build files (mono-components.json) in every mono runtime pack, not just on mobile targets * Apply suggestions from code review Co-authored-by: Ankit Jain <radical@gmail.com> * rename component-manifest to RuntimeComponentManifest * fixup nullability annotations * fix whitespace * fix formatting * Misc fixes to JsonToItemsTaskFactory * Rename MonoRuntimeComponentManifestReadTask from MonoRuntimeComponentsReadManifestTask * undo nullability annotation Build doesn't like it for some reason (probably net472) * fix incorrect task parameter name * Remove Identity metadata from dictionary at json parsing time Also improve nullability a bit by making the properties immutable * Throw correct json deserializer exceptions * Catch JsonException in an async function 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] ``` * fixup comments Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com> Co-authored-by: Ankit Jain <radical@gmail.com>
1 parent 30d770d commit 893739f

File tree

21 files changed

+858
-79
lines changed

21 files changed

+858
-79
lines changed

docs/design/mono/components.md

Lines changed: 69 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,10 @@ To implement `feature_X` as a component. Carry out the following steps:
164164
{ feature_X_cleanup },
165165
feature_X_hello,
166166
};
167-
167+
168168
MonoComponentFeatureX *
169169
mono_component_feature_X_init (void) { return &fn_table; }
170-
170+
171171
void feature_X_cleanup (MonoComponent *self)
172172
{
173173
static int cleaned = 0;
@@ -207,10 +207,10 @@ To implement `feature_X` as a component. Carry out the following steps:
207207
{ feature_X_cleanup },
208208
feature_X_hello,
209209
};
210-
210+
211211
MonoComponentFeatureX *
212212
mono_component_feature_X_init (void) { return &fn_table; }
213-
213+
214214
void feature_X_cleanup (MonoComponent *self)
215215
{
216216
static int cleaned = 0;
@@ -229,7 +229,7 @@ To implement `feature_X` as a component. Carry out the following steps:
229229
```c
230230
MonoComponentFeatureX*
231231
mono_component_feature_X (void);
232-
232+
233233
...
234234
MonoComponentFeatureX*
235235
mono_component_feature_X_stub_init (void);
@@ -238,7 +238,7 @@ To implement `feature_X` as a component. Carry out the following steps:
238238
* Add an entry to the `components` list to load the component to `mono/metadata/components.c`, and also implement the getter for the component:
239239
```c
240240
static MonoComponentFeatureX *feature_X = NULL;
241-
241+
242242
MonoComponentEntry components[] = {
243243
...
244244
{"feature_X", "feature_X", COMPONENT_INIT_FUNC (feature_X), (MonoComponent**)&feature_X, NULL },
@@ -265,16 +265,66 @@ To implement `feature_X` as a component. Carry out the following steps:
265265
## Detailed design - Packaging and runtime packs
266266

267267
The components are building blocks to put together a functional runtime. The
268-
runtime pack includes the base runtime and the components and additional
269-
properties and targets that enable the workload to construct a runtime for
270-
various scenarios.
271-
272-
In each runtime pack we include:
273-
274-
- The compiled compnents for the apropriate host architectures in a well-known subdirectory
275-
- An MSBuild props file that defines an item group that list each component name and has metadata that indicates:
276-
- the path to the component in the runtime pack
277-
- the path to the stub component in the runtime pack (if components are static)
278-
- An MSBuild targets file that defines targets to copy a specified set of components to the app publish folder (if components are dynamic); or to link the runtime together with stubs and a set of enabled components (if components are static)
279-
280-
** TODO ** Write this up in more detail
268+
runtime pack includes the base runtime and the components. The mono workload
269+
includes the runtime pack and additional tasks, properties and targets that
270+
enable the workload to construct a runtime for various scenarios.
271+
272+
For the target RID, we expose:
273+
274+
- `@(_MonoRuntimeComponentLinking)` set to either `'static'` or `'dynamic'` depending on whether the
275+
current runtime pack for the current target includes runtime components as static archives or as
276+
shared libraries, respectively.
277+
- `@(_MonoRuntimeComponentSharedLibExt)` and `@(_MonoRuntimeComponentStaticLibExt)` set to the file
278+
extension of the runtime components for the current target (ie, `'.a', '.so', '.dylib'` etc).
279+
- `@(_MonoRuntimeAvailableComponents)` a list of component names without the `lib` prefix (if any)
280+
or file extensions. For example: `'hot_reload; diagnostics_tracing'`.
281+
282+
Each of the above item lists has `RuntimeIdentifier` metadata. For technical reasons the mono
283+
workload will provide a single `@(_MonoRuntimeAvailableComponent)` item list for all platforms. We
284+
use the `RuntimeIdentifier` metadata to filter out the details applicable for the current platform.
285+
286+
- The target `_MonoSelectRuntimeComponents` that has the following inputs and outputs:
287+
- input `@(_MonoComponent)` (to be set by the workload) : a list of components that a workload wants to use for the current
288+
app. It is an error if this specifies any unknown component name.
289+
- output `@(_MonoRuntimeSelectedComponents)` and `@(_MonoRuntimeSelectedStubComponents)` The names
290+
of the components that were (resp, were not) selected. For example `'hot_reload;
291+
diagnostics_tracing'`. Each item has two metadata properties `ComponentLib` and
292+
`ComponentStubLib` (which may be empty) that specify the name of the static or dynamic library
293+
of the component. This is not the main output of the target, it's primarily for debugging.
294+
- output `@(_MonoRuntimeComponentLink)` a list of library names (relative to the `native/`
295+
subdirectory of the runtime pack) that (for dynamic components) must be placed next to the
296+
runtime in the application bundle, or (for static components) that must be linked with the
297+
runtime to enable the components' functionality. Each item in the list has metadata
298+
`ComponentName` (e.g. `'hot_reload'`), `IsStub` (`true` or `false`), `Linking` (`'static'` or
299+
`'dynamic'`). This output should be used by the workloads when linking the app and runtime if
300+
the workload uses an allow list of native libraries to link or bundle.
301+
- output `@(_MonoRuntimeComponentDontLink)` a list of library names (relative to the `native/`
302+
subdirectory of the runtime pack) that should be excluded from the application bundle (for
303+
dynamic linking) or that should not be passed to the native linker (for static linking). This
304+
output should be used by workloads that just link or bundle every native library from `native/`
305+
in order to filter the contents of the subdirectory to exclude the disabled components (and to
306+
exclude the static library stubs for the enabled components when static linking).
307+
308+
Generally workloads should only use one of `@(_MonoRuntimeComponentLink)` or
309+
`@(_MonoRuntimeComponentDontLink)`, depending on whether they use an allow or block list for the
310+
contents of the `native/` subdirectory.
311+
312+
Example fragment (assuming the mono workload has been imported):
313+
314+
```xml
315+
<Project>
316+
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
317+
<_MonoComponent Include="hot_reload;diagnostics_tracing" />
318+
</ItemGroup>
319+
320+
<Target Name="PrintComponents" DependsOnTargets="_MonoSelectRuntimeComponents">
321+
<Message Importance="High" Text="Runtime identifier: $(RuntimeIdentifier)" />
322+
<Message Importance="High" Text="Selected : @(_MonoRuntimeSelectedComponents) %(ComponentLib)" />
323+
<Message Importance="High" Text="Stubbed out : @(_MonoRuntimeSelectedStubComponents) %(ComponentStubLib)" />
324+
<Message Importance="High" Text="Linking with lib @(_MonoRuntimeComponentLink) Stub: %(IsStub) Linking: %(Linking) Component: %(ComponentName)"/>
325+
326+
<Message Importance="High" Text="UnSelected : @(_MonoRuntimeUnSelectedComponents) %(ComponentLib)" />
327+
<Message Importance="High" Text="Exclude these from linking: @(_MonoRuntimeComponentDontLink) Stub: %(IsStub) Linking: %(Linking) Component: %(ComponentName)" />
328+
</Target>
329+
</Project>
330+
```

src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.props

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@
7070
<TargetPath>runtimes/$(RuntimeIdentifier)/native/include/%(RecursiveDir)</TargetPath>
7171
</RuntimeFiles>
7272

73+
<RuntimeFiles Condition="'$(RuntimeFlavor)' == 'mono'"
74+
Include="$(MonoArtifactsPath)\build\**\*.*"
75+
ExcludeFromDataFiles="true">
76+
<TargetPath>runtimes/$(RuntimeIdentifier)/build/%(RecursiveDir)</TargetPath>
77+
</RuntimeFiles>
78+
7379
<CoreCLRCrossTargetFiles PackOnly="true" />
7480
<CoreCLRCrossTargetFiles Condition="'%(FileName)' == 'clrjit' or '%(FileName)' == 'libclrjit'">
7581
<TargetPath>runtimes/$(CoreCLRCrossTargetComponentDirName)_$(TargetArchitecture)/native</TargetPath>

src/mono/mono.proj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,9 @@
431431
<ItemGroup Condition="'$(MonoComponentsStatic)' == 'true'">
432432
<_MonoCMakeArgs Include="-DSTATIC_COMPONENTS=1" />
433433
</ItemGroup>
434+
<ItemGroup>
435+
<_MonoCMakeArgs Include="-DMONO_COMPONENTS_RID=$(TargetOS)-$(TargetArchitecture)" />
436+
</ItemGroup>
434437

435438
<PropertyGroup>
436439
<_MonoCFLAGSOption>-DCMAKE_C_FLAGS="@(_MonoCPPFLAGS, ' ') @(_MonoCFLAGS, ' ')"</_MonoCFLAGSOption>
@@ -770,6 +773,7 @@
770773
<Destination>$(RuntimeBinDir)cross\$(PackageRID)\opt$(ExeExt)</Destination>
771774
</_MonoRuntimeArtifacts>
772775
<_MonoIncludeArtifacts Include="$(MonoObjDir)out\include\**" />
776+
<_MonoRuntimeBuildArtifacts Include="$(MonoObjDir)\build\**" />
773777
<_MonoRuntimeArtifacts Condition="'$(_MonoIncludeInterpStaticFiles)' == 'true'" Include="$(MonoObjDir)out\lib\libmono-ee-interp.a">
774778
<Destination>$(RuntimeBinDir)libmono-ee-interp.a</Destination>
775779
</_MonoRuntimeArtifacts>
@@ -816,6 +820,11 @@
816820
SkipUnchangedFiles="true"
817821
Condition="'$(MonoGenerateOffsetsOSGroups)' == '' and ('$(TargetsMacCatalyst)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true' or '$(TargetsAndroid)' == 'true' or '$(TargetsBrowser)' == 'true')"/>
818822

823+
<Copy SourceFiles="@(_MonoRuntimeBuildArtifacts)"
824+
DestinationFiles="@(_MonoRuntimeBuildArtifacts->'$(RuntimeBinDir)build\%(RecursiveDir)%(Filename)%(Extension)')"
825+
SkipUnchangedFiles="true"
826+
Condition="'$(BuildMonoAOTCrossCompilerOnly)' != 'true'" />
827+
819828
<Exec Condition="'$(BuildMonoAOTCrossCompilerOnly)' != 'true' and '$(MonoGenerateOffsetsOSGroups)' == '' and ('$(TargetsOSX)' == 'true' or '$(TargetsMacCatalyst)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true')" Command="install_name_tool -id @rpath/$(MonoFileName) $(RuntimeBinDir)$(MonoFileName)" />
820829
</Target>
821830

src/mono/mono/component/CMakeLists.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ set(${MONO_DIAGNOSTICS_TRACING_COMPONENT_NAME}-dependencies
8282

8383
#define a library for each component and component stub
8484
function(define_component_libs)
85+
# NOTE: keep library naming pattern in sync with RuntimeComponentManifest.targets
8586
if (NOT DISABLE_LIBS)
8687
foreach(component IN LISTS components)
8788
add_library("mono-component-${component}-static" STATIC $<TARGET_OBJECTS:${component}-objects>)
@@ -121,6 +122,7 @@ endforeach()
121122
if(NOT DISABLE_COMPONENTS AND NOT STATIC_COMPONENTS)
122123
# define a shared library for each component
123124
foreach(component IN LISTS components)
125+
# NOTE: keep library naming pattern in sync with RuntimeComponentManifest.targets
124126
if(HOST_WIN32)
125127
add_library("mono-component-${component}" SHARED "${${component}-sources}")
126128
target_compile_definitions("mono-component-${component}" PRIVATE -DCOMPILING_COMPONENT_DYNAMIC;-DMONO_DLL_IMPORT)
@@ -172,6 +174,26 @@ foreach(component IN LISTS components)
172174
list(APPEND mono-components-stub-objects $<TARGET_OBJECTS:${component}-stub-objects>)
173175
endforeach()
174176

177+
if(NOT MONO_CROSS_COMPILE)
178+
set(TemplateMonoRuntimeComponentSharedLibExt "${CMAKE_SHARED_LIBRARY_SUFFIX}")
179+
set(TemplateMonoRuntimeComponentStaticLibExt "${CMAKE_STATIC_LIBRARY_SUFFIX}")
180+
set(TemplateRuntimeIdentifier "${MONO_COMPONENTS_RID}")
181+
if(DISABLE_COMPONENTS)
182+
set(TemplateMonoRuntimeComponentLinking "static")
183+
set(TemplateMonoRuntimeAvailableComponents "")
184+
else()
185+
list(TRANSFORM components REPLACE "^(.+)$" "{ \"identity\": \"\\1\", \"RuntimeIdentifier\": \"${TemplateRuntimeIdentifier}\" }," OUTPUT_VARIABLE TemplateMonoRuntimeAvailableComponentsList)
186+
list(JOIN TemplateMonoRuntimeAvailableComponentsList "\n" TemplateMonoRuntimeAvailableComponents)
187+
if(STATIC_COMPONENTS)
188+
set(TemplateMonoRuntimeComponentLinking "static")
189+
else()
190+
set(TemplateMonoRuntimeComponentLinking "dynamic")
191+
endif()
192+
endif()
193+
# Write a RuntimeComponentManifest.json file in the artifacts/obj/mono/<host>/build/ directory
194+
# without the ../.. the file would go in artifacts/obj/mono/<host>/mono/mini
195+
configure_file( "${MONO_COMPONENT_PATH}/RuntimeComponentManifest.json.in" "../../build/RuntimeComponentManifest.json")
196+
endif()
175197

176198
# component tests
177199
set(MONO_EVENTPIPE_TEST_SOURCE_PATH "${MONO_EVENTPIPE_SHIM_SOURCE_PATH}/test")
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"items": {
3+
"_MonoRuntimeComponentLinking": [
4+
{ "identity": "${TemplateMonoRuntimeComponentLinking}", "RuntimeIdentifier": "${TemplateRuntimeIdentifier}" },
5+
],
6+
"_MonoRuntimeComponentSharedLibExt": [
7+
{ "identity": "${TemplateMonoRuntimeComponentSharedLibExt}", "RuntimeIdentifier": "${TemplateRuntimeIdentifier}" },
8+
],
9+
"_MonoRuntimeComponentStaticLibExt": [
10+
{ "identity": "${TemplateMonoRuntimeComponentStaticLibExt}", "RuntimeIdentifier": "${TemplateRuntimeIdentifier}" },
11+
],
12+
"_MonoRuntimeAvailableComponents": [
13+
${TemplateMonoRuntimeAvailableComponents}
14+
],
15+
}
16+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<Project DefaultTargets="Build">
2+
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.props))" />
3+
4+
<PropertyGroup>
5+
<PackageDescription>Provides the tasks+targets, for consumption by mono-based workloads</PackageDescription>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="$(RepoTasksDir)RuntimeConfigParser\RuntimeConfigParser.csproj" />
10+
<ProjectReference Include="$(RepoTasksDir)JsonToItemsTaskFactory\JsonToItemsTaskFactory.csproj" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<PackageFile Include="Sdk\Sdk.props" TargetPath="Sdk" />
15+
<PackageFile Include="Sdk\Sdk.targets" TargetPath="Sdk" />
16+
<PackageFile Include="build\$(MSBuildProjectName).props" TargetPath="build" />
17+
<PackageFile Include="Sdk\RuntimeConfigParserTask.props" TargetPath="Sdk" />
18+
<PackageFile Include="Sdk\RuntimeComponentManifest.props" TargetPath="Sdk" />
19+
<PackageFile Include="Sdk\RuntimeComponentManifest.targets" TargetPath="Sdk" />
20+
</ItemGroup>
21+
22+
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.targets))" />
23+
</Project>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Mono Runtime Host support targets
2+
3+
This Sdk provides additional tasks and targets for workloads hosting the MonoVM .NET runtime.
4+
5+
## component-manifest.targets
6+
7+
See https://github.com/dotnet/runtime/blob/main/docs/design/mono/components.md
8+
9+
## RuntimeConfigParserTask
10+
The `RuntimeConfigParserTask` task converts a json `runtimeconfig.json` to a binary blob for MonoVM's `monovm_runtimeconfig_initialize` API.
11+
To use the task in a project, reference the NuGet package, with the appropriate nuget source.
12+
13+
### NuGet.config
14+
```xml
15+
<?xml version="1.0" encoding="utf-8"?>
16+
<configuration>
17+
<packageSources>
18+
<add key="dotnet6" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json" />
19+
</packageSources>
20+
</configuration>
21+
```
22+
23+
### In the project file
24+
```xml
25+
<!-- Import the NuGet package into the project -->
26+
<ItemGroup>
27+
<PackageReference Include="Microsoft.NET.Runtime.MonoTargets.Sdk" Version="<desired-dotnet-6-sdk-version>" />
28+
</ItemGroup>
29+
30+
<!-- Use the RuntimeConfigParser task in a target -->
31+
<Target>
32+
<RuntimeConfigParserTask
33+
RuntimeConfigFile="$(Path_to_runtimeconfig.json_file)"
34+
OutputFile="$(Path_to_generated_binary_file)"
35+
RuntimeConfigReservedProperties="@(runtime_properties_reserved_by_host)">
36+
</RuntimeConfigParserTask>
37+
</Target>
38+
```
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project>
2+
<PropertyGroup>
3+
<JsonToItemsTaskFactoryTasksAssemblyPath Condition="'$(MSBuildRuntimeType)' == 'Core'">$(MSBuildThisFileDirectory)..\tasks\net6.0\JsonToItemsTaskFactory.dll</JsonToItemsTaskFactoryTasksAssemblyPath>
4+
<JsonToItemsTaskFactoryTasksAssemblyPath Condition="'$(MSBuildRuntimeType)' != 'Core'">$(MSBuildThisFileDirectory)..\tasks\net472\JsonToItemsTaskFactory.dll</JsonToItemsTaskFactoryTasksAssemblyPath>
5+
</PropertyGroup>
6+
<UsingTask TaskName="MonoRuntimeComponentManifestReadTask" TaskFactory="JsonToItemsTaskFactory.JsonToItemsTaskFactory" AssemblyFile="$(JsonToItemsTaskFactoryTasksAssemblyPath)">
7+
<ParameterGroup>
8+
<_MonoRuntimeComponentSharedLibExt ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="false" Output="true" />
9+
<_MonoRuntimeComponentStaticLibExt ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="false" Output="true" />
10+
<_MonoRuntimeComponentLinking ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="false" Output="true" />
11+
<_MonoRuntimeAvailableComponents ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="false" Output="true" />
12+
</ParameterGroup>
13+
</UsingTask>
14+
</Project>

0 commit comments

Comments
 (0)