From 4460b1accc8ae359c3242adf10a5dd507a5fe933 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Mon, 24 Jun 2024 15:05:06 -0700 Subject: [PATCH 1/5] Make BindingDemo use source generators --- build/EmbedXaml.props | 1 + samples/BindingDemo/App.xaml.cs | 2 +- samples/BindingDemo/BindingDemo.csproj | 6 +++--- samples/BindingDemo/MainWindow.xaml.cs | 14 +++----------- samples/BindingDemo/TestItemView.xaml.cs | 9 ++------- .../Generators.Sandbox/Generators.Sandbox.csproj | 9 ++------- 6 files changed, 12 insertions(+), 29 deletions(-) diff --git a/build/EmbedXaml.props b/build/EmbedXaml.props index 0bb8da4f47a..ccf49d2370b 100644 --- a/build/EmbedXaml.props +++ b/build/EmbedXaml.props @@ -8,5 +8,6 @@ Designer + diff --git a/samples/BindingDemo/App.xaml.cs b/samples/BindingDemo/App.xaml.cs index 8a5364c70be..805fc24cd7b 100644 --- a/samples/BindingDemo/App.xaml.cs +++ b/samples/BindingDemo/App.xaml.cs @@ -4,7 +4,7 @@ namespace BindingDemo { - public class App : Application + public partial class App : Application { public override void Initialize() { diff --git a/samples/BindingDemo/BindingDemo.csproj b/samples/BindingDemo/BindingDemo.csproj index faeb643d8a1..130df8f560e 100644 --- a/samples/BindingDemo/BindingDemo.csproj +++ b/samples/BindingDemo/BindingDemo.csproj @@ -2,18 +2,18 @@ Exe $(AvsCurrentTargetFramework) + true - + - - + diff --git a/samples/BindingDemo/MainWindow.xaml.cs b/samples/BindingDemo/MainWindow.xaml.cs index eaa57e1f5fb..061b693711a 100644 --- a/samples/BindingDemo/MainWindow.xaml.cs +++ b/samples/BindingDemo/MainWindow.xaml.cs @@ -1,22 +1,14 @@ using BindingDemo.ViewModels; -using Avalonia; using Avalonia.Controls; -using Avalonia.Markup.Xaml; namespace BindingDemo { - public class MainWindow : Window + public partial class MainWindow : Window { public MainWindow() { - this.InitializeComponent(); - this.DataContext = new MainWindowViewModel(); - this.AttachDevTools(); - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); + InitializeComponent(); + DataContext = new MainWindowViewModel(); } } } diff --git a/samples/BindingDemo/TestItemView.xaml.cs b/samples/BindingDemo/TestItemView.xaml.cs index 8c0b592f006..df2b7281b08 100644 --- a/samples/BindingDemo/TestItemView.xaml.cs +++ b/samples/BindingDemo/TestItemView.xaml.cs @@ -3,16 +3,11 @@ namespace BindingDemo { - public class TestItemView : UserControl + public partial class TestItemView : UserControl { public TestItemView() { - this.InitializeComponent(); - } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); + InitializeComponent(); } } } diff --git a/samples/Generators.Sandbox/Generators.Sandbox.csproj b/samples/Generators.Sandbox/Generators.Sandbox.csproj index 6cbf210d3fc..9bd3876d904 100644 --- a/samples/Generators.Sandbox/Generators.Sandbox.csproj +++ b/samples/Generators.Sandbox/Generators.Sandbox.csproj @@ -5,12 +5,6 @@ true - - - - - - @@ -23,6 +17,7 @@ - + + From abbde41040b8b5166b28221e465a3c46df3e6d41 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Mon, 24 Jun 2024 15:06:35 -0700 Subject: [PATCH 2/5] Use compiled bindings and only avoid Rx in BindingDemo --- samples/BindingDemo/BindingDemo.csproj | 3 +- samples/BindingDemo/MainWindow.xaml | 4 +-- .../DataAnnotationsErrorViewModel.cs | 2 ++ .../ViewModels/IndeiErrorViewModel.cs | 9 ++++-- .../ViewModels/MainWindowViewModel.cs | 32 ++++++++++++++++--- 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/samples/BindingDemo/BindingDemo.csproj b/samples/BindingDemo/BindingDemo.csproj index 130df8f560e..1b5fed92217 100644 --- a/samples/BindingDemo/BindingDemo.csproj +++ b/samples/BindingDemo/BindingDemo.csproj @@ -2,6 +2,7 @@ Exe $(AvsCurrentTargetFramework) + true true @@ -12,7 +13,7 @@ - + diff --git a/samples/BindingDemo/MainWindow.xaml b/samples/BindingDemo/MainWindow.xaml index f14ad59cd5f..e7753cc473c 100644 --- a/samples/BindingDemo/MainWindow.xaml +++ b/samples/BindingDemo/MainWindow.xaml @@ -82,7 +82,7 @@ - + @@ -126,7 +126,7 @@ - + diff --git a/samples/BindingDemo/ViewModels/DataAnnotationsErrorViewModel.cs b/samples/BindingDemo/ViewModels/DataAnnotationsErrorViewModel.cs index 391d1791d37..e60a6b3d9a6 100644 --- a/samples/BindingDemo/ViewModels/DataAnnotationsErrorViewModel.cs +++ b/samples/BindingDemo/ViewModels/DataAnnotationsErrorViewModel.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace BindingDemo.ViewModels { @@ -6,6 +7,7 @@ public class DataAnnotationsErrorViewModel { [Phone] [MaxLength(10)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "MaxLength is safe here, as string implements ICollection.")] public string PhoneNumber { get; set; } [Range(0, 9)] diff --git a/samples/BindingDemo/ViewModels/IndeiErrorViewModel.cs b/samples/BindingDemo/ViewModels/IndeiErrorViewModel.cs index 9ae8d9558f8..a4513729d3d 100644 --- a/samples/BindingDemo/ViewModels/IndeiErrorViewModel.cs +++ b/samples/BindingDemo/ViewModels/IndeiErrorViewModel.cs @@ -13,8 +13,13 @@ public class IndeiErrorViewModel : ViewModelBase, INotifyDataErrorInfo public IndeiErrorViewModel() { - this.WhenAnyValue(x => x.Maximum, x => x.Value) - .Subscribe(_ => UpdateErrors()); + PropertyChanged += (sender, args) => + { + if (args.PropertyName == nameof(Maximum) || args.PropertyName == nameof(Value)) + { + UpdateErrors(); + } + }; } public bool HasErrors diff --git a/samples/BindingDemo/ViewModels/MainWindowViewModel.cs b/samples/BindingDemo/ViewModels/MainWindowViewModel.cs index 18a7a01a694..fe40714a01b 100644 --- a/samples/BindingDemo/ViewModels/MainWindowViewModel.cs +++ b/samples/BindingDemo/ViewModels/MainWindowViewModel.cs @@ -1,14 +1,13 @@ using System; using System.Collections.ObjectModel; using System.Linq; -using System.Reactive; -using System.Reactive.Linq; using System.Threading.Tasks; using System.Threading; using MiniMvvm; using Avalonia.Controls; using Avalonia.Metadata; using Avalonia.Controls.Selection; +using Avalonia.Threading; namespace BindingDemo.ViewModels { @@ -54,8 +53,7 @@ public MainWindowViewModel() } }); - CurrentTimeObservable = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1)) - .Select(x => DateTimeOffset.Now); + CurrentTimeObservable = new DispatcherTimerObservable(TimeSpan.FromMilliseconds(500)); } public ObservableCollection Items { get; } @@ -115,5 +113,31 @@ bool CanDo(object parameter) { return BooleanFlag; } + + private class DispatcherTimerObservable(TimeSpan interval) : IObservable + { + public IDisposable Subscribe(IObserver observer) + { + var timer = new DispatcherTimer(); + timer.Tag = observer; + timer.Interval = interval; + timer.Tick += static (s, _) => + { + var observer = (IObserver)((DispatcherTimer)s!).Tag!; + observer.OnNext(DateTimeOffset.Now); + }; + timer.Start(); + return new Disposable(timer, observer); + } + + private class Disposable(DispatcherTimer timer, IObserver observer) : IDisposable + { + public void Dispose() + { + timer.Stop(); + observer.OnCompleted(); + } + } + } } } From bb9aeee5ac4de11a5a14e6a13a12ac58da91ea50 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Mon, 24 Jun 2024 15:37:10 -0700 Subject: [PATCH 3/5] Implement BuildAotDemo job --- .nuke/build.schema.json | 2 ++ azure-pipelines.yml | 21 ++++++++++++++++++++- nukebuild/Build.cs | 25 ++++++++++++++++++++++++- nukebuild/DotNetConfigHelper.cs | 10 ++++++++++ samples/BindingDemo/BindingDemo.csproj | 1 + 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json index f833ddd89a4..0143b701cad 100644 --- a/.nuke/build.schema.json +++ b/.nuke/build.schema.json @@ -73,6 +73,7 @@ "items": { "type": "string", "enum": [ + "BuildAotDemo", "BuildToNuGetCache", "CiAzureLinux", "CiAzureOSX", @@ -110,6 +111,7 @@ "items": { "type": "string", "enum": [ + "BuildAotDemo", "BuildToNuGetCache", "CiAzureLinux", "CiAzureOSX", diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f6e116a8fa7..2d9a4521f74 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -20,7 +20,7 @@ jobs: PathtoPublish: '$(Build.ArtifactStagingDirectory)' ArtifactName: 'PRNumber' publishLocation: 'Container' - + - job: Linux pool: vmImage: 'ubuntu-20.04' @@ -207,3 +207,22 @@ jobs: artifactName: 'Samples' condition: succeeded() +- job: BuildAotDemo + pool: + vmImage: 'windows-2022' + variables: + SolutionDir: '$(Build.SourcesDirectory)' + steps: + - task: UseDotNet@2 + displayName: 'Use .NET 8.0 SDK' + inputs: + packageType: sdk + useGlobalJson: true + - task: CmdLine@2 + displayName: 'Run Build' + inputs: + script: ./build.sh --target BuildAotDemo + - task: PublishBuildArtifacts@1 + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/demo/' + ArtifactName: 'Demo' diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs index 9157e4c44b0..d90021f6fe1 100644 --- a/nukebuild/Build.cs +++ b/nukebuild/Build.cs @@ -94,9 +94,12 @@ DotNetConfigHelper ApplySettingCore(DotNetConfigHelper c) .AddProperty("SkipBuildingTests", "True"); return c; } + DotNetBuildSettings ApplySetting(DotNetBuildSettings c, Configure configurator = null) => ApplySettingCore(c).Build.Apply(configurator); - + + DotNetPublishSettings ApplySetting(DotNetPublishSettings c, Configure configurator = null) => + ApplySettingCore(c).Publish.Apply(configurator); DotNetPackSettings ApplySetting(DotNetPackSettings c, Configure configurator = null) => ApplySettingCore(c).Pack.Apply(configurator); @@ -401,6 +404,26 @@ await Task.WhenAll( file.GenerateCppHeader()); }); + // Skip anything that might slow down PublishAot build. + // Runtime configuration will be assumed from the running OS. + Target BuildAotDemo => _ => _ + .DependsOn(Clean, CompileNative) + .Executes(() => + { + var outputDir = Parameters.ArtifactsDir / "demo" / "BindingDemo"; + DotNetPublish(c => ApplySetting(c) + .SetOutput(outputDir) + // Extra property instead of PublishAot, see https://github.com/dotnet/sdk/issues/37228 why. + .AddProperty("EnablePublishAot", true) + .SetProject(RootDirectory.GlobFiles(@"**\BindingDemo.csproj").FirstOrDefault() + ?? throw new InvalidOperationException($"Project BindingDemo doesn't exist")) + ); + foreach (var extraFile in Directory.EnumerateFiles(outputDir, "*.xml") + .Concat(Directory.EnumerateFiles(outputDir, "*.pdb"))) + { + File.Delete(extraFile); + } + }); public static int Main() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) diff --git a/nukebuild/DotNetConfigHelper.cs b/nukebuild/DotNetConfigHelper.cs index 9d43261616a..060dfb01221 100644 --- a/nukebuild/DotNetConfigHelper.cs +++ b/nukebuild/DotNetConfigHelper.cs @@ -5,6 +5,7 @@ public class DotNetConfigHelper { public DotNetBuildSettings Build; + public DotNetPublishSettings Publish; public DotNetPackSettings Pack; public DotNetTestSettings Test; @@ -13,6 +14,11 @@ public DotNetConfigHelper(DotNetBuildSettings s) Build = s; } + public DotNetConfigHelper(DotNetPublishSettings s) + { + Publish = s; + } + public DotNetConfigHelper(DotNetPackSettings s) { Pack = s; @@ -28,6 +34,7 @@ public DotNetConfigHelper AddProperty(string key, bool value) => public DotNetConfigHelper AddProperty(string key, string value) { Build = Build?.AddProperty(key, value); + Publish = Publish?.AddProperty(key, value); Pack = Pack?.AddProperty(key, value); Test = Test?.AddProperty(key, value); @@ -37,6 +44,7 @@ public DotNetConfigHelper AddProperty(string key, string value) public DotNetConfigHelper SetConfiguration(string configuration) { Build = Build?.SetConfiguration(configuration); + Publish = Publish?.SetConfiguration(configuration); Pack = Pack?.SetConfiguration(configuration); Test = Test?.SetConfiguration(configuration); return this; @@ -45,12 +53,14 @@ public DotNetConfigHelper SetConfiguration(string configuration) public DotNetConfigHelper SetVerbosity(DotNetVerbosity verbosity) { Build = Build?.SetVerbosity(verbosity); + Publish = Publish?.SetVerbosity(verbosity); Pack = Pack?.SetVerbosity(verbosity); Test = Test?.SetVerbosity(verbosity); return this; } public static implicit operator DotNetConfigHelper(DotNetBuildSettings s) => new DotNetConfigHelper(s); + public static implicit operator DotNetConfigHelper(DotNetPublishSettings s) => new DotNetConfigHelper(s); public static implicit operator DotNetConfigHelper(DotNetPackSettings s) => new DotNetConfigHelper(s); public static implicit operator DotNetConfigHelper(DotNetTestSettings s) => new DotNetConfigHelper(s); } diff --git a/samples/BindingDemo/BindingDemo.csproj b/samples/BindingDemo/BindingDemo.csproj index 1b5fed92217..c480bdbefda 100644 --- a/samples/BindingDemo/BindingDemo.csproj +++ b/samples/BindingDemo/BindingDemo.csproj @@ -4,6 +4,7 @@ $(AvsCurrentTargetFramework) true true + true From c3df191407e2d7862524603a5b5f2037c7018ad6 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Mon, 24 Jun 2024 16:07:46 -0700 Subject: [PATCH 4/5] Try linux build and see if it fails --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 2d9a4521f74..a084cf74f83 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -209,7 +209,7 @@ jobs: - job: BuildAotDemo pool: - vmImage: 'windows-2022' + vmImage: 'ubuntu-20.04' variables: SolutionDir: '$(Build.SourcesDirectory)' steps: From 8726007381762b4c5c43aa2293e0adb175c856bc Mon Sep 17 00:00:00 2001 From: Max Katz Date: Mon, 24 Jun 2024 16:46:28 -0700 Subject: [PATCH 5/5] Rename artifact and remove dbg file --- azure-pipelines.yml | 2 +- nukebuild/Build.cs | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a084cf74f83..abd25db0468 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -225,4 +225,4 @@ jobs: - task: PublishBuildArtifacts@1 inputs: PathtoPublish: '$(Build.SourcesDirectory)/artifacts/demo/' - ArtifactName: 'Demo' + ArtifactName: 'AotDemo' diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs index d90021f6fe1..2dfdf52209e 100644 --- a/nukebuild/Build.cs +++ b/nukebuild/Build.cs @@ -418,10 +418,14 @@ await Task.WhenAll( .SetProject(RootDirectory.GlobFiles(@"**\BindingDemo.csproj").FirstOrDefault() ?? throw new InvalidOperationException($"Project BindingDemo doesn't exist")) ); - foreach (var extraFile in Directory.EnumerateFiles(outputDir, "*.xml") - .Concat(Directory.EnumerateFiles(outputDir, "*.pdb"))) + if (Parameters.Configuration != Parameters.ReleaseConfiguration) { - File.Delete(extraFile); + foreach (var extraFile in Directory.EnumerateFiles(outputDir, "*.xml") + .Concat(Directory.EnumerateFiles(outputDir, "*.pdb")) + .Concat(Directory.EnumerateFiles(outputDir, "*.dbg"))) + { + File.Delete(extraFile); + } } });