diff --git a/src/ObjCRuntime/ErrorHelper.cs b/src/ObjCRuntime/ErrorHelper.cs index c9b385b52d..a26a775d57 100644 --- a/src/ObjCRuntime/ErrorHelper.cs +++ b/src/ObjCRuntime/ErrorHelper.cs @@ -37,7 +37,15 @@ namespace ObjCRuntime { return new ProductException (code, false, innerException, message, args); } - static void CollectExceptions (Exception ex, List exceptions) + internal static IList CollectExceptions (IEnumerable exceptions) + { + var rv = new List (); + foreach (var ex in exceptions) + CollectExceptions (ex, rv); + return rv; + } + + internal static void CollectExceptions (Exception ex, List exceptions) { AggregateException ae = ex as AggregateException; diff --git a/tools/common/ErrorHelper.tools.cs b/tools/common/ErrorHelper.tools.cs index 77a976d7c5..933489a262 100644 --- a/tools/common/ErrorHelper.tools.cs +++ b/tools/common/ErrorHelper.tools.cs @@ -272,12 +272,9 @@ namespace Xamarin.Bundler { public static void Show (IEnumerable list) { - List exceptions = new List (); + var exceptions = CollectExceptions (list); bool error = false; - foreach (var e in list) - CollectExceptions (e, exceptions); - foreach (var ex in exceptions) error |= ShowInternal (ex); diff --git a/tools/dotnet-linker/LinkerConfiguration.cs b/tools/dotnet-linker/LinkerConfiguration.cs index 7f01672d2f..d087cc74af 100644 --- a/tools/dotnet-linker/LinkerConfiguration.cs +++ b/tools/dotnet-linker/LinkerConfiguration.cs @@ -283,6 +283,29 @@ namespace Xamarin.Linker { document.Save (Path.Combine (ItemsDirectory, itemName + ".items")); } + + public void Report (params Exception [] exceptions) + { + Report ((IList) exceptions); + } + + public void Report (IList exceptions) + { + // We can't really use the linker's reporting facilities and keep our own error codes, because we'll + // end up re-using the same error codes the linker already uses for its own purposes. So instead show + // a generic error using the linker's Context.LogMessage API, and then print our own errors to stderr. + // Since we print using a standard message format, msbuild will parse those error messages and show + // them as msbuild errors. + var list = ErrorHelper.CollectExceptions (exceptions); + var allWarnings = list.All (v => v is ProductException pe && !pe.Error); + if (!allWarnings) { + // Revisit the error code after https://github.com/mono/linker/issues/1596 has been fixed. + var msg = MessageContainer.CreateErrorMessage ("Failed to execute the custom steps.", 1999, Platform.ToString ()); + Context.LogMessage (msg); + } + // ErrorHelper.Show will print our errors and warnings to stderr. + ErrorHelper.Show (list); + } } } diff --git a/tools/dotnet-linker/Steps/ConfigurationAwareStep.cs b/tools/dotnet-linker/Steps/ConfigurationAwareStep.cs index f40acbb381..8951e8de3a 100644 --- a/tools/dotnet-linker/Steps/ConfigurationAwareStep.cs +++ b/tools/dotnet-linker/Steps/ConfigurationAwareStep.cs @@ -14,7 +14,7 @@ namespace Xamarin.Linker { protected void Report (Exception exception) { - ErrorHelper.Show (exception); + Configuration.Report (exception); } protected void Report (List exceptions) diff --git a/tools/dotnet-linker/Steps/ConfigurationAwareSubStep.cs b/tools/dotnet-linker/Steps/ConfigurationAwareSubStep.cs index 5d7e0bf050..df36ccf695 100644 --- a/tools/dotnet-linker/Steps/ConfigurationAwareSubStep.cs +++ b/tools/dotnet-linker/Steps/ConfigurationAwareSubStep.cs @@ -7,14 +7,12 @@ namespace Xamarin.Linker { public abstract class ConfigurationAwareSubStep : ExceptionalSubStep { protected override void Report (Exception exception) { - ErrorHelper.Show (exception); + Configuration.Report (exception); } protected void Report (List exceptions) { - // Maybe there's a better way to show errors that integrates with the linker? - // We can't just throw an exception or exit here, since there might be only warnings in the list of exceptions. - ErrorHelper.Show (exceptions); + Configuration.Report (exceptions); } } }