From 0d0b2125769a197266e7697dbced96160e3fb4e0 Mon Sep 17 00:00:00 2001 From: Arlo Date: Fri, 6 Jun 2025 17:20:39 -0500 Subject: [PATCH 1/5] Extracted MultiTarget/WinUI checks into dedicated Test-Component-Support.ps1 script --- Build-Toolkit-Components.ps1 | 70 +++---------- MultiTarget/Get-MultiTargets.ps1 | 2 +- MultiTarget/Test-Component-Support.ps1 | 131 +++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 59 deletions(-) create mode 100644 MultiTarget/Test-Component-Support.ps1 diff --git a/Build-Toolkit-Components.ps1 b/Build-Toolkit-Components.ps1 index c5178314..6cbc0ec5 100644 --- a/Build-Toolkit-Components.ps1 +++ b/Build-Toolkit-Components.ps1 @@ -121,10 +121,6 @@ $MultiTargets = $MultiTargets | Where-Object { $_ -notin $ExcludeMultiTargets } Write-Output "Building components '$Components' for MultiTargets: $MultiTargets" -if ($Components -eq @('all')) { - $Components = @('**') -} - if ($ExcludeComponents) { $Components = $Components | Where-Object { $_ -notin $ExcludeComponents } } @@ -212,14 +208,9 @@ function Invoke-MSBuildWithBinlog { } } -# List of WinUI-0 (non-WinUI) compatible multitargets -$WinUI0MultiTargets = @('netstandard') - -# List of WinUI-2 compatible multitargets -$WinUI2MultiTargets = @('uwp', 'wasm', 'wpf', 'linuxgtk', 'macos', 'ios', 'android') - -# List of WinUI-3 compatible multitargets -$WinUI3MultiTargets = @('wasdk', 'wasm', 'wpf', 'linuxgtk', 'macos', 'ios', 'android') +if ($Components -eq @('all')) { + $Components = @('**') +} # Components are built individually foreach ($ComponentName in $Components) { @@ -236,59 +227,22 @@ foreach ($ComponentName in $Components) { # Get supported MultiTarget for this component $supportedMultiTargets = & $PSScriptRoot\MultiTarget\Get-MultiTargets.ps1 -component $componentName - # If WinUI 0 is requested, the component must not support WinUI 2 or WinUI 3 to be built. - # If WinUI 2 or 3 is requested, the component have a target that supports WinUI 2 or 3 to be built. - $isWinUI0Supported = $false - $isWinUI2Supported = $false - $isWinUI3Supported = $false - - # Flag to check if any of the requested targets are supported by the component - $isRequestedTargetSupported = $false - - foreach ($requestedTarget in $MultiTargets) { - if ($false -eq $isRequestedTargetSupported) { - $isRequestedTargetSupported = $requestedTarget -in $supportedMultiTargets - } - } - - foreach ($supportedMultiTarget in $supportedMultiTargets) { - # Only build components that support WinUI 2 - if ($false -eq $isWinUI2Supported) { - $isWinUI2Supported = $supportedMultiTarget -in $WinUI2MultiTargets; - } - - # Only build components that support WinUI 3 - if ($false -eq $isWinUI3Supported) { - $isWinUI3Supported = $supportedMultiTarget -in $WinUI3MultiTargets; - } - - # Build components that support neither WinUI 2 nor WinUI 3 (e.g. netstandard only) - if ($false -eq $isWinUI0Supported) { - $isWinUI0Supported = $supportedMultiTarget -in $WinUI0MultiTargets -and -not ($isWinUI2Supported -or $isWinUI3Supported); - } - } - - # If none of the requested targets are supported by the component, we can skip build to save time and avoid errors. - if (-not $isRequestedTargetSupported) { - Write-Warning "Skipping $componentName, none of the requested MultiTargets '$MultiTargets' are enabled for this component." - continue - } - - if (-not $isWinUI0Supported -and $WinUIMajorVersion -eq 0) { - Write-Warning "Skipping $componentName. WinUI is disabled and one of the supported MultiTargets '$supportedMultiTargets' supports WinUI." - continue; - } - - if ((-not $isWinUI2Supported -and $WinUIMajorVersion -eq 2) -or (-not $isWinUI3Supported -and $WinUIMajorVersion -eq 3)) { - Write-Warning "Skipping $componentName. WinUI $WinUIMajorVersion is enabled and not supported by any of the MultiTargets '$supportedMultiTargets'" + $shouldBuild = & $PSScriptRoot\MultiTarget\Test-Component-Support.ps1 ` + -RequestedMultiTargets $MultiTargets ` + -SupportedMultiTargets $supportedMultiTargets ` + -Component $componentName ` + -WinUIMajorVersion $WinUIMajorVersion + + if (-not $shouldBuild.IsSupported) { + Write-Warning "Skipping $componentName. $($shouldBuild.Reason)" continue } # Filter ExcludeMultiTargets out of supportedMultiTargets # For display purposes only. The actual build uses the EnabledMultiTargets.props + EnabledTargetFrameworks.props to calculate supported targets at build time. $supportedMultiTargets = $supportedMultiTargets | Where-Object { $_ -notin $ExcludeMultiTargets } - Write-Output "Building $componentName for MultiTargets '$supportedMultiTargets'" + Invoke-MSBuildWithBinlog $componentCsproj.FullName $EnableBinLogs $BinlogOutput } } diff --git a/MultiTarget/Get-MultiTargets.ps1 b/MultiTarget/Get-MultiTargets.ps1 index 08569a40..19ffaec2 100644 --- a/MultiTarget/Get-MultiTargets.ps1 +++ b/MultiTarget/Get-MultiTargets.ps1 @@ -50,4 +50,4 @@ if ($null -eq $regex -or $null -eq $regex.Matches -or $null -eq $regex.Matches.G } $multiTargets = $regex.Matches.Groups[1].Value; -return $multiTargets.Split(';'); \ No newline at end of file +return $multiTargets.Split(';') | Where-Object { $_ -ne '' }; \ No newline at end of file diff --git a/MultiTarget/Test-Component-Support.ps1 b/MultiTarget/Test-Component-Support.ps1 new file mode 100644 index 00000000..19fe696b --- /dev/null +++ b/MultiTarget/Test-Component-Support.ps1 @@ -0,0 +1,131 @@ +<# +.SYNOPSIS + Tests WinUI support for a specific component and its requested MultiTargets. + +.DESCRIPTION + This script tests WinUI support for a specific component and its requested MultiTargets. It checks if the requested MultiTargets are supported by the component and if the WinUI version is compatible. + +.PARAMETER SupportedMultiTargets + Specifies known supported MultiTargets for the given component. Is retrieved if not specified. + +.PARAMETER RequestedMultiTargets + Specifies the MultiTarget TFM(s) to include for building the components. The default value is 'all'. If not specified, it will use the supported MultiTargets. + +.PARAMETER Component + Specifies the names of the components to build. Defaults to all components. + +.PARAMETER WinUIMajorVersion + Specifies the WinUI major version to use when building for Uno. Also decides the package id and dependency variant. + +.EXAMPLE + Build-Toolkit-Components -MultiTargets 'uwp', 'wasm' -DateForVersion '220101' -PreviewVersion 'local' -NupkgOutput 'C:\Output' -BinlogOutput 'C:\Logs' -EnableBinLogs -Components 'MyComponent1', 'MyComponent2' -ExcludeComponents 'MyComponent3' -Release -Verbose + + Builds the 'MyComponent1' and 'MyComponent2' components for the 'uwp' and 'wasm' target frameworks with version '220101' and preview version 'local'. The 'MyComponent3' component will be excluded from building. The .nupkg files will be copied to 'C:\Output' and binlogs will be generated in 'C:\Logs'. The components will be built in Release configuration with detailed msbuild verbosity. + +.NOTES + Author: Arlo Godfrey + Date: 6/6/2025 +#> +Param ( + [ValidateSet('wasm', 'uwp', 'wasdk', 'wpf', 'linuxgtk', 'macos', 'ios', 'android', 'netstandard')] + [Alias("smt")] + [string[]]$SupportedMultiTargets, + + [ValidateSet('all', 'wasm', 'uwp', 'wasdk', 'wpf', 'linuxgtk', 'macos', 'ios', 'android', 'netstandard')] + [Alias("rmt")] + [Parameter(Mandatory=$true)] + [string[]]$RequestedMultiTargets, + + [Alias("c")] + [Parameter(Mandatory=$true)] + [string]$Component, + + [Alias("winui")] + [Parameter(Mandatory=$true)] + [int]$WinUIMajorVersion +) + +if ($RequestedMultiTargets -eq 'all') { + $RequestedMultiTargets = @('wasm', 'uwp', 'wasdk', 'wpf', 'linuxgtk', 'macos', 'ios', 'android', 'netstandard') +} + +# List of WinUI-0 (non-WinUI) compatible multitargets +$WinUI0MultiTargets = @('netstandard') + +# List of WinUI-2 compatible multitargets +$WinUI2MultiTargets = @('uwp', 'wasm', 'wpf', 'linuxgtk', 'macos', 'ios', 'android') + +# List of WinUI-3 compatible multitargets +$WinUI3MultiTargets = @('wasdk', 'wasm', 'wpf', 'linuxgtk', 'macos', 'ios', 'android') + +# If WinUI 0 is requested, the component must not support WinUI 2 or WinUI 3 to be built. +# If WinUI 2 or 3 is requested, the component must have a target that supports WinUI 2 or 3 to be built. +$isWinUI0Supported = $false +$isWinUI2Supported = $false +$isWinUI3Supported = $false + +if ($null -ne $SupportedMultiTargets -and $SupportedMultiTargets.Count -gt 0) { + # If supported MultiTargets are provided, use them directly + $supportedMultiTargets = $SupportedMultiTargets +} else { + # If not provided, retrieve the supported MultiTargets for the component + if ($null -eq $Component) { + Write-Error "Component name must be specified to retrieve supported MultiTargets." + exit 1 + } + $supportedMultiTargets = & $PSScriptRoot\MultiTarget\Get-MultiTargets.ps1 -component $Component +} + + +# Flag to check if any of the requested targets are supported by the component +$isRequestedTargetSupported = $false + +foreach ($requestedTarget in $RequestedMultiTargets) { + if ($false -eq $isRequestedTargetSupported) { + $isRequestedTargetSupported = $requestedTarget -in $supportedMultiTargets + } +} + +foreach ($supportedMultiTarget in $supportedMultiTargets) { + # Only build components that support WinUI 2 + if ($false -eq $isWinUI2Supported) { + $isWinUI2Supported = $supportedMultiTarget -in $WinUI2MultiTargets; + } + + # Only build components that support WinUI 3 + if ($false -eq $isWinUI3Supported) { + $isWinUI3Supported = $supportedMultiTarget -in $WinUI3MultiTargets; + } + + # Build components that support neither WinUI 2 nor WinUI 3 (e.g. netstandard only) + if ($false -eq $isWinUI0Supported) { + $isWinUI0Supported = $supportedMultiTarget -in $WinUI0MultiTargets -and -not ($isWinUI2Supported -or $isWinUI3Supported); + } +} + +# If none of the requested targets are supported by the component, we can skip build to save time and avoid errors. +if (-not $isRequestedTargetSupported) { + $IsSupported = $false + $Reason = "None of the requested MultiTargets '$MultiTargets' are enabled for this component." +} + +if (-not $isWinUI0Supported -and $WinUIMajorVersion -eq 0) { + $IsSupported = $false + $Reason = "WinUI is disabled and one of the supported MultiTargets '$supportedMultiTargets' supports WinUI." +} + +if ((-not $isWinUI2Supported -and $WinUIMajorVersion -eq 2) -or (-not $isWinUI3Supported -and $WinUIMajorVersion -eq 3)) { + $IsSupported = $false + $Reason = "WinUI $WinUIMajorVersion is enabled and not supported by any of the MultiTargets '$supportedMultiTargets'" +} + +if ($null -eq $IsSupported) { + # Default to true if no conditions were met + $IsSupported = $true + $Reason = $null +} + +return [PSCustomObject]@{ + IsSupported = $IsSupported + Reason = $Reason +} \ No newline at end of file From e7ebe9d0536cd3acf974db2408daebac0d8b0cab Mon Sep 17 00:00:00 2001 From: Arlo Date: Fri, 6 Jun 2025 17:29:55 -0500 Subject: [PATCH 2/5] Add Filter-Supported-Components.ps1 script for one-line multi-component MultiTarget / WinUI checks via Test-Component-Support.ps1 --- MultiTarget/Filter-Supported-Components.ps1 | 69 +++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 MultiTarget/Filter-Supported-Components.ps1 diff --git a/MultiTarget/Filter-Supported-Components.ps1 b/MultiTarget/Filter-Supported-Components.ps1 new file mode 100644 index 00000000..bc187e85 --- /dev/null +++ b/MultiTarget/Filter-Supported-Components.ps1 @@ -0,0 +1,69 @@ +<# +.SYNOPSIS + Given a list of components, filters them based on their support for the specified MultiTarget TFM(s) and WinUI major version. + +.DESCRIPTION + This script checks each component to determine if it supports the specified MultiTarget TFM(s) and WinUI major version. + It returns a list of components that are supported for the given parameters. + +.PARAMETER MultiTargets + Specifies the MultiTarget TFM(s) to include for building the components. + +.PARAMETER WinUIMajorVersion + Specifies the WinUI major version to use when building for Uno. Also decides the package id and dependency variant. + +.NOTES + Author: Arlo Godfrey + Date: 6/6/2025 +#> +Param ( + [ValidateSet('all', 'wasm', 'uwp', 'wasdk', 'wpf', 'linuxgtk', 'macos', 'ios', 'android', 'netstandard')] + [Alias("mt")] + [Parameter(Mandatory=$true)] + [string[]]$MultiTargets, + + [Alias("c")] + [Parameter(Mandatory=$true)] + [string[]]$Components, + + [Alias("winui")] + [Parameter(Mandatory=$true)] + [int]$WinUIMajorVersion +) + +if ($MultiTargets -eq 'all') { + $MultiTargets = @('wasm', 'uwp', 'wasdk', 'wpf', 'linuxgtk', 'macos', 'ios', 'android', 'netstandard') +} + +$supportedComponents = @(); + +if ($Components -eq @('all')) { + $Components = @('**') +} + +foreach ($ComponentName in $Components) { + # Find all components source csproj (when wildcard), or find specific component csproj by name. + $path = "$PSScriptRoot/../../components/$ComponentName/src/*.csproj" + + foreach ($componentCsproj in Get-ChildItem -Path $path) { + # Get component name from csproj path + $componentPath = Get-Item "$componentCsproj/../../" + $componentName = $($componentPath.BaseName); + + # Get supported MultiTarget for this component + $supportedMultiTargets = & $PSScriptRoot\Get-MultiTargets.ps1 -component $componentName + + $componentSupportResult = & $PSScriptRoot\Test-Component-Support.ps1 ` + -RequestedMultiTargets $MultiTargets ` + -SupportedMultiTargets $supportedMultiTargets ` + -Component $componentName ` + -WinUIMajorVersion $WinUIMajorVersion + + if ($componentSupportResult.IsSupported -eq $true) { + $supportedComponents += $componentName + } + } +} + + +return $supportedComponents; \ No newline at end of file From c33eb11ee40be83a0bdfd6226155e33507862324 Mon Sep 17 00:00:00 2001 From: Arlo Date: Sat, 7 Jun 2025 12:21:25 -0500 Subject: [PATCH 3/5] Update MultiTarget/Test-Component-Support.ps1 --- MultiTarget/Test-Component-Support.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MultiTarget/Test-Component-Support.ps1 b/MultiTarget/Test-Component-Support.ps1 index 19fe696b..51ef885b 100644 --- a/MultiTarget/Test-Component-Support.ps1 +++ b/MultiTarget/Test-Component-Support.ps1 @@ -106,7 +106,7 @@ foreach ($supportedMultiTarget in $supportedMultiTargets) { # If none of the requested targets are supported by the component, we can skip build to save time and avoid errors. if (-not $isRequestedTargetSupported) { $IsSupported = $false - $Reason = "None of the requested MultiTargets '$MultiTargets' are enabled for this component." + $Reason = "None of the requested MultiTargets '$RequestedMultiTargets' are enabled for this component." } if (-not $isWinUI0Supported -and $WinUIMajorVersion -eq 0) { From 7b48ffcdf58f2011040a1d2ba14f7fbb09cfa93c Mon Sep 17 00:00:00 2001 From: Arlo Date: Mon, 9 Jun 2025 12:12:32 -0500 Subject: [PATCH 4/5] Fix invalid relative script path --- MultiTarget/Test-Component-Support.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MultiTarget/Test-Component-Support.ps1 b/MultiTarget/Test-Component-Support.ps1 index 51ef885b..a3dd3923 100644 --- a/MultiTarget/Test-Component-Support.ps1 +++ b/MultiTarget/Test-Component-Support.ps1 @@ -73,7 +73,7 @@ if ($null -ne $SupportedMultiTargets -and $SupportedMultiTargets.Count -gt 0) { Write-Error "Component name must be specified to retrieve supported MultiTargets." exit 1 } - $supportedMultiTargets = & $PSScriptRoot\MultiTarget\Get-MultiTargets.ps1 -component $Component + $supportedMultiTargets = & $PSScriptRoot\Get-MultiTargets.ps1 -component $Component } From a14c5492d3e13d09d5434e31f3f2afbfc18436fc Mon Sep 17 00:00:00 2001 From: Arlo Date: Mon, 9 Jun 2025 12:16:09 -0500 Subject: [PATCH 5/5] Update examples in Test-Component-Support.ps1 to clarify usage for component testing with WinUI --- MultiTarget/Test-Component-Support.ps1 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/MultiTarget/Test-Component-Support.ps1 b/MultiTarget/Test-Component-Support.ps1 index a3dd3923..3844dedd 100644 --- a/MultiTarget/Test-Component-Support.ps1 +++ b/MultiTarget/Test-Component-Support.ps1 @@ -18,9 +18,14 @@ Specifies the WinUI major version to use when building for Uno. Also decides the package id and dependency variant. .EXAMPLE - Build-Toolkit-Components -MultiTargets 'uwp', 'wasm' -DateForVersion '220101' -PreviewVersion 'local' -NupkgOutput 'C:\Output' -BinlogOutput 'C:\Logs' -EnableBinLogs -Components 'MyComponent1', 'MyComponent2' -ExcludeComponents 'MyComponent3' -Release -Verbose + Test-Component-Support -RequestedMultiTargets 'uwp', 'wasm' -Component 'MarkdownTextBlock' -WinUIMajorVersion 2 - Builds the 'MyComponent1' and 'MyComponent2' components for the 'uwp' and 'wasm' target frameworks with version '220101' and preview version 'local'. The 'MyComponent3' component will be excluded from building. The .nupkg files will be copied to 'C:\Output' and binlogs will be generated in 'C:\Logs'. The components will be built in Release configuration with detailed msbuild verbosity. + Tests if the 'MarkdownTextBlock' component supports the 'uwp' and 'wasm' target frameworks with WinUI 2. Returns an object indicating if the component is supported and the reason if not. + +.EXAMPLE + Test-Component-Support -SupportedMultiTargets 'uwp', 'wasm', 'wasdk' -RequestedMultiTargets 'all' -Component 'DataTable' -WinUIMajorVersion 3 + + Tests if the 'DataTable' component supports all target frameworks with WinUI 3, using the explicitly provided supported MultiTargets instead of retrieving them. .NOTES Author: Arlo Godfrey