Skip to content

Commit

Permalink
[mono] Clean up internal usage of RuntimeComponents to always be tr…
Browse files Browse the repository at this point in the history
…eated as MSBuild Item (#91800)

* Always use runtime components as MSBuild items

* Addressing PR feedback

* Renaming MonoSharedBuild.props into CommonMobileBuild.props

* Formatting: whitespace

Co-authored-by: Ankit Jain <radical@gmail.com>

* Formatting: whitespace

Co-authored-by: Ankit Jain <radical@gmail.com>

---------

Co-authored-by: Ankit Jain <radical@gmail.com>
  • Loading branch information
ivanpovazan and radical authored Oct 18, 2023
1 parent fa0ba15 commit f16e8bd
Show file tree
Hide file tree
Showing 29 changed files with 194 additions and 181 deletions.
47 changes: 41 additions & 6 deletions docs/design/mono/diagnostics-tracing.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,27 @@ Depending on platform, there are different recommended and supported ways to inc

### Android

Android is build using dynamic component support, meaning that components are included as shared objects and runtime will try to load them from the same location as `libmonosgen-2.0.so`. If runtime fails to load component, it will be disabled, if it successfully loads the component at runtime, it will be enabled and used. Enabling/disabling components is then a matter of including/excluding the needed shared library files in the APK (in same folder as `libmonosgen-2.0.so`). The same runtime build can be used to support any combination of components.
Android is built using dynamic component support, meaning that components are included as shared objects and runtime will try to load them from the same location as `libmonosgen-2.0.so`. If runtime fails to load component, it will be disabled, if it successfully loads the component at runtime, it will be enabled and used. Enabling/disabling components is then a matter of including/excluding the needed shared library files in the APK (in same folder as `libmonosgen-2.0.so`). The same runtime build can be used to support any combination of components.

If `AndroidAppBuilderTask` is used, there is a msbuild property, `RuntimeComponents` that can be used to include specific components in the generated application. By default, its empty, meaning all components will be disabled, using a `*` will enabled all components and by specify individual components, only those will be enabled. Enabling tracing would look like this, `RuntimeComponents="diagnostics_tracing"`, more components can be enabled by separating them with `;`.
Android runtime pack has the following runtime components included: `debugger`, `hot_reload`, `diagnostics_tracing`, `marshal-ilgen`.

Android runtime pack have the following component libraries included. For default scenarios, the dynamic versions should be used together with `libmonosgen-2.0.so`, but runtime pack also includes static versions of the components that can be used if runtime is built statically using `libmonosgen-2.0.a`. In case of static linking, using `libmono-component-*-stub-static.a` library will disable the component, using `libmono-component-*-static.a` will enable it.
For default scenarios, the dynamic versions should be used together with `libmonosgen-2.0.so`, but runtime pack also includes static versions of the components that can be used if runtime is built statically using `libmonosgen-2.0.a`. In case of static linking, using `libmono-component-*-stub-static.a` library will disable the component, using `libmono-component-*-static.a` will enable it.

```
libmono-component-diagnostics_tracing.so
libmono-component-diagnostics_tracing-static.a
libmono-component-diagnostics_tracing-stub-static.a
```

In order to enable the `diagnostic tracing` runtime component in your build, please take a look at [Enabling runtime components](#enabling-runtime-components) section.

### iOS

iOS is build using static component support, meaning that components are included as static libraries that needs to be linked together with `libmonosgen-2.0.a` to produce final application. Static components come in two flavors, the component library, and a stub library. Linking the component library will enable the component in final application, while linking the stub library disables the component. Depending on linked component flavors it is possible to create a build that enables specific components while disabling others. All components needs to be linked in (using component or stub library) or there will be unresolved symbols in `libmonosgen-2.0.a`.
iOS is built using static component support, meaning that components are included as static libraries that needs to be linked together with `libmonosgen-2.0.a` to produce final application. Static components come in two flavors, the component library, and a stub library. Linking the component library will enable the component in final application, while linking the stub library disables the component. Depending on linked component flavors it is possible to create a build that enables specific components while disabling others. All components needs to be linked in (using component or stub library) or there will be unresolved symbols in `libmonosgen-2.0.a`.

If `AppleAppBuilderTask` is used, there is a msbuild property, `RuntimeComponents` that can be used to include specific components in the build application. By default, its empty, meaning all components will be disabled, using a `*` will enabled all components and by specify individual components, only those will be enabled. Enabling tracing would look like this, `RuntimeComponents="diagnostics_tracing"`, more components can be enabled by separating them with `;`.
iOS runtime pack has the following runtime components included: `debugger`, `hot_reload`, `diagnostics_tracing`, `marshal-ilgen`.

iOS runtime pack have the following component libraries included. Using `libmono-component-*-stub-static.a` library will disable the component, using `libmono-component-*-static.a` will enable it.
Using `libmono-component-*-stub-static.a` library will disable the component, using `libmono-component-*-static.a` will enable it.

```
libmono-component-diagnostics_tracing-static.a
Expand All @@ -60,6 +62,39 @@ libmono-component-diagnostics_tracing-stub-static.a

NOTE, running on iOS simulator offers some additional capabilities, so runtime pack for iOS includes shared as well as static library builds, like the Android use case described above.

In order to enable the `diagnostic tracing` runtime component in your build, please take a look at [Enabling runtime components](#enabling-runtime-components) section.

### Enabling runtime components

When using `AndroidAppBuilderTask` to target `Android`, or `AppleAppBuilderTask` to target `iOS` platforms, there is a MSBuild item: `RuntimeComponents` that can be used to include specific components in the generated application. By default, its empty, meaning all components will be disabled.
To enable a single component (eg: `diagnostic tracing`), by adding the following to your project file:
```xml
<ItemGroup>
<RuntimeComponents Include="diagnostics_tracing" />
</ItemGroup>
```
will enable only that runtime component.

On the other hand, if it is desired to include all components, there are two options:
1. Manually, include all supported components manually via:
```xml
<ItemGroup>
<RuntimeComponents Include="debugger" />
<RuntimeComponents Include="hot_reload" />
<RuntimeComponents Include="diagnostics_tracing" />
<RuntimeComponents Include="marshal-ilgen" />
</ItemGroup>
```
2. Automatically, use provided MSBuild property that includes all the supported components for you, in the following way:
- Import `AndroidBuild.props/targets` in your project file (the file can be found [here](../../../src/mono/msbuild/android/build/AndroidBuild.targets))
- Set `UseAllRuntimeComponents` MSBuild property to `true` via:
- By adding: `-p:UseAllRuntimeComponents=true` to your build command, or
- By adding the following in your project file:
```xml
<PropertyGroup>
<UseAllRuntimeComponents>true</UseAllRuntimeComponents>
</PropertyGroup>
```
## Install diagnostic client tooling

```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
<TestRuntime>true</TestRuntime>
<IncludeRemoteExecutor>true</IncludeRemoteExecutor>
</PropertyGroup>
<PropertyGroup>
<RuntimeComponents Condition="'$(TargetsAppleMobile)' == 'true' or '$(TargetOS)' == 'android'">diagnostics_tracing;marshal-ilgen</RuntimeComponents>
</PropertyGroup>
<ItemGroup Condition="'$(TargetsAppleMobile)' == 'true' or '$(TargetOS)' == 'android'">
<RuntimeComponents Include="diagnostics_tracing" />
<RuntimeComponents Include="marshal-ilgen" />
</ItemGroup>
<!-- Windows only files -->
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'windows'">
<Compile Include="BasicEventSourceTest\Harness\EtwListener.cs" />
Expand Down
3 changes: 3 additions & 0 deletions src/libraries/sendtohelix-mobile.targets
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
<_XHarnessAppleCustomCommand Condition="'$(NeedsiOSSDK)' == 'true'">
source build-apple-app.sh
</_XHarnessAppleCustomCommand>
<_RuntimeComponentManifestDir>$([MSBuild]::NormalizeDirectory('$(MonoArtifactsPath)', 'build'))</_RuntimeComponentManifestDir>
</PropertyGroup>

<ItemGroup Condition="'$(NeedsiOSSDK)' == 'true'">
Expand All @@ -66,6 +67,8 @@
<HelixCorrelationPayload Include="$(MonoAOTCompilerDir)" Condition="'$(RuntimeFlavor)' == 'mono'"
Destination="build/MonoAOTCompiler" />
<HelixCorrelationPayload Include="$(MicrosoftNetCoreAppRuntimePackDir)" Destination="build/microsoft.netcore.app.runtime.$(TargetOS)-$(TargetArchitecture.ToLower())" />
<HelixCorrelationPayload Include="$(_RuntimeComponentManifestDir)" Condition="'$(RuntimeFlavor)' == 'mono'"
Destination="build/microsoft.netcore.app.runtime.$(TargetOS)-$(TargetArchitecture.ToLower())/runtimes/$(TargetOS)-$(TargetArchitecture.ToLower())/build" />
<HelixCorrelationPayload Include="$(iOSLikeBuildTargetsDir)" Destination="build/apple" />
<HelixCorrelationPayload Include="$(iOSLikeLibraryBuilderTargetsDir)" Destination="build/common" />
<HelixCorrelationPayload Include="$(MonoAotCrossDir)" Condition="'$(RuntimeFlavor)' == 'mono'"
Expand Down
8 changes: 8 additions & 0 deletions src/mono/msbuild/android/build/AndroidBuild.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
<_HostOS Condition="'$(_HostOS)' == ''">linux</_HostOS>

<_IsLibraryMode Condition="'$(UseNativeAOTRuntime)' != 'true' and '$(NativeLib)' != ''">true</_IsLibraryMode>
<_ReadRuntimeComponentsManifestTargetName Condition="'$(UseNativeAOTRuntime)' != 'true'">_MonoReadAvailableComponentsManifest</_ReadRuntimeComponentsManifestTargetName>

<AndroidBuildAfterThisTarget Condition="'$(AndroidBuildAfterThisTarget)' == ''">Publish</AndroidBuildAfterThisTarget>
<AndroidBuildDependsOn>
$(_ReadRuntimeComponentsManifestTargetName);
_InitializeCommonProperties;
_BeforeAndroidBuild;
_AndroidResolveReferences;
Expand All @@ -21,5 +23,11 @@
_AndroidGenerateAppBundle;
_AfterAndroidBuild
</AndroidBuildDependsOn>

<!-- When building on Helix $(_CommonTargetsDir) will be properly set, otherwise we have to set it to a in-tree location -->
<_CommonTargetsDir Condition="'$(_CommonTargetsDir)' == ''">$([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), '..', '..', 'common'))</_CommonTargetsDir>
</PropertyGroup>

<Import Condition="'$(UseNativeAOTRuntime)' != 'true'" Project="$(_CommonTargetsDir)CommonMobileBuild.props" />
<Import Condition="'$(UseNativeAOTRuntime)' != 'true'" Project="$(_CommonTargetsDir)RuntimeComponentManifest.targets" />
</Project>
39 changes: 13 additions & 26 deletions src/mono/msbuild/android/build/AndroidBuild.targets
Original file line number Diff line number Diff line change
Expand Up @@ -41,40 +41,27 @@
<_MonoHeaderPath>$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'include', 'mono-2.0'))</_MonoHeaderPath>
</PropertyGroup>

<!-- Make sure marshal-ilgen is included in the components list. -->
<ItemGroup Condition="'$(RuntimeComponents)' != '*'">
<_RuntimeComponentList Include="$(RuntimeComponents)" />
<_RuntimeComponentList Include="marshal-ilgen" KeepDuplicates="false"/>
<ItemGroup Condition="'$(UseNativeAOTRuntime)' != 'true'">
<RuntimeComponents Condition="'$(UseAllRuntimeComponents)' == 'true'" Include="@(_MonoRuntimeAvailableComponents)" />
<!-- Make sure marshal-ilgen is included in the components list. -->
<RuntimeComponents Condition="'$(UseAllRuntimeComponents)' != 'true'" Include="marshal-ilgen" KeepDuplicates="false" />
</ItemGroup>

<PropertyGroup Condition="'$(RuntimeComponents)' != '*'">
<RuntimeComponents>@(_RuntimeComponentList)</RuntimeComponents>
</PropertyGroup>

<ItemGroup Condition="'$(_IsLibraryMode)' == 'true'">
<_CommonLinkerArgs Include="-l:libz.so" />
<_CommonLinkerArgs Include="-l:liblog.so" />
<_CommonLinkerArgs Include="-l:libc.so" />
<_CommonLinkerArgs Include="-l:libm.so" />
<_CommonLinkerArgs Include="--build-id=sha1" />

<!-- add all non stub libs first -->
<!-- if RuntimeComponents is empty, exclude -static.a and include -stub-static.a instead -->
<!-- if RuntimeComponents is *, we're ok because all -static.a is included -->
<!-- if RuntimeComponents is a list, add to items and only pull in -static.a -->

<_UsedComponents
Condition="'$(RuntimeComponents)' != '' and '$(RuntimeComponents)' != '*'"
Include="$(RuntimeComponents)" />

<_RuntimeLibraries
Include="$(AndroidBuildDir)\*-stub-static.a" />
<_RuntimeLibraries
Include="$(AndroidBuildDir)\*.a"
Exclude="$(AndroidBuildDir)\*-static.a" />

<_RuntimeLibraries Remove="$(AndroidBuildDir)\libmono-component-%(_UsedComponents.Identity)-stub-static.a" />
<_RuntimeLibraries Include="$(AndroidBuildDir)\libmono-component-%(_UsedComponents.Identity)-static.a" />
<!-- include all libraries except components -->
<_RuntimeLibraries Include="$(AndroidBuildDir)\*.a" Exclude="$(AndroidBuildDir)\libmono-component-*.a" />
<!-- include all component stub libraries -->
<_RuntimeLibraries Include="$(AndroidBuildDir)\libmono-component-*-stub-static.a" />
<!-- if RuntimeComponents is not empty, remove stubs for the required components and include the actual component library -->
<_RuntimeLibraries Condition="'@(RuntimeComponents)' != ''" Remove="$(AndroidBuildDir)\libmono-component-%(RuntimeComponents.Identity)-stub-static.a" />
<_RuntimeLibraries Condition="'@(RuntimeComponents)' != ''" Include="$(AndroidBuildDir)\libmono-component-%(RuntimeComponents.Identity)-static.a" />
<!-- if RuntimeComponents is empty, do nothing as we already included all the component stubs above -->
</ItemGroup>
</Target>

Expand Down Expand Up @@ -283,7 +270,7 @@
NativeDependencies="@(_NativeDependencies)"
OutputDir="$(AndroidBundleDir)"
ProjectName="$(AssemblyName)"
RuntimeComponents="$(RuntimeComponents)"
RuntimeComponents="@(RuntimeComponents)"
RuntimeIdentifier="$(RuntimeIdentifier)"
StripDebugSymbols="False">
<Output TaskParameter="ApkBundlePath" PropertyName="ApkBundlePath" />
Expand Down
4 changes: 3 additions & 1 deletion src/mono/msbuild/apple/build/AppleBuild.LocalBuild.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
$(AppleBuildSupportDir) - directory which has all the tasks, targets, and runtimepack
-->
<Project>
<Import Project="$(MSBuildThisFileDirectory)AppleBuild.props" />

<PropertyGroup>
<!-- Keep these underscored targets in sync with the root Directory.Build.props -->
Expand Down Expand Up @@ -84,4 +83,7 @@
<MonoTargetsTasksAssemblyPath>$([MSBuild]::NormalizePath('$(MonoTargetsTasksDir)', 'MonoTargetsTasks.dll'))</MonoTargetsTasksAssemblyPath>
</PropertyGroup>

<!-- Due to dependencies on resolving properties like: $(MicrosoftNetCoreAppRuntimePackRidDir) we need to import the default props at the end -->
<Import Project="$(MSBuildThisFileDirectory)AppleBuild.props" />

</Project>
8 changes: 8 additions & 0 deletions src/mono/msbuild/apple/build/AppleBuild.props
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@
<_AotCompileTargetName Condition="'$(UseNativeAOTRuntime)' == 'true'">_AppleNativeAotCompile</_AotCompileTargetName>
<_AotCompileTargetName Condition="'$(UseNativeAOTRuntime)' != 'true'">_AppleAotCompile</_AotCompileTargetName>
<IlcCompileDependsOn>ComputeIlcCompileInputs;SetupOSSpecificProps;PrepareForILLink</IlcCompileDependsOn>
<_ReadRuntimeComponentsManifestTargetName Condition="'$(UseNativeAOTRuntime)' != 'true'">_MonoReadAvailableComponentsManifest</_ReadRuntimeComponentsManifestTargetName>

<AppleBuildAfterThisTarget Condition="'$(AppleBuildAfterThisTarget)' == ''">Publish</AppleBuildAfterThisTarget>
<AppleBuildDependsOn>
$(_ReadRuntimeComponentsManifestTargetName);
_InitializeCommonProperties;
_BeforeAppleBuild;
_AppleResolveReferences;
Expand All @@ -37,5 +39,11 @@
_AppleGenerateAppBundle;
_AfterAppleBuild
</AppleBuildDependsOn>

<!-- When building on Helix $(_CommonTargetsDir) will be properly set, otherwise we have to set it to a in-tree location -->
<_CommonTargetsDir Condition="'$(_CommonTargetsDir)' == ''">$([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), '..', '..', 'common'))</_CommonTargetsDir>
</PropertyGroup>

<Import Condition="'$(UseNativeAOTRuntime)' != 'true'" Project="$(_CommonTargetsDir)CommonMobileBuild.props" />
<Import Condition="'$(UseNativeAOTRuntime)' != 'true'" Project="$(_CommonTargetsDir)RuntimeComponentManifest.targets" />
</Project>
Loading

0 comments on commit f16e8bd

Please sign in to comment.