[dotnet] Only pass a single custom step to the linker. (#9173)
* [dotnet] Only pass a single custom step to the linker. The linker will load the assemblies with the custom steps once per custom step argument, which means that each step is effectively in a different assembly, making it impossible to share state between steps. This behavior is filed as a linker bug: https://github.com/mono/linker/issues/1314 Until this is fixed, we can just have a single step that injects all the other steps programmatically. * [tests] Adjust .NET tests according to new behavior.
This commit is contained in:
Родитель
25b8cbe22b
Коммит
4a5dc20338
|
@ -149,19 +149,11 @@
|
|||
<_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --verbose</_ExtraTrimmerArgs>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- add our custom steps -->
|
||||
<!-- add a custom step which inserts any other steps we need -->
|
||||
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)">
|
||||
<BeforeStep>LoadReferencesStep</BeforeStep>
|
||||
<Type>Xamarin.SetupStep</Type>
|
||||
</_TrimmerCustomSteps>
|
||||
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)">
|
||||
<!-- At the end of the pipeline -->
|
||||
<Type>Xamarin.GenerateMainStep</Type>
|
||||
</_TrimmerCustomSteps>
|
||||
<_TrimmerCustomSteps Include="$(_AdditionalTaskAssembly)">
|
||||
<!-- At the end of the pipeline -->
|
||||
<Type>Xamarin.GatherFrameworksStep</Type>
|
||||
</_TrimmerCustomSteps>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Create the file with our custom linker options -->
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
@ -8,6 +9,8 @@ using Xamarin.Utils;
|
|||
namespace Xamarin.Tests {
|
||||
[TestFixture]
|
||||
public class DotNetProjectTest {
|
||||
Dictionary<string, string> verbosity = new Dictionary<string, string> { { "_BundlerVerbosity", "1" } };
|
||||
|
||||
string GetProjectPath (string project, string subdir = null)
|
||||
{
|
||||
var project_dir = Path.Combine (Configuration.SourceRoot, "tests", "dotnet", project);
|
||||
|
@ -41,7 +44,7 @@ namespace Xamarin.Tests {
|
|||
var platform = ApplePlatform.iOS;
|
||||
var project_path = GetProjectPath ("MySingleView");
|
||||
Clean (project_path);
|
||||
var result = DotNet.AssertBuild (project_path);
|
||||
var result = DotNet.AssertBuild (project_path, verbosity);
|
||||
AssertThatLinkerExecuted (result);
|
||||
AssertAppContents (platform, Path.Combine (Path.GetDirectoryName (project_path), "bin", "Debug", "net5.0", "ios-x64", "MySingleView.app"));
|
||||
}
|
||||
|
@ -52,7 +55,7 @@ namespace Xamarin.Tests {
|
|||
var platform = ApplePlatform.MacOSX;
|
||||
var project_path = GetProjectPath ("MyCocoaApp");
|
||||
Clean (project_path);
|
||||
var result = DotNet.AssertBuild (project_path);
|
||||
var result = DotNet.AssertBuild (project_path, verbosity);
|
||||
AssertThatLinkerExecuted (result);
|
||||
AssertAppContents (platform, Path.Combine (Path.GetDirectoryName (project_path), "bin", "Debug", "net5.0", "osx-x64", "MyCocoaApp.app"));
|
||||
}
|
||||
|
@ -63,7 +66,7 @@ namespace Xamarin.Tests {
|
|||
var platform = ApplePlatform.TVOS;
|
||||
var project_path = GetProjectPath ("MyTVApp");
|
||||
Clean (project_path);
|
||||
var result = DotNet.AssertBuild (project_path);
|
||||
var result = DotNet.AssertBuild (project_path, verbosity);
|
||||
AssertThatLinkerExecuted (result);
|
||||
AssertAppContents (platform, Path.Combine (Path.GetDirectoryName (project_path), "bin", "Debug", "net5.0", "tvos-x64", "MyTVApp.app"));
|
||||
}
|
||||
|
@ -73,7 +76,7 @@ namespace Xamarin.Tests {
|
|||
{
|
||||
var project_path = GetProjectPath ("MyWatchApp");
|
||||
Clean (project_path);
|
||||
var result = DotNet.AssertBuildFailure (project_path);
|
||||
var result = DotNet.AssertBuildFailure (project_path, verbosity);
|
||||
Assert.That (result.StandardOutput.ToString (), Does.Contain ("The specified RuntimeIdentifier 'watchos-x86' is not recognized."), "Missing runtime pack for watchOS");
|
||||
}
|
||||
|
||||
|
@ -85,7 +88,7 @@ namespace Xamarin.Tests {
|
|||
{
|
||||
var project_path = GetProjectPath ("MyClassLibrary", platform);
|
||||
Clean (project_path);
|
||||
var result = DotNet.AssertBuild (project_path);
|
||||
var result = DotNet.AssertBuild (project_path, verbosity);
|
||||
Assert.That (result.StandardOutput.ToString (), Does.Not.Contain ("Task \"ILLink\""), "Linker executed unexpectedly.");
|
||||
}
|
||||
|
||||
|
@ -93,7 +96,7 @@ namespace Xamarin.Tests {
|
|||
{
|
||||
var output = result.StandardOutput.ToString ();
|
||||
Assert.That (output, Does.Contain ("Building target \"_RunILLink\" completely."), "Linker did not executed as expected.");
|
||||
Assert.That (output, Does.Contain ("Hello SetupStep"), "Custom steps did not run as expected.");
|
||||
Assert.That (output, Does.Contain ("Pipeline Steps:"), "Custom steps did not run as expected.");
|
||||
}
|
||||
|
||||
void AssertAppContents (ApplePlatform platform, string app_directory)
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
using Mono.Linker;
|
||||
using Mono.Linker.Steps;
|
||||
|
||||
using Xamarin.Bundler;
|
||||
|
@ -10,12 +13,35 @@ namespace Xamarin {
|
|||
|
||||
public class SetupStep : ConfigurationAwareStep {
|
||||
|
||||
List<IStep> _steps;
|
||||
public List<IStep> Steps {
|
||||
get {
|
||||
if (_steps == null) {
|
||||
var pipeline = typeof (LinkContext).GetProperty ("Pipeline").GetGetMethod ().Invoke (Context, null);
|
||||
_steps = (List<IStep>) pipeline.GetType ().GetField ("_steps", BindingFlags.Instance | BindingFlags.NonPublic).GetValue (pipeline);
|
||||
}
|
||||
return _steps;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Process ()
|
||||
{
|
||||
// This will be replaced with something more useful later.
|
||||
Console.WriteLine ("Hello SetupStep");
|
||||
// Don't use --custom-step to load each step, because this assembly
|
||||
// is loaded into the current process once per --custom-step,
|
||||
// which makes it very difficult to share state between steps.
|
||||
Steps.Add (new GenerateMainStep ());
|
||||
Steps.Add (new GatherFrameworksStep ());
|
||||
|
||||
Configuration.Write ();
|
||||
|
||||
if (Configuration.Verbosity > 0) {
|
||||
Console.WriteLine ();
|
||||
Console.WriteLine ("Pipeline Steps:");
|
||||
foreach (var step in Steps) {
|
||||
Console.WriteLine ($" {step}");
|
||||
}
|
||||
}
|
||||
|
||||
ErrorHelper.Platform = Configuration.Platform;
|
||||
Directory.CreateDirectory (Configuration.ItemsDirectory);
|
||||
Directory.CreateDirectory (Configuration.CacheDirectory);
|
||||
|
|
Загрузка…
Ссылка в новой задаче