mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-09 17:44:48 +09:00
[Android] Introduce NetTraceToMibcConverter task & streamline testing targets (#72394)
NetTraceToMibcConverter - Used in profiled AOT scenarios where a .nettrace file is given as input and is converted to a .mibc file that can be fed into the AOT compiler. This previously was in the AotCompiler task, but for clarity purposes is now separated out. Streamline Android testing targets - The testing targets function the same, but are now structured similarly to iOS and Wasm. - Introduced new testing properties to support profiled AOT: NetTraceFilePath - The path to a .nettrace file that will be converted into a .mibc file and fed into the aot compiler RuntimeComponents - The list of native components to include in the test app build (diagnostics_tracing) DiagnosticsPorts - The ip address:port where the runtime will listen when running diagnostic tooling DiagnosticStartupMode - The mode the runtime will use at startup for diagnostic scenarios. Suspend will halt the app very early and wait, while nosuspend will wait for a connection, but not halt the runtime Co-authored-by: Mitchell Hwang <16830051+mdh1418@users.noreply.github.com>
This commit is contained in:
parent
c8e6d67eee
commit
209c040d26
20 changed files with 626 additions and 351 deletions
|
@ -115,7 +115,8 @@
|
|||
<MonoAOTCompilerTasksAssemblyPath>$([MSBuild]::NormalizePath('$(MonoAOTCompilerDir)', 'MonoAOTCompiler.dll'))</MonoAOTCompilerTasksAssemblyPath>
|
||||
<MonoTargetsTasksAssemblyPath>$([MSBuild]::NormalizePath('$(MonoTargetsTasksDir)', 'MonoTargetsTasks.dll'))</MonoTargetsTasksAssemblyPath>
|
||||
<TestExclusionListTasksAssemblyPath>$([MSBuild]::NormalizePath('$(TestExclusionListTasksDir)', 'TestExclusionListTasks.dll'))</TestExclusionListTasksAssemblyPath>
|
||||
<ILAsmToolPath Condition="'$(DotNetBuildFromSource)' == 'true' or '$(BuildArchitecture)' == 's390x' or '$(BuildArchitecture)' == 'ppc64le'">$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'coreclr', '$(TargetOS).$(TargetArchitecture).$(Configuration)'))</ILAsmToolPath>
|
||||
<CoreCLRToolPath>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'coreclr', '$(TargetOS).$(TargetArchitecture).$(Configuration)'))</CoreCLRToolPath>
|
||||
<ILAsmToolPath Condition="'$(DotNetBuildFromSource)' == 'true' or '$(BuildArchitecture)' == 's390x' or '$(BuildArchitecture)' == 'ppc64le'">$(CoreCLRToolPath)</ILAsmToolPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="CalculateConfiguration">
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<DefaultMonoSubsets Condition="'$(MonoAOTEnableLLVM)' == 'true' and '$(MonoAOTLLVMDir)' == ''">mono.llvm+</DefaultMonoSubsets>
|
||||
<DefaultMonoSubsets Condition="'$(TargetOS)' == 'Browser'">$(DefaultMonoSubsets)mono.wasmruntime+</DefaultMonoSubsets>
|
||||
<DefaultMonoSubsets Condition="'$(MonoCrossAOTTargetOS)' != ''">$(DefaultMonoSubsets)mono.aotcross+</DefaultMonoSubsets>
|
||||
<DefaultMonoSubsets>$(DefaultMonoSubsets)mono.runtime+mono.corelib+mono.packages+</DefaultMonoSubsets>
|
||||
<DefaultMonoSubsets>$(DefaultMonoSubsets)mono.runtime+mono.corelib+mono.packages+mono.tools+</DefaultMonoSubsets>
|
||||
<DefaultMonoSubsets Condition="'$(TargetsMobile)' != 'true'">$(DefaultMonoSubsets)host+</DefaultMonoSubsets>
|
||||
|
||||
<DefaultLibrariesSubsets Condition="'$(BuildTargetFramework)' == '$(NetCoreAppCurrent)' or
|
||||
|
@ -136,6 +136,7 @@
|
|||
<SubsetName Include="Mono.AotCross" Description="The cross-compiler runtime for Mono AOT." />
|
||||
<SubsetName Include="Mono.CoreLib" Description="The managed System.Private.CoreLib library for Mono." />
|
||||
<SubsetName Include="Mono.Packages" Description="The projects that produce NuGet packages for the Mono runtime." />
|
||||
<SubsetName Include="Mono.Tools" Description="Tooling that helps support Mono development and testing." />
|
||||
<SubsetName Include="Mono.WasmRuntime" Description="The WebAssembly runtime." />
|
||||
<SubsetName Include="Mono.MsCorDbi" Description="The implementation of ICorDebug interface." />
|
||||
<SubsetName Include="Mono.Workloads" OnDemand="true" Description="Builds the installers and the insertion metadata for Blazor workloads." />
|
||||
|
@ -358,6 +359,10 @@
|
|||
<ProjectToBuild Include="$(MonoProjectRoot)System.Private.CoreLib\System.Private.CoreLib.csproj" Category="mono" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="$(_subset.Contains('+mono.tools+'))">
|
||||
<ProjectToBuild Include="$(CoreClrProjectRoot)tools\dotnet-pgo\dotnet-pgo.csproj;" Category="mono" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="$(_subset.Contains('+mono.workloads+'))">
|
||||
<ProjectToBuild Include="$(WorkloadsProjectRoot)\workloads.csproj" Category="mono" />
|
||||
</ItemGroup>
|
||||
|
|
74
eng/testing/tests.android.targets
Normal file
74
eng/testing/tests.android.targets
Normal file
|
@ -0,0 +1,74 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<BundleTestAppTargets>$(BundleTestAppTargets);BundleTestAndroidApp</BundleTestAppTargets>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$(MonoProjectRoot)\msbuild\android\build\AndroidApp.props" />
|
||||
<Import Project="$(MonoProjectRoot)\msbuild\android\build\AndroidApp.InTree.targets" />
|
||||
|
||||
<PropertyGroup>
|
||||
<AndroidBuildAppDependsOn>PrepareForAndroidBuildApp;$(AndroidBuildAppDependsOn);_CopyTestArchive</AndroidBuildAppDependsOn>
|
||||
|
||||
<BundleTestAndroidAppDependsOn>AndroidBuildApp</BundleTestAndroidAppDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Target that kicks off the whole test build and run flow -->
|
||||
<Target Name="BundleTestAndroidApp" DependsOnTargets="$(BundleTestAndroidAppDependsOn)" />
|
||||
|
||||
<Target Name="PrepareForAndroidBuildApp">
|
||||
<Error Condition="!Exists('$(MicrosoftNetCoreAppRuntimePackRidDir)')" Text="MicrosoftNetCoreAppRuntimePackRidDir=$(MicrosoftNetCoreAppRuntimePackRidDir) doesn't exist" />
|
||||
|
||||
<WriteLinesToFile File="$(PublishDir)xunit-excludes.txt" Lines="$(XunitExcludesTxtFileContent)" Overwrite="true" />
|
||||
|
||||
<PropertyGroup>
|
||||
<MainLibraryFileName Condition="'$(MainLibraryFileName)' == ''">AndroidTestRunner.dll</MainLibraryFileName>
|
||||
|
||||
<AndroidAppDir>$(PublishDir)</AndroidAppDir>
|
||||
<AndroidAppBundleDir>$(BundleDir)</AndroidAppBundleDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AndroidEnv Condition="'$(XUnitSingleThreadedMode)' == 'true'" Include="XUNIT_SINGLE_THREADED">
|
||||
<Value>1</Value>
|
||||
</AndroidEnv>
|
||||
<AndroidEnv Condition="'$(XUnitUseRandomizedTestOrderer)' == 'true'" Include="XUNIT_RANDOM_ORDER_SEED">
|
||||
<Value>1883302047</Value>
|
||||
</AndroidEnv>
|
||||
<AndroidEnv Condition="'$(XUnitSingleThreadedMode)' == 'true'" Include="XUNIT_VERBOSE">
|
||||
<Value>1</Value>
|
||||
</AndroidEnv>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AndroidAssembliesToBundle Include="@(NativeLibraries->'$(PublishDir)%(Identity)')">
|
||||
<_InternalForceInterpret>true</_InternalForceInterpret>
|
||||
<_IsNative>true</_IsNative>
|
||||
</AndroidAssembliesToBundle>
|
||||
|
||||
<_PublishAssemblies Include="$(PublishDir)\**\*.dll" Exclude="$(PublishDir)\**\*.resources.dll" />
|
||||
<_SatelliteAssemblies Include="$(PublishDir)\**\*.resources.dll" />
|
||||
|
||||
<AndroidAssembliesToBundle Include="@(_PublishAssemblies)">
|
||||
<_InternalForceInterpret Condition="'$(UseMonoJustInterp)' == 'true' and '%(FileName)%(Extension)' != 'System.Private.CoreLib.dll'">true</_InternalForceInterpret>
|
||||
<_IsNative>false</_IsNative>
|
||||
</AndroidAssembliesToBundle>
|
||||
|
||||
<AndroidNativeFilesToBundle Include="$(PublishDir)\**\*.*" Exclude="$(PublishDir)\*.dll" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_CopyTestArchive"
|
||||
Condition="'$(ArchiveTests)' == 'true' and '$(IgnoreForCI)' != 'true'">
|
||||
<Error Condition="'$(TestArchiveTestsDir)' == ''" Text="TestArchiveTestsDir property to archive the test folder must be set." />
|
||||
|
||||
<Message Importance="High" Text="PackageId: $(ApkPackageId)"/>
|
||||
<Message Importance="High" Text="Instrumentation: net.dot.MonoRunner"/>
|
||||
<Message Importance="High" Text="Apk: $(ApkBundlePath)"/>
|
||||
|
||||
<Copy SourceFiles="$(ApkBundlePath)"
|
||||
DestinationFolder="$(TestArchiveTestsDir)"
|
||||
SkipUnchangedFiles="true"
|
||||
Condition="'$(ArchiveTests)' == 'true' and '$(IgnoreForCI)' != 'true'" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
|
@ -8,7 +8,6 @@
|
|||
<RunScriptOutputPath>$([MSBuild]::NormalizePath('$(BundleDir)', '$(RunScriptOutputName)'))</RunScriptOutputPath>
|
||||
|
||||
<PublishingTestsRun>true</PublishingTestsRun>
|
||||
<BundleTestAppTargets>BundleTestAndroidApp</BundleTestAppTargets>
|
||||
<PublishTestAsSelfContainedDependsOn>Publish</PublishTestAsSelfContainedDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -16,6 +15,11 @@
|
|||
<RunAOTCompilation Condition="'$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'tvOS'">true</RunAOTCompilation>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<DotnetPgoToolDir>$([MSBuild]::NormalizeDirectory('$(CoreCLRToolPath)', 'dotnet-pgo'))</DotnetPgoToolDir>
|
||||
<DotnetPgoToolPath>$([MSBuild]::NormalizePath('$(DotnetPgoToolDir)', 'dotnet-pgo'))</DotnetPgoToolPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(EnableAggressiveTrimming)' == 'true' or '$(EnableSoftTrimming)' == 'true'">
|
||||
<PublishTrimmed>true</PublishTrimmed>
|
||||
<!-- Suppress linker warnings as these are tests -->
|
||||
|
@ -39,6 +43,10 @@
|
|||
<AdditionalXHarnessArguments Condition="'$(ExpectedExitCode)' != ''">$(AdditionalXHarnessArguments) --expected-exit-code $(ExpectedExitCode)</AdditionalXHarnessArguments>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<DiagnosticPorts Condition="'$(DiagnosticStartupMode)' != ''">$(DiagnosticPorts),$(DiagnosticStartupMode)</DiagnosticPorts>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(TargetOS)' == 'Android'">
|
||||
<!-- The -arg flag for xharness passes the arguments along to the instrumentation app -->
|
||||
<AdditionalXHarnessArguments Condition="'$(XUnitMethodName)' != ''">$(AdditionalXHarnessArguments) --arg=-m=$(XUnitMethodName)</AdditionalXHarnessArguments>
|
||||
|
@ -55,9 +63,8 @@
|
|||
<Compile Include="$(RepoRoot)src\libraries\Common\tests\Tests\RandomizedTestOrderAssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<UsingTask Condition="'$(RunAOTCompilation)' == 'true'" TaskName="MonoAOTCompiler" AssemblyFile="$(MonoAOTCompilerTasksAssemblyPath)" />
|
||||
<Import Condition="'$(RunAOTCompilation)' == 'true'" Project="$(MonoAOTCompilerDir)MonoAOTCompiler.props" />
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)tests.android.targets"
|
||||
Condition="'$(TargetOS)' == 'Android'" />
|
||||
<Import Project="$(MSBuildThisFileDirectory)tests.ioslike.targets"
|
||||
Condition="'$(TargetsAppleMobile)' == 'true'" />
|
||||
<Import Project="$(MSBuildThisFileDirectory)tests.wasm.targets"
|
||||
|
@ -67,115 +74,6 @@
|
|||
<_MobileIntermediateOutputPath>$(IntermediateOutputPath)mobile</_MobileIntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<UsingTask TaskName="RuntimeConfigParserTask"
|
||||
AssemblyFile="$(MonoTargetsTasksAssemblyPath)"
|
||||
Condition="'$(MonoTargetsTasksAssemblyPath)' != ''" />
|
||||
|
||||
<Target Name="GenerateRuntimeConfig" Condition="'$(TargetOS)' != 'Browser'"
|
||||
Inputs="$(PublishDir)$(AssemblyName).runtimeconfig.json"
|
||||
Outputs="$(PublishDir)runtimeconfig.bin">
|
||||
<PropertyGroup>
|
||||
<RuntimeConfigFilePath>$(PublishDir)$(AssemblyName).runtimeconfig.json</RuntimeConfigFilePath>
|
||||
<ParsedRuntimeConfigFilePath>$(PublishDir)runtimeconfig.bin</ParsedRuntimeConfigFilePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<RuntimeConfigReservedProperties Include="RUNTIME_IDENTIFIER"/>
|
||||
<RuntimeConfigReservedProperties Include="APP_CONTEXT_BASE_DIRECTORY"/>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Parse runtimeconfig.template.json file -->
|
||||
<RuntimeConfigParserTask
|
||||
RuntimeConfigFile="$(RuntimeConfigFilePath)"
|
||||
OutputFile="$(ParsedRuntimeConfigFilePath)"
|
||||
RuntimeConfigReservedProperties="@(RuntimeConfigReservedProperties)">
|
||||
</RuntimeConfigParserTask>
|
||||
</Target>
|
||||
|
||||
<!-- Generate a self-contained app bundle for Android with tests. -->
|
||||
<UsingTask Condition="'$(TargetOS)' == 'Android'"
|
||||
TaskName="AndroidAppBuilderTask"
|
||||
AssemblyFile="$(AndroidAppBuilderTasksAssemblyPath)" />
|
||||
|
||||
<Target Condition="'$(TargetOS)' == 'Android'" Name="BundleTestAndroidApp" DependsOnTargets="GenerateRuntimeConfig">
|
||||
<Error Condition="!Exists('$(MicrosoftNetCoreAppRuntimePackRidDir)')" Text="MicrosoftNetCoreAppRuntimePackRidDir=$(MicrosoftNetCoreAppRuntimePackRidDir) doesn't exist" />
|
||||
|
||||
<PropertyGroup>
|
||||
<AndroidAbi Condition="'$(TargetArchitecture)' == 'arm64'">arm64-v8a</AndroidAbi>
|
||||
<AndroidAbi Condition="'$(TargetArchitecture)' == 'arm'">armeabi-v7a</AndroidAbi>
|
||||
<AndroidAbi Condition="'$(TargetArchitecture)' == 'x64'">x86_64</AndroidAbi>
|
||||
<AndroidAbi Condition="'$(TargetArchitecture)' == 'x86'">x86</AndroidAbi>
|
||||
|
||||
<MainLibraryFileName Condition="'$(MainLibraryFileName)' == ''">AndroidTestRunner.dll</MainLibraryFileName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_AndroidEnv Condition="'$(XUnitSingleThreadedMode)' == 'true'" Include="XUNIT_SINGLE_THREADED">
|
||||
<Value>1</Value>
|
||||
</_AndroidEnv>
|
||||
<_AndroidEnv Condition="'$(XUnitUseRandomizedTestOrderer)' == 'true'" Include="XUNIT_RANDOM_ORDER_SEED">
|
||||
<Value>1883302047</Value>
|
||||
</_AndroidEnv>
|
||||
<_AndroidEnv Condition="'$(XUnitSingleThreadedMode)' == 'true'" Include="XUNIT_VERBOSE">
|
||||
<Value>1</Value>
|
||||
</_AndroidEnv>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(RunAOTCompilation)' == 'true'">
|
||||
<AotInputAssemblies Include="$(PublishDir)\*.dll">
|
||||
<AotArguments>@(MonoAOTCompilerDefaultAotArguments, ';')</AotArguments>
|
||||
<ProcessArguments>@(MonoAOTCompilerDefaultProcessArguments, ';')</ProcessArguments>
|
||||
</AotInputAssemblies>
|
||||
</ItemGroup>
|
||||
|
||||
<WriteLinesToFile File="$(PublishDir)xunit-excludes.txt" Lines="$(XunitExcludesTxtFileContent)" Overwrite="true" />
|
||||
|
||||
<MakeDir Directories="$(_MobileIntermediateOutputPath)"
|
||||
Condition="'$(RunAOTCompilation)' == 'true'"/>
|
||||
<RemoveDir Directories="$(BundleDir)" />
|
||||
|
||||
<MonoAOTCompiler Condition="'$(RunAOTCompilation)' == 'true'"
|
||||
CompilerBinaryPath="@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','$(TargetOS.ToLowerInvariant())-$(TargetArchitecture.ToLowerInvariant())'))"
|
||||
OutputDir="$(_MobileIntermediateOutputPath)"
|
||||
Mode="Full"
|
||||
OutputType="AsmOnly"
|
||||
Assemblies="@(AotInputAssemblies)"
|
||||
AotModulesTablePath="$(BundleDir)\modules.c"
|
||||
IntermediateOutputPath="$(IntermediateOutputPath)"
|
||||
UseLLVM="$(MonoEnableLLVM)"
|
||||
LLVMPath="$(MonoAotCrossDir)">
|
||||
<Output TaskParameter="CompiledAssemblies" ItemName="BundleAssemblies" />
|
||||
</MonoAOTCompiler>
|
||||
|
||||
<AndroidAppBuilderTask
|
||||
RuntimeIdentifier="$(RuntimeIdentifier)"
|
||||
ProjectName="$(AssemblyName)"
|
||||
MonoRuntimeHeaders="$(MicrosoftNetCoreAppRuntimePackNativeDir)include\mono-2.0"
|
||||
Assemblies="@(BundleAssemblies)"
|
||||
MainLibraryFileName="$(MainLibraryFileName)"
|
||||
IncludeNetworkSecurityConfig="$(IncludeNetworkSecurityConfig)"
|
||||
EnvironmentVariables="@(_AndroidEnv)"
|
||||
ForceAOT="$(RunAOTCompilation)"
|
||||
ForceInterpreter="$(MonoForceInterpreter)"
|
||||
RuntimeComponents="$(RuntimeComponents)"
|
||||
DiagnosticPorts="$(DiagnosticPorts)"
|
||||
StripDebugSymbols="False"
|
||||
OutputDir="$(BundleDir)"
|
||||
AppDir="$(PublishDir)">
|
||||
<Output TaskParameter="ApkPackageId" PropertyName="ApkPackageId" />
|
||||
<Output TaskParameter="ApkBundlePath" PropertyName="ApkBundlePath" />
|
||||
</AndroidAppBuilderTask>
|
||||
|
||||
<Message Importance="High" Text="PackageId: $(ApkPackageId)"/>
|
||||
<Message Importance="High" Text="Instrumentation: net.dot.MonoRunner"/>
|
||||
<Message Importance="High" Text="Apk: $(ApkBundlePath)"/>
|
||||
|
||||
<Copy SourceFiles="$(ApkBundlePath)"
|
||||
DestinationFolder="$(TestArchiveTestsDir)"
|
||||
SkipUnchangedFiles="true"
|
||||
Condition="'$(ArchiveTests)' == 'true' and '$(IgnoreForCI)' != 'true'" />
|
||||
</Target>
|
||||
|
||||
<!-- This .targets file is also imported by the runtime Trimming tests, and we want to be able to manually configure trimming in them so this
|
||||
should be considered if we ever want to change the Condition of the ConfigureTrimming target -->
|
||||
<Target Name="ConfigureTrimming" Condition="('$(EnableAggressiveTrimming)' == 'true' or '$(EnableSoftTrimming)' == 'true') And '$(SkipConfigureTrimming)' != 'true'" AfterTargets="AddTestRunnersToPublishedFiles">
|
||||
|
|
13
src/mono/msbuild/android/build/AndroidApp.InTree.props
Normal file
13
src/mono/msbuild/android/build/AndroidApp.InTree.props
Normal file
|
@ -0,0 +1,13 @@
|
|||
<Project>
|
||||
<!-- This depends on the root Directory.Build.props imported this file -->
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)AndroidApp.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
|
||||
<EnableTargetingPackDownload>false</EnableTargetingPackDownload>
|
||||
<EnableRuntimePackDownload>false</EnableRuntimePackDownload>
|
||||
<PublishTrimmed>true</PublishTrimmed>
|
||||
<TrimMode>link</TrimMode>
|
||||
<RunAnalyzers>false</RunAnalyzers>
|
||||
</PropertyGroup>
|
||||
</Project>
|
21
src/mono/msbuild/android/build/AndroidApp.InTree.targets
Normal file
21
src/mono/msbuild/android/build/AndroidApp.InTree.targets
Normal file
|
@ -0,0 +1,21 @@
|
|||
<Project>
|
||||
<!-- This depends on the root Directory.Build.targets imported this file -->
|
||||
<UsingTask TaskName="MonoAOTCompiler" AssemblyFile="$(MonoAOTCompilerTasksAssemblyPath)" />
|
||||
<UsingTask TaskName="NetTraceToMibcConverter" AssemblyFile="$(MonoTargetsTasksAssemblyPath)" />
|
||||
<UsingTask TaskName="RuntimeConfigParserTask" AssemblyFile="$(MonoTargetsTasksAssemblyPath)" />
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)AndroidApp.targets" />
|
||||
|
||||
<!-- Use local runtime pack -->
|
||||
<Target Name="UpdateRuntimePack" AfterTargets="ResolveFrameworkReferences">
|
||||
<PropertyGroup>
|
||||
<_LocalMicrosoftNetCoreAppRuntimePackDir>$(MicrosoftNetCoreAppRuntimePackDir)</_LocalMicrosoftNetCoreAppRuntimePackDir>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ResolvedRuntimePack PackageDirectory="$(_LocalMicrosoftNetCoreAppRuntimePackDir)"
|
||||
Condition="'$(_LocalMicrosoftNetCoreAppRuntimePackDir)' != '' and
|
||||
'%(ResolvedRuntimePack.FrameworkName)' == 'Microsoft.NETCore.App'" />
|
||||
</ItemGroup>
|
||||
<Message Text="Used runtime pack: %(ResolvedRuntimePack.PackageDirectory)" Importance="high" />
|
||||
</Target>
|
||||
</Project>
|
18
src/mono/msbuild/android/build/AndroidApp.props
Normal file
18
src/mono/msbuild/android/build/AndroidApp.props
Normal file
|
@ -0,0 +1,18 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<RuntimeIdentifier>$(TargetOS.ToLowerInvariant())-$(TargetArchitecture.ToLowerInvariant())</RuntimeIdentifier>
|
||||
<UseMonoRuntime>true</UseMonoRuntime>
|
||||
<UseMonoJustInterp Condition="'$(RunAOTCompilation)' == 'true' and '$(MonoForceInterpreter)' == 'true'">true</UseMonoJustInterp>
|
||||
|
||||
<AndroidBuildAppAfterThisTarget Condition="'$(AndroidBuildAppAfterThisTarget)' == ''">Publish</AndroidBuildAppAfterThisTarget>
|
||||
<AndroidBuildAppDependsOn>
|
||||
_InitializeCommonProperties;
|
||||
_BeforeAndroidBuildApp;
|
||||
_AndroidResolveReferences;
|
||||
_AndroidPrepareProfiledAot;
|
||||
_AndroidAotCompileApp;
|
||||
_AndroidGenerateAppBundle;
|
||||
_AfterAndroidBuildApp
|
||||
</AndroidBuildAppDependsOn>
|
||||
</PropertyGroup>
|
||||
</Project>
|
168
src/mono/msbuild/android/build/AndroidApp.targets
Normal file
168
src/mono/msbuild/android/build/AndroidApp.targets
Normal file
|
@ -0,0 +1,168 @@
|
|||
<Project>
|
||||
<UsingTask TaskName="AndroidAppBuilderTask"
|
||||
AssemblyFile="$(AndroidAppBuilderTasksAssemblyPath)" />
|
||||
|
||||
<Target Name="AndroidBuildApp" AfterTargets="$(AndroidBuildAppAfterThisTarget)" />
|
||||
|
||||
<Target Name="_AndroidCoreBuild" BeforeTargets="AndroidBuildApp" DependsOnTargets="$(AndroidBuildAppDependsOn)" />
|
||||
|
||||
<Target Name="_InitializeCommonProperties">
|
||||
<Error Condition="'$(IntermediateOutputPath)' == ''" Text="%24(IntermediateOutputPath) property needs to be set" />
|
||||
|
||||
<PropertyGroup>
|
||||
<_MobileIntermediateOutputPath>$([MSBuild]::NormalizeDirectory($(IntermediateOutputPath), 'mobile'))</_MobileIntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_BeforeAndroidBuildApp">
|
||||
<PropertyGroup>
|
||||
<_AndroidRuntimeConfigFilePath Condition="'$(_AndroidRuntimeConfigFilePath)' == ''">$([MSBuild]::NormalizePath($(AndroidAppDir), '$(AssemblyName).runtimeconfig.json'))</_AndroidRuntimeConfigFilePath>
|
||||
<_ParsedRuntimeConfigFilePath Condition="'$(_ParsedRuntimeConfigFilePath)' == ''">$([MSBuild]::NormalizePath($(AndroidAppDir), 'runtimeconfig.bin'))</_ParsedRuntimeConfigFilePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<RemoveDir Directories="$(AndroidAppBundleDir)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_AndroidResolveReferences">
|
||||
<ItemGroup>
|
||||
<_AndroidAssembliesInternal Remove="@(_AndroidAssembliesInternal)" />
|
||||
<_AndroidAssembliesInternal Include="@(AndroidAssembliesToBundle)">
|
||||
<_InternalForceInterpret>%(AndroidAssembliesToBundle._InternalForceInterpret)</_InternalForceInterpret>
|
||||
<_IsNative>%(AndroidAssembliesToBundle._IsNative)</_IsNative>
|
||||
</_AndroidAssembliesInternal>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_AndroidBeforeAotCompileApp">
|
||||
<PropertyGroup>
|
||||
<_AOTMode Condition="'$(UseMonoJustInterp)' != 'true'">Normal</_AOTMode>
|
||||
<_AOTMode Condition="'$(UseMonoJustInterp)' == 'true'">JustInterp</_AOTMode>
|
||||
<_AOTMode Condition="'$(ForceFullAOT)' == 'true'">Full</_AOTMode>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'arm'" Include="mtriple=armv7-linux-gnueabi" />
|
||||
<MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'arm64'" Include="mtriple=aarch64-linux-android" />
|
||||
<MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'x86'" Include="mtriple=i686-linux-android" />
|
||||
<MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'x64'" Include="mtriple=x86_64-linux-android" />
|
||||
|
||||
<MonoAOTCompilerDefaultAotArguments Include="static" />
|
||||
<MonoAOTCompilerDefaultAotArguments Include="dwarfdebug" />
|
||||
|
||||
<MonoAOTCompilerDefaultAotArguments Include="nimt-trampolines=2000" />
|
||||
<MonoAOTCompilerDefaultAotArguments Include="ntrampolines=10000" />
|
||||
<MonoAOTCompilerDefaultAotArguments Include="nrgctx-fetch-trampolines=256" />
|
||||
<MonoAOTCompilerDefaultAotArguments Include="ngsharedvt-trampolines=4400" />
|
||||
<MonoAOTCompilerDefaultAotArguments Include="nftnptr-arg-trampolines=4000" />
|
||||
<MonoAOTCompilerDefaultAotArguments Include="nrgctx-trampolines=31000" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<AotArguments>@(MonoAOTCompilerDefaultAotArguments, ';')</AotArguments>
|
||||
<ProcessArguments>@(MonoAOTCompilerDefaultProcessArguments, ';')</ProcessArguments>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_AotInputAssemblies Include="@(_AndroidAssembliesInternal)"
|
||||
Condition="'%(_AndroidAssembliesInternal._InternalForceInterpret)' != 'true'">
|
||||
<AotArguments>$(AotArguments)</AotArguments>
|
||||
<ProcessArguments>$(ProcessArguments)</ProcessArguments>
|
||||
</_AotInputAssemblies>
|
||||
|
||||
<_AOT_InternalForceInterpretAssemblies Include="@(_AndroidAssembliesInternal->WithMetadataValue('_InternalForceInterpret', 'true'))" />
|
||||
<_AndroidAssembliesInternal Remove="@(_AndroidAssembliesInternal)" />
|
||||
</ItemGroup>
|
||||
|
||||
<MakeDir Directories="$(_MobileIntermediateOutputPath)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_AndroidPrepareProfiledAot"
|
||||
Condition="'$(NetTraceFilePath)' != '' and '$(ForceFullAOT)' != 'true'"
|
||||
DependsOnTargets="_AndroidBeforeAotCompileApp">
|
||||
<PropertyGroup>
|
||||
<_ToolPath>$([System.IO.Path]::GetDirectoryName('$(DotnetPgoToolPath)'))</_ToolPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<NetTraceToMibcConverter
|
||||
ToolPath="$(_ToolPath)"
|
||||
Assemblies="@(_AotInputAssemblies)"
|
||||
NetTraceFilePath="$(NetTraceFilePath)"
|
||||
OutputDir="$(_MobileIntermediateOutputPath)">
|
||||
<Output TaskParameter="MibcFilePath" ItemName="ProfiledAOTProfilePaths" />
|
||||
</NetTraceToMibcConverter>
|
||||
</Target>
|
||||
|
||||
<Target Name="_AndroidAotCompileApp"
|
||||
Condition="'$(RunAOTCompilation)' == 'true'"
|
||||
DependsOnTargets="_AndroidBeforeAotCompileApp">
|
||||
|
||||
<ItemGroup>
|
||||
<ProfiledAOTProfilePaths Include="$(MibcFilePath)" />
|
||||
</ItemGroup>
|
||||
|
||||
<MonoAOTCompiler
|
||||
CompilerBinaryPath="@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','$(TargetOS.ToLowerInvariant())-$(TargetArchitecture.ToLowerInvariant())'))"
|
||||
OutputDir="$(_MobileIntermediateOutputPath)"
|
||||
Mode="$(_AOTMode)"
|
||||
OutputType="AsmOnly"
|
||||
Assemblies="@(_AotInputAssemblies)"
|
||||
AotModulesTablePath="$(AndroidAppBundleDir)\modules.c"
|
||||
IntermediateOutputPath="$(_MobileIntermediateOutputPath)"
|
||||
MibcProfilePath="@(ProfiledAOTProfilePaths)"
|
||||
UseLLVM="$(MonoEnableLLVM)"
|
||||
LLVMPath="$(MonoAotCrossDir)">
|
||||
<Output TaskParameter="CompiledAssemblies" ItemName="_AndroidAssembliesInternal" />
|
||||
</MonoAOTCompiler>
|
||||
|
||||
<ItemGroup>
|
||||
<_AndroidAssembliesInternal Include="@(_AOT_InternalForceInterpretAssemblies)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_AndroidGenerateAppBundle" DependsOnTargets="_AndroidGenerateRuntimeConfig">
|
||||
|
||||
<AndroidAppBuilderTask
|
||||
RuntimeIdentifier="$(RuntimeIdentifier)"
|
||||
ProjectName="$(AssemblyName)"
|
||||
MonoRuntimeHeaders="$(MicrosoftNetCoreAppRuntimePackNativeDir)include\mono-2.0"
|
||||
Assemblies="@(_AndroidAssembliesInternal)"
|
||||
MainLibraryFileName="$(MainLibraryFileName)"
|
||||
IncludeNetworkSecurityConfig="$(IncludeNetworkSecurityConfig)"
|
||||
EnvironmentVariables="@(AndroidEnv)"
|
||||
ForceAOT="$(RunAOTCompilation)"
|
||||
ForceFullAOT="$(ForceFullAOT)"
|
||||
ForceInterpreter="$(MonoForceInterpreter)"
|
||||
StripDebugSymbols="False"
|
||||
RuntimeComponents="$(RuntimeComponents)"
|
||||
DiagnosticPorts="$(DiagnosticPorts)"
|
||||
OutputDir="$(AndroidAppBundleDir)"
|
||||
AppDir="$(AndroidAppDir)">
|
||||
<Output TaskParameter="ApkPackageId" PropertyName="ApkPackageId" />
|
||||
<Output TaskParameter="ApkBundlePath" PropertyName="ApkBundlePath" />
|
||||
</AndroidAppBuilderTask>
|
||||
|
||||
<Message Importance="High" Text="PackageId: $(ApkPackageId)"/>
|
||||
<Message Importance="High" Text="Instrumentation: net.dot.MonoRunner"/>
|
||||
<Message Importance="High" Text="Apk: $(ApkBundlePath)"/>
|
||||
</Target>
|
||||
|
||||
<Target Name="_AfterAndroidBuildApp">
|
||||
|
||||
</Target>
|
||||
|
||||
<Target Name="_AndroidGenerateRuntimeConfig"
|
||||
Inputs="$(_AndroidRuntimeConfigFilePath)"
|
||||
Outputs="$(_ParsedRuntimeConfigFilePath)"
|
||||
Condition="Exists('$(_AndroidRuntimeConfigFilePath)')">
|
||||
<ItemGroup>
|
||||
<_RuntimeConfigReservedProperties Include="RUNTIME_IDENTIFIER"/>
|
||||
<_RuntimeConfigReservedProperties Include="APP_CONTEXT_BASE_DIRECTORY"/>
|
||||
</ItemGroup>
|
||||
|
||||
<RuntimeConfigParserTask
|
||||
RuntimeConfigFile="$(_AndroidRuntimeConfigFilePath)"
|
||||
OutputFile="$(_ParsedRuntimeConfigFilePath)"
|
||||
RuntimeConfigReservedProperties="@(_RuntimeConfigReservedProperties)">
|
||||
</RuntimeConfigParserTask>
|
||||
</Target>
|
||||
</Project>
|
|
@ -24,15 +24,7 @@
|
|||
<_AppleRuntimeConfigFilePath Condition="'$(_AppleRuntimeConfigFilePath)' == ''">$([MSBuild]::NormalizePath($(AppleAppDir), '$(AssemblyName).runtimeconfig.json'))</_AppleRuntimeConfigFilePath>
|
||||
<_ParsedRuntimeConfigFilePath Condition="'$(_ParsedRuntimeConfigFilePath)' == ''">$([MSBuild]::NormalizePath($(AppleAppDir), 'runtimeconfig.bin'))</_ParsedRuntimeConfigFilePath>
|
||||
</PropertyGroup>
|
||||
<!--<AppleAppDir Condition="'$(AppleAppDir)' == ''">$(OutputPath)</AppleAppDir>
|
||||
|
||||
<AppleAppBundleDir Condition="'$(AppleAppBundleDir)' == ''">$([MSBuild]::NormalizeDirectory($(OutputPath), 'AppBundle'))</AppleAppBundleDir>
|
||||
|
||||
<MainLibraryFileName Condition="'$(MainLibraryFileName)' == ''">$(TargetFileName)</MainLibraryFileName>
|
||||
|
||||
<AppleAppDir>$([MSBuild]::NormalizeDirectory($(AppleAppDir)))</AppleAppDir>
|
||||
<AppleAppBundleDir>$([MSBuild]::NormalizeDirectory($(AppleAppBundleDir)))</AppleAppBundleDir>
|
||||
-->
|
||||
<RemoveDir Directories="$(AppleAppBundleDir)" />
|
||||
</Target>
|
||||
|
||||
|
@ -83,11 +75,6 @@
|
|||
|
||||
<ItemGroup>
|
||||
<_AotExcludeAssemblies Include="*System.Runtime.WindowsRuntime.dll" />
|
||||
|
||||
<DebugTestItem Include="@(_AppleAssembliesInternal)">
|
||||
<_InternalForceInterpret>%(_AppleAssembliesInternal._InternalForceInterpret)</_InternalForceInterpret>
|
||||
<_IsNative>%(_AppleAssembliesInternal._IsNative)</_IsNative>
|
||||
</DebugTestItem>
|
||||
|
||||
<_AotInputAssemblies Include="@(_AppleAssembliesInternal)"
|
||||
Condition="'%(_AppleAssembliesInternal._InternalForceInterpret)' != 'true'">
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
<UsingTask TaskName="ILStrip" AssemblyFile="$(MonoTargetsTasksAssemblyPath)" />
|
||||
<!-- RuntimeConfigParser -->
|
||||
<UsingTask TaskName="RuntimeConfigParserTask" AssemblyFile="$(MonoTargetsTasksAssemblyPath)" />
|
||||
<!-- NetTraceToMibcConverter -->
|
||||
<UsingTask TaskName="NetTraceToMibcConverter" AssemblyFile="$(MonoTargetsTasksAssemblyPath)" />
|
||||
<!-- Specific instances of JsonToItemsTaskFactory -->
|
||||
<!-- MonoRuntimeComponentManifestReadTask -->
|
||||
<UsingTask TaskName="MonoRuntimeComponentManifestReadTask" TaskFactory="JsonToItemsTaskFactory.JsonToItemsTaskFactory" AssemblyFile="$(MonoTargetsTasksAssemblyPath)">
|
||||
|
|
|
@ -38,6 +38,11 @@ public class AndroidAppBuilderTask : Task
|
|||
/// </summary>
|
||||
public bool ForceAOT { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if we want to AOT all assemblies or not
|
||||
/// </summary>
|
||||
public bool ForceFullAOT { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Static linked runtime
|
||||
/// </summary>
|
||||
|
@ -111,6 +116,7 @@ public class AndroidAppBuilderTask : Task
|
|||
apkBuilder.KeyStorePath = KeyStorePath;
|
||||
apkBuilder.ForceInterpreter = ForceInterpreter;
|
||||
apkBuilder.ForceAOT = ForceAOT;
|
||||
apkBuilder.ForceFullAOT = ForceFullAOT;
|
||||
apkBuilder.EnvironmentVariables = EnvironmentVariables;
|
||||
apkBuilder.StaticLinkedRuntime = StaticLinkedRuntime;
|
||||
apkBuilder.RuntimeComponents = RuntimeComponents;
|
||||
|
|
|
@ -28,6 +28,7 @@ public class ApkBuilder
|
|||
public string? KeyStorePath { get; set; }
|
||||
public bool ForceInterpreter { get; set; }
|
||||
public bool ForceAOT { get; set; }
|
||||
public bool ForceFullAOT { get; set; }
|
||||
public ITaskItem[] EnvironmentVariables { get; set; } = Array.Empty<ITaskItem>();
|
||||
public bool InvariantGlobalization { get; set; }
|
||||
public bool EnableRuntimeLogging { get; set; }
|
||||
|
@ -342,6 +343,11 @@ public class ApkBuilder
|
|||
}
|
||||
}
|
||||
|
||||
if (ForceFullAOT)
|
||||
{
|
||||
defines.AppendLine("add_definitions(-DFULL_AOT=1)");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(DiagnosticPorts))
|
||||
{
|
||||
defines.AppendLine("add_definitions(-DDIAGNOSTIC_PORTS=\"" + DiagnosticPorts + "\")");
|
||||
|
|
|
@ -273,9 +273,14 @@ mono_droid_runtime_init (const char* executable, int managed_argc, char* managed
|
|||
LOG_INFO("AOT Enabled");
|
||||
#if STATIC_AOT
|
||||
register_aot_modules();
|
||||
#endif
|
||||
#endif // STATIC_AOT
|
||||
|
||||
#if FULL_AOT
|
||||
mono_jit_set_aot_mode(MONO_AOT_MODE_FULL);
|
||||
#endif
|
||||
#else
|
||||
mono_jit_set_aot_mode(MONO_AOT_MODE_NORMAL);
|
||||
#endif // FULL_AOT
|
||||
#endif // FORCE_INTERPRETER
|
||||
|
||||
MonoDomain *domain = mono_jit_init_version ("dotnet.android", "mobile");
|
||||
assert (domain);
|
||||
|
|
|
@ -111,21 +111,6 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task
|
|||
/// </summary>
|
||||
public bool UseDwarfDebug { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Path to Dotnet PGO binary (dotnet-pgo)
|
||||
/// </summary>
|
||||
public string? PgoBinaryPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// NetTrace file to use when invoking dotnet-pgo for
|
||||
/// </summary>
|
||||
public string? NetTracePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Directory containing all assemblies referenced in a .nettrace collected from a separate device needed by dotnet-pgo. Necessary for mobile platforms.
|
||||
/// </summary>
|
||||
public ITaskItem[] ReferenceAssemblyPathsForPGO { get; set; } = Array.Empty<ITaskItem>();
|
||||
|
||||
/// <summary>
|
||||
/// File to use for profile-guided optimization, *only* the methods described in the file will be AOT compiled.
|
||||
/// </summary>
|
||||
|
@ -287,31 +272,6 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task
|
|||
if (!Directory.Exists(IntermediateOutputPath))
|
||||
Directory.CreateDirectory(IntermediateOutputPath);
|
||||
|
||||
if (!string.IsNullOrEmpty(NetTracePath))
|
||||
{
|
||||
if (!File.Exists(NetTracePath))
|
||||
{
|
||||
Log.LogError($"{nameof(NetTracePath)}='{NetTracePath}' doesn't exist");
|
||||
return false;
|
||||
}
|
||||
if (!File.Exists(PgoBinaryPath))
|
||||
{
|
||||
Log.LogError($"NetTracePath was provided, but {nameof(PgoBinaryPath)}='{PgoBinaryPath}' doesn't exist");
|
||||
return false;
|
||||
}
|
||||
if (ReferenceAssemblyPathsForPGO.Length == 0)
|
||||
{
|
||||
Log.LogError($"NetTracePath was provided, but {nameof(ReferenceAssemblyPathsForPGO)} is empty");
|
||||
return false;
|
||||
}
|
||||
foreach (var refAsmItem in ReferenceAssemblyPathsForPGO)
|
||||
{
|
||||
string? fullPath = refAsmItem.GetMetadata("FullPath");
|
||||
if (!File.Exists(fullPath))
|
||||
throw new LogAsErrorException($"ReferenceAssembly '{fullPath}' doesn't exist");
|
||||
}
|
||||
}
|
||||
|
||||
if (AotProfilePath != null)
|
||||
{
|
||||
foreach (var path in AotProfilePath)
|
||||
|
@ -438,48 +398,6 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task
|
|||
}
|
||||
}
|
||||
|
||||
private bool ProcessNettrace(string netTraceFile)
|
||||
{
|
||||
var outputMibcPath = Path.Combine(OutputDir, Path.ChangeExtension(Path.GetFileName(netTraceFile), ".mibc"));
|
||||
|
||||
if (_cache!.Enabled)
|
||||
{
|
||||
string hash = Utils.ComputeHash(netTraceFile);
|
||||
if (!_cache!.UpdateAndCheckHasFileChanged($"-mibc-source-file-{Path.GetFileName(netTraceFile)}", hash))
|
||||
{
|
||||
Log.LogMessage(MessageImportance.Low, $"Skipping generating {outputMibcPath} from {netTraceFile} because source file hasn't changed");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.LogMessage(MessageImportance.Low, $"Generating {outputMibcPath} from {netTraceFile} because the source file's hash has changed.");
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder pgoArgsStr = new StringBuilder(string.Empty);
|
||||
pgoArgsStr.Append($"create-mibc");
|
||||
pgoArgsStr.Append($" --trace {netTraceFile} ");
|
||||
foreach (var refAsmItem in ReferenceAssemblyPathsForPGO)
|
||||
{
|
||||
string? fullPath = refAsmItem.GetMetadata("FullPath");
|
||||
pgoArgsStr.Append($" --reference \"{fullPath}\" ");
|
||||
}
|
||||
pgoArgsStr.Append($" --output {outputMibcPath} ");
|
||||
(int exitCode, string output) = Utils.TryRunProcess(Log,
|
||||
PgoBinaryPath!,
|
||||
pgoArgsStr.ToString());
|
||||
|
||||
if (exitCode != 0)
|
||||
{
|
||||
Log.LogError($"dotnet-pgo({PgoBinaryPath}) failed for {netTraceFile}:{output}");
|
||||
return false;
|
||||
}
|
||||
|
||||
MibcProfilePath = MibcProfilePath.Append(outputMibcPath).ToArray();
|
||||
Log.LogMessage(MessageImportance.Low, $"Generated {outputMibcPath} from {PgoBinaryPath}");
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ExecuteInternal()
|
||||
{
|
||||
if (!ProcessAndValidateArguments())
|
||||
|
@ -498,9 +416,6 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task
|
|||
|
||||
_cache = new FileCache(CacheFilePath, Log);
|
||||
|
||||
if (!string.IsNullOrEmpty(NetTracePath) && !ProcessNettrace(NetTracePath))
|
||||
return false;
|
||||
|
||||
List<PrecompileArguments> argsList = new();
|
||||
foreach (var assemblyItem in _assembliesToCompile)
|
||||
argsList.Add(GetPrecompileArgumentsFor(assemblyItem, monoPaths));
|
||||
|
@ -1150,132 +1065,6 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task
|
|||
}
|
||||
}
|
||||
|
||||
internal sealed class FileCache
|
||||
{
|
||||
private CompilerCache? _newCache;
|
||||
private CompilerCache? _oldCache;
|
||||
|
||||
public bool Enabled { get; }
|
||||
public TaskLoggingHelper Log { get; }
|
||||
|
||||
public FileCache(string? cacheFilePath, TaskLoggingHelper log)
|
||||
{
|
||||
Log = log;
|
||||
if (string.IsNullOrEmpty(cacheFilePath))
|
||||
{
|
||||
Log.LogMessage(MessageImportance.Low, $"Disabling cache, because CacheFilePath is not set");
|
||||
return;
|
||||
}
|
||||
|
||||
Enabled = true;
|
||||
if (File.Exists(cacheFilePath))
|
||||
{
|
||||
_oldCache = (CompilerCache?)JsonSerializer.Deserialize(File.ReadAllText(cacheFilePath),
|
||||
typeof(CompilerCache),
|
||||
new JsonSerializerOptions());
|
||||
}
|
||||
|
||||
_oldCache ??= new();
|
||||
_newCache = new(_oldCache.FileHashes);
|
||||
}
|
||||
|
||||
public bool UpdateAndCheckHasFileChanged(string filePath, string newHash)
|
||||
{
|
||||
if (!Enabled)
|
||||
throw new InvalidOperationException("Cache is not enabled. Make sure the cache file path is set");
|
||||
|
||||
_newCache!.FileHashes[filePath] = newHash;
|
||||
return !_oldCache!.FileHashes.TryGetValue(filePath, out string? oldHash) || oldHash != newHash;
|
||||
}
|
||||
|
||||
public bool ShouldCopy(ProxyFile proxyFile, [NotNullWhen(true)] out string? cause)
|
||||
{
|
||||
if (!Enabled)
|
||||
throw new InvalidOperationException("Cache is not enabled. Make sure the cache file path is set");
|
||||
|
||||
cause = null;
|
||||
|
||||
string newHash = Utils.ComputeHash(proxyFile.TempFile);
|
||||
_newCache!.FileHashes[proxyFile.TargetFile] = newHash;
|
||||
|
||||
if (!File.Exists(proxyFile.TargetFile))
|
||||
{
|
||||
cause = $"the output file didn't exist";
|
||||
return true;
|
||||
}
|
||||
|
||||
string? oldHash;
|
||||
if (!_oldCache!.FileHashes.TryGetValue(proxyFile.TargetFile, out oldHash))
|
||||
oldHash = Utils.ComputeHash(proxyFile.TargetFile);
|
||||
|
||||
if (oldHash != newHash)
|
||||
{
|
||||
cause = $"hash for the file changed";
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Save(string? cacheFilePath)
|
||||
{
|
||||
if (!Enabled || string.IsNullOrEmpty(cacheFilePath))
|
||||
return false;
|
||||
|
||||
var json = JsonSerializer.Serialize (_newCache, new JsonSerializerOptions { WriteIndented = true });
|
||||
File.WriteAllText(cacheFilePath!, json);
|
||||
return true;
|
||||
}
|
||||
|
||||
public ProxyFile NewFile(string targetFile) => new ProxyFile(targetFile, this);
|
||||
}
|
||||
|
||||
internal sealed class ProxyFile
|
||||
{
|
||||
public string TargetFile { get; }
|
||||
public string TempFile { get; }
|
||||
private FileCache _cache;
|
||||
|
||||
public ProxyFile(string targetFile, FileCache cache)
|
||||
{
|
||||
_cache = cache;
|
||||
this.TargetFile = targetFile;
|
||||
this.TempFile = _cache.Enabled ? targetFile + ".tmp" : targetFile;
|
||||
}
|
||||
|
||||
public bool CopyOutputFileIfChanged()
|
||||
{
|
||||
if (!_cache.Enabled)
|
||||
return true;
|
||||
|
||||
if (!File.Exists(TempFile))
|
||||
throw new LogAsErrorException($"Could not find the temporary file {TempFile} for target file {TargetFile}. Look for any errors/warnings generated earlier in the build.");
|
||||
|
||||
try
|
||||
{
|
||||
if (!_cache.ShouldCopy(this, out string? cause))
|
||||
{
|
||||
_cache.Log.LogMessage(MessageImportance.Low, $"Skipping copying over {TargetFile} as the contents are unchanged");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (File.Exists(TargetFile))
|
||||
File.Delete(TargetFile);
|
||||
|
||||
File.Copy(TempFile, TargetFile);
|
||||
|
||||
_cache.Log.LogMessage(MessageImportance.Low, $"Copying {TempFile} to {TargetFile} because {cause}");
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_cache.Log.LogMessage(MessageImportance.Low, $"Deleting temp file {TempFile}");
|
||||
File.Delete(TempFile);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum MonoAotMode
|
||||
{
|
||||
Normal,
|
||||
|
@ -1306,13 +1095,3 @@ public enum MonoAotModulesTableLanguage
|
|||
C,
|
||||
ObjC
|
||||
}
|
||||
|
||||
internal sealed class CompilerCache
|
||||
{
|
||||
public CompilerCache() => FileHashes = new();
|
||||
public CompilerCache(IDictionary<string, string> oldHashes)
|
||||
=> FileHashes = new(oldHashes);
|
||||
|
||||
[JsonPropertyName("file_hashes")]
|
||||
public ConcurrentDictionary<string, string> FileHashes { get; set; }
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MonoAOTCompiler.cs" />
|
||||
<Compile Include="..\Common\CompilerCache.cs" />
|
||||
<Compile Include="..\Common\ProxyFile.cs" />
|
||||
<Compile Include="..\Common\FileCache.cs" />
|
||||
<Compile Include="..\Common\Utils.cs" />
|
||||
<Compile Include="..\Common\LogAsErrorException.cs" />
|
||||
<Compile Include="$(RepoRoot)src\libraries\System.Private.CoreLib\src\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" />
|
||||
|
|
21
src/tasks/Common/CompilerCache.cs
Normal file
21
src/tasks/Common/CompilerCache.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
#nullable enable
|
||||
|
||||
internal sealed class CompilerCache
|
||||
{
|
||||
public CompilerCache() => FileHashes = new();
|
||||
public CompilerCache(IDictionary<string, string> oldHashes)
|
||||
=> FileHashes = new(oldHashes);
|
||||
|
||||
[JsonPropertyName("file_hashes")]
|
||||
public ConcurrentDictionary<string, string> FileHashes { get; set; }
|
||||
}
|
93
src/tasks/Common/FileCache.cs
Normal file
93
src/tasks/Common/FileCache.cs
Normal file
|
@ -0,0 +1,93 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
#nullable enable
|
||||
|
||||
internal sealed class FileCache
|
||||
{
|
||||
private CompilerCache? _newCache;
|
||||
private CompilerCache? _oldCache;
|
||||
|
||||
public bool Enabled { get; }
|
||||
public TaskLoggingHelper Log { get; }
|
||||
|
||||
public FileCache(string? cacheFilePath, TaskLoggingHelper log)
|
||||
{
|
||||
Log = log;
|
||||
if (string.IsNullOrEmpty(cacheFilePath))
|
||||
{
|
||||
Log.LogMessage(MessageImportance.Low, $"Disabling cache, because CacheFilePath is not set");
|
||||
return;
|
||||
}
|
||||
|
||||
//Enabled = true;
|
||||
if (File.Exists(cacheFilePath))
|
||||
{
|
||||
_oldCache = (CompilerCache?)JsonSerializer.Deserialize(File.ReadAllText(cacheFilePath),
|
||||
typeof(CompilerCache),
|
||||
new JsonSerializerOptions());
|
||||
}
|
||||
|
||||
_oldCache ??= new();
|
||||
_newCache = new(_oldCache.FileHashes);
|
||||
}
|
||||
|
||||
public bool UpdateAndCheckHasFileChanged(string filePath, string newHash)
|
||||
{
|
||||
if (!Enabled)
|
||||
throw new InvalidOperationException("Cache is not enabled. Make sure the cache file path is set");
|
||||
|
||||
_newCache!.FileHashes[filePath] = newHash;
|
||||
return !_oldCache!.FileHashes.TryGetValue(filePath, out string? oldHash) || oldHash != newHash;
|
||||
}
|
||||
|
||||
public bool ShouldCopy(ProxyFile proxyFile, [NotNullWhen(true)] out string? cause)
|
||||
{
|
||||
if (!Enabled)
|
||||
throw new InvalidOperationException("Cache is not enabled. Make sure the cache file path is set");
|
||||
|
||||
cause = null;
|
||||
|
||||
string newHash = Utils.ComputeHash(proxyFile.TempFile);
|
||||
_newCache!.FileHashes[proxyFile.TargetFile] = newHash;
|
||||
|
||||
if (!File.Exists(proxyFile.TargetFile))
|
||||
{
|
||||
cause = $"the output file didn't exist";
|
||||
return true;
|
||||
}
|
||||
|
||||
string? oldHash;
|
||||
if (!_oldCache!.FileHashes.TryGetValue(proxyFile.TargetFile, out oldHash))
|
||||
oldHash = Utils.ComputeHash(proxyFile.TargetFile);
|
||||
|
||||
if (oldHash != newHash)
|
||||
{
|
||||
cause = $"hash for the file changed";
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Save(string? cacheFilePath)
|
||||
{
|
||||
if (!Enabled || string.IsNullOrEmpty(cacheFilePath))
|
||||
return false;
|
||||
|
||||
var json = JsonSerializer.Serialize (_newCache, new JsonSerializerOptions { WriteIndented = true });
|
||||
File.WriteAllText(cacheFilePath!, json);
|
||||
return true;
|
||||
}
|
||||
|
||||
public ProxyFile NewFile(string targetFile) => new ProxyFile(targetFile, this);
|
||||
}
|
56
src/tasks/Common/ProxyFile.cs
Normal file
56
src/tasks/Common/ProxyFile.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Build.Framework;
|
||||
|
||||
#nullable enable
|
||||
|
||||
internal sealed class ProxyFile
|
||||
{
|
||||
public string TargetFile { get; }
|
||||
public string TempFile { get; }
|
||||
private FileCache _cache;
|
||||
|
||||
public ProxyFile(string targetFile, FileCache cache)
|
||||
{
|
||||
_cache = cache;
|
||||
this.TargetFile = targetFile;
|
||||
this.TempFile = _cache.Enabled ? targetFile + ".tmp" : targetFile;
|
||||
}
|
||||
|
||||
public bool CopyOutputFileIfChanged()
|
||||
{
|
||||
if (!_cache.Enabled)
|
||||
return true;
|
||||
|
||||
if (!File.Exists(TempFile))
|
||||
throw new LogAsErrorException($"Could not find the temporary file {TempFile} for target file {TargetFile}. Look for any errors/warnings generated earlier in the build.");
|
||||
|
||||
try
|
||||
{
|
||||
if (!_cache.ShouldCopy(this, out string? cause))
|
||||
{
|
||||
_cache.Log.LogMessage(MessageImportance.Low, $"Skipping copying over {TargetFile} as the contents are unchanged");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (File.Exists(TargetFile))
|
||||
File.Delete(TargetFile);
|
||||
|
||||
File.Copy(TempFile, TargetFile);
|
||||
|
||||
_cache.Log.LogMessage(MessageImportance.Low, $"Copying {TempFile} to {TargetFile} because {cause}");
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_cache.Log.LogMessage(MessageImportance.Low, $"Deleting temp file {TempFile}");
|
||||
File.Delete(TempFile);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,6 +29,8 @@
|
|||
<Compile Include="..\Common\Utils.cs" />
|
||||
<Compile Include="RuntimeConfigParser\RuntimeConfigParser.cs" />
|
||||
<Compile Include="JsonToItemsTaskFactory\JsonToItemsTaskFactory.cs" />
|
||||
<Compile Include="NetTraceToMibcConverterTask\NetTraceToMibcConverter.cs" />
|
||||
<Compile Include="..\Common\LogAsErrorException.cs" />
|
||||
<Compile Include="$(RepoRoot)src\libraries\System.Private.CoreLib\src\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public class NetTraceToMibcConverter : ToolTask
|
||||
{
|
||||
/// <summary>
|
||||
/// List of all assemblies referenced in a .nettrace file. Important when you run traces against an executable on a different machine / device
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ITaskItem[] Assemblies { get; set; } = Array.Empty<ITaskItem>();
|
||||
|
||||
/// <summary>
|
||||
/// Path to .nettrace file which should be converted to .mibc
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string NetTraceFilePath { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Directory where the mibc file will be placed
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
[Required]
|
||||
public string? OutputDir { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to the mibc file generated from the converter.
|
||||
/// </summary>
|
||||
[Output]
|
||||
public string MibcFilePath { get; set; } = "";
|
||||
|
||||
public override string ToolExe { get; set; } = "";
|
||||
|
||||
protected override string ToolName { get; } = "NetTraceToMibcConverter";
|
||||
|
||||
protected override string GenerateFullPathToTool()
|
||||
{
|
||||
return ToolPath;
|
||||
}
|
||||
|
||||
protected override bool ValidateParameters()
|
||||
{
|
||||
if (string.IsNullOrEmpty(ToolPath))
|
||||
{
|
||||
Log.LogError($"{nameof(ToolPath)}='{ToolPath}' must be specified.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(ToolExe))
|
||||
{
|
||||
ToolExe = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? "dotnet-pgo.exe" : "dotnet-pgo";
|
||||
}
|
||||
|
||||
string mibcConverterBinaryPath = Path.Combine(ToolPath, ToolExe);
|
||||
|
||||
if (!File.Exists(mibcConverterBinaryPath))
|
||||
{
|
||||
Log.LogError($"{nameof(mibcConverterBinaryPath)}='{mibcConverterBinaryPath}' doesn't exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Assemblies.Length == 0)
|
||||
{
|
||||
Log.LogError($"'{nameof(Assemblies)}' is required.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File.Exists(NetTraceFilePath))
|
||||
{
|
||||
Log.LogError($"{nameof(NetTraceFilePath)}='{NetTraceFilePath}' doesn't exist");
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var asmItem in Assemblies)
|
||||
{
|
||||
string? fullPath = asmItem.GetMetadata("FullPath");
|
||||
if (!File.Exists(fullPath))
|
||||
throw new LogAsErrorException($"Could not find {fullPath} to AOT");
|
||||
}
|
||||
|
||||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
|
||||
protected override string GenerateCommandLineCommands()
|
||||
{
|
||||
MibcFilePath = Path.Combine(OutputDir, Path.ChangeExtension(Path.GetFileName(NetTraceFilePath), ".mibc"));
|
||||
|
||||
StringBuilder mibcConverterArgsStr = new StringBuilder("create-mibc");
|
||||
mibcConverterArgsStr.Append($" --trace \"{NetTraceFilePath}\" ");
|
||||
|
||||
foreach (var refAsmItem in Assemblies)
|
||||
{
|
||||
string? fullPath = refAsmItem.GetMetadata("FullPath");
|
||||
mibcConverterArgsStr.Append($" --reference \"{fullPath}\" ");
|
||||
}
|
||||
|
||||
mibcConverterArgsStr.Append($" --output \"{MibcFilePath}\"");
|
||||
|
||||
return mibcConverterArgsStr.ToString();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue