diff --git a/Build-Toolkit-Components.ps1 b/Build-Toolkit-Components.ps1 index c517831..6cbc0ec 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/Filter-Supported-Components.ps1 b/MultiTarget/Filter-Supported-Components.ps1 new file mode 100644 index 0000000..bc187e8 --- /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 diff --git a/MultiTarget/Get-MultiTargets.ps1 b/MultiTarget/Get-MultiTargets.ps1 index 08569a4..19ffaec 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 0000000..3844ded --- /dev/null +++ b/MultiTarget/Test-Component-Support.ps1 @@ -0,0 +1,136 @@ +<# +.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 + Test-Component-Support -RequestedMultiTargets 'uwp', 'wasm' -Component 'MarkdownTextBlock' -WinUIMajorVersion 2 + + 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 + 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\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 '$RequestedMultiTargets' 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