diff options
| author | Adonais Romero González <[email protected]> | 2023-01-30 15:00:49 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-01-30 15:00:49 -0800 |
| commit | 07779ee84973f2f63a1f2ced6377463b1c01baaf (patch) | |
| tree | d28fc10efc8f5dee97ec5df162bb533f6e801585 | |
| parent | 2c0c8763300988d92ddd139cadf012f5ab1b12e1 (diff) | |
Build scripts update (#844)
---------
Co-authored-by: Jakob Lichtenberg (170957) <[email protected]>
| -rw-r--r-- | .github/README.md | 35 | ||||
| -rw-r--r-- | .github/scripts/Build-ChangedProjects.ps1 | 34 | ||||
| -rw-r--r-- | .github/scripts/Build-ChangedSamples.ps1 | 40 | ||||
| -rw-r--r-- | .github/workflows/Code-Scanning.yml | 4 | ||||
| -rw-r--r-- | .github/workflows/ci-pr.yml | 10 | ||||
| -rw-r--r-- | .github/workflows/ci.yml | 6 | ||||
| -rw-r--r-- | Build-AllProjects.ps1 | 15 | ||||
| -rw-r--r-- | Build-AllSamples.ps1 | 57 | ||||
| -rw-r--r-- | Build-Project.ps1 | 64 | ||||
| -rw-r--r-- | Build-ProjectSet.ps1 | 65 | ||||
| -rw-r--r-- | Build-Sample.ps1 | 153 | ||||
| -rw-r--r-- | Build-SampleSet.ps1 | 190 | ||||
| -rw-r--r-- | Building-Locally.md | 57 |
13 files changed, 541 insertions, 189 deletions
diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 00000000..b7569139 --- /dev/null +++ b/.github/README.md @@ -0,0 +1,35 @@ +# Using GitHub actions for building drivers + +If you use GitHub to host your code, you can leverage [GitHub Actions](https://docs.github.com/en/actions) to create automated workflows to build your driver projects. + +`windows-2022` runner (provided by `windows-latest`) is configured with Windows Driver Kit version 22H2 and Visual Studio 2022 off the box, so most solutions can be built directly running `msbuild` directly. + +```yaml +name: Build all driver samples +on: + push: + branches: + - main +jobs: + build: + strategy: + matrix: + configuration: [Debug, Release] + platform: [x64] + runs-on: windows-2022 + env: + Solution_Path: path\to\driver\solution.sln + steps: + - name: Check out repository code + uses: actions/checkout@v3 + + - name: Add MSBuild to PATH + uses: microsoft/[email protected] + + - name: Build solution + run: | + msbuild $${{ env.Solution_Path }} -p:Configuration:${{ env.Configuration }} -p:Platform:${{ env.Platform }} + env: + Configuration: ${{ matrix.configuration }} + Platform: ${{ matrix.platform }} +``` diff --git a/.github/scripts/Build-ChangedProjects.ps1 b/.github/scripts/Build-ChangedProjects.ps1 deleted file mode 100644 index a13e3501..00000000 --- a/.github/scripts/Build-ChangedProjects.ps1 +++ /dev/null @@ -1,34 +0,0 @@ -param ( - [array]$ChangedFiles -) - -$root = (Get-Location).Path - -# To include in CI gate -$projectSet = @{} -foreach ($file in $ChangedFiles) -{ - if (-not (Test-Path $file)) { - Write-Output "`u{2754} Changed file $file cannot be found" - continue - } - $dir = (Get-Item $file).DirectoryName - while ((-not ($slnItems = (Get-ChildItem $dir '*.sln'))) -and ($dir -ne $root)) - { - $dir = (Get-Item $dir).Parent.FullName - } - if ($dir -eq $root) - { - Write-Output "`u{2754} Changed file $file does not match a project." - continue - } - $projectName = $dir.Replace($root, '').Trim('\').Replace('\', '.').ToLower() - Write-Output "`u{1F50E} Found project [$projectName] at $dir from changed file $file" - if (-not ($projectSet.ContainsKey($projectName))) - { - $projectSet[$projectName] = $dir - } -} - -.\Build-ProjectSet -ProjectSet $projectSet - diff --git a/.github/scripts/Build-ChangedSamples.ps1 b/.github/scripts/Build-ChangedSamples.ps1 new file mode 100644 index 00000000..82096cd6 --- /dev/null +++ b/.github/scripts/Build-ChangedSamples.ps1 @@ -0,0 +1,40 @@ +[CmdletBinding()] +param ( + [array]$ChangedFiles +) + +$Verbose = $false +if ($PSBoundParameters.ContainsKey('Verbose')) { + $Verbose = $PsBoundParameters.Get_Item('Verbose') +} + +$root = (Get-Location).Path + +# To include in CI gate +$sampleSet = @{} +foreach ($file in $ChangedFiles) +{ + if (-not (Test-Path $file)) { + Write-Verbose "`u{2754} Changed file $file cannot be found" + continue + } + $dir = (Get-Item $file).DirectoryName + while ((-not ($slnItems = (Get-ChildItem $dir '*.sln'))) -and ($dir -ne $root)) + { + $dir = (Get-Item $dir).Parent.FullName + } + if ($dir -eq $root) + { + Write-Verbose "`u{2754} Changed file $file does not match a sample." + continue + } + $sampleName = $dir.Replace($root, '').Trim('\').Replace('\', '.').ToLower() + Write-Verbose "`u{1F50E} Found sample [$sampleName] at $dir from changed file $file" + if (-not ($sampleSet.ContainsKey($sampleName))) + { + $sampleSet[$sampleName] = $dir + } +} + +.\Build-SampleSet -SampleSet $sampleSet -Verbose:$Verbose -LogFilesDirectory (Join-Path $root "_logs") + diff --git a/.github/workflows/Code-Scanning.yml b/.github/workflows/Code-Scanning.yml index 2993c393..b2c851b6 100644 --- a/.github/workflows/Code-Scanning.yml +++ b/.github/workflows/Code-Scanning.yml @@ -46,9 +46,9 @@ jobs: uses: microsoft/[email protected] - name: Retrieve and build all available solutions - id: build-all-projects + id: build-all-samples run: | - .\Build-AllProjects.ps1 + .\Build-AllSamples.ps1 env: Configuration: ${{ matrix.configuration }} Platform: ${{ matrix.platform }} diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index 931df9e4..c701bd23 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -15,8 +15,6 @@ jobs: configuration: [Debug, Release] platform: [x64, arm64] runs-on: windows-2022 - env: - Solution_Path: general\echo\kmdf\kmdfecho.sln steps: - name: Check out repository code uses: actions/checkout@v3 @@ -29,12 +27,14 @@ jobs: - name: Get changed files id: get-changed-files uses: tj-actions/changed-files@v27 + with: + separator: "," - name: Retrieve and build solutions from changed files - id: build-changed-projects + id: build-changed-samples run: | - $changedFiles = "${{ steps.get-changed-files.outputs.all_changed_files }}".Split(' ') - .\.github\scripts\Build-ChangedProjects.ps1 -ChangedFiles $changedFiles + $changedFiles = "${{ steps.get-changed-files.outputs.all_changed_files }}".Split(',') + .\.github\scripts\Build-ChangedSamples.ps1 -ChangedFiles $changedFiles -Verbose env: Configuration: ${{ matrix.configuration }} Platform: ${{ matrix.platform }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4c07460a..a8063d6e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,6 @@ jobs: configuration: [Debug, Release] platform: [x64, arm64] runs-on: windows-2022 - env: - Solution_Path: general\echo\kmdf\kmdfecho.sln steps: - name: Check out repository code uses: actions/checkout@v3 @@ -27,9 +25,9 @@ jobs: uses: microsoft/[email protected] - name: Retrieve and build all available solutions - id: build-all-projects + id: build-all-samples run: | - .\Build-AllProjects.ps1 + .\Build-AllSamples.ps1 -Verbose env: Configuration: ${{ matrix.configuration }} Platform: ${{ matrix.platform }} diff --git a/Build-AllProjects.ps1 b/Build-AllProjects.ps1 deleted file mode 100644 index 1c35d884..00000000 --- a/Build-AllProjects.ps1 +++ /dev/null @@ -1,15 +0,0 @@ -$root = Get-Location -$solutionFiles = Get-ChildItem -Path $root -Recurse -Filter *.sln | Select-Object -ExpandProperty FullName - -# To include in CI gate -$projectSet = @{} -foreach ($file in $solutionFiles) -{ - $dir = (Get-Item $file).DirectoryName - $dir_norm = $dir.Replace($root, '').Trim('\').Replace('\', '.').ToLower() - Write-Output "`u{1F50E} Found project [$dir_norm] at $dir" - $projectSet[$dir_norm] = $dir -} - -.\Build-ProjectSet -ProjectSet $projectSet - diff --git a/Build-AllSamples.ps1 b/Build-AllSamples.ps1 new file mode 100644 index 00000000..d857c641 --- /dev/null +++ b/Build-AllSamples.ps1 @@ -0,0 +1,57 @@ +<# +.SYNOPSIS +Builds all available sample solutions in the repository (excluding specific solutions). + +.DESCRIPTION +This script searches for all available Visual Studio Solutions (.sln files) and attempts to run MSBuild to build them for the specified configurations and platforms. + +.PARAMETER Configurations +A list of configurations to build samples under. Values available are "Debug" and "Release". By default, $env:Configuration will be used as the sole configuration to build for. If this value doesn't exist, "Debug" will be used instead. + +.PARAMETER Platforms +A list of platforms to build samples under (e.g. "x64", "arm64"). By default, $env:Platform will be used as the sole platform to build for. If this value doesn't exist, "x64" will be used instead. + +.PARAMETER LogFilesDirectory +Path to a directory where the log files will be written to. If not provided, outputs will be logged to the "_logs" directory within the current working directory. + +.INPUTS +None. + +.OUTPUTS +None. + +.EXAMPLE +.\Build-AllSamples + +.EXAMPLE +.\Build-AllSamples -Configurations 'Debug','Release' -Platforms 'x64','arm64' -LogFilesDirectory .\_logs + +#> + +[CmdletBinding()] +param( + [string[]]$Configurations = @([string]::IsNullOrEmpty($env:Configuration) ? "Debug" : $env:Configuration), + [string[]]$Platforms = @([string]::IsNullOrEmpty($env:Platform) ? "x64" : $env:Platform), + [string]$LogFilesDirectory = (Join-Path (Get-Location) "_logs") +) + +$Verbose = $false +if ($PSBoundParameters.ContainsKey('Verbose')) { + $Verbose = $PsBoundParameters.Get_Item('Verbose') +} + +$root = Get-Location +$solutionFiles = Get-ChildItem -Path $root -Recurse -Filter *.sln | Select-Object -ExpandProperty FullName + +# To include in CI gate +$sampleSet = @{} +foreach ($file in $solutionFiles) { + $dir = (Get-Item $file).DirectoryName + $dir_norm = $dir.Replace($root, '').Trim('\').Replace('\', '.').ToLower() + Write-Verbose "`u{1F50E} Found sample [$dir_norm] at $dir" + $sampleSet[$dir_norm] = $dir +} + + + +.\Build-SampleSet -SampleSet $sampleSet -Configurations $Configurations -Platform $Platforms -LogFilesDirectory $LogFilesDirectory -Verbose:$Verbose diff --git a/Build-Project.ps1 b/Build-Project.ps1 deleted file mode 100644 index b01d13a8..00000000 --- a/Build-Project.ps1 +++ /dev/null @@ -1,64 +0,0 @@ -param( - $Directory, - [string]$ProjectName, - $LogFilesDirectory = "_logfiles", - [string]$Configuration = "Debug", - [string]$Platform = "x64" -) - -# TODO Validate $Directory and $LogFilesDirectory -New-Item -ItemType Directory -Force -Path $LogFilesDirectory | Out-Null - -if ([string]::IsNullOrWhitespace($ProjectName)) -{ - $ProjectName = (Resolve-Path $Directory).Path.Replace((Get-Location), '').Replace('\', '.').Trim('.').ToLower() -} - -$solutionFile = Get-ChildItem -Path $Directory -Filter *.sln | Select-Object -ExpandProperty FullName -First 1 - -$configurationIsSupported = $false -$inSolutionConfigurationPlatformsSection = $false -foreach ($line in Get-Content -Path $solutionFile) -{ - if (-not $inSolutionConfigurationPlatformsSection -and $line -match "\s*GlobalSection\(SolutionConfigurationPlatforms\).*") - { - $inSolutionConfigurationPlatformsSection = $true; - continue; - } - elseif ($line -match "\s*EndGlobalSection.*") - { - $inSolutionConfigurationPlatformsSection = $false; - continue; - } - - if ($inSolutionConfigurationPlatformsSection) - { - [regex]$regex = ".*=\s*(?<ConfigString>(?<Configuration>.*)\|(?<Platform>.*))\s*" - $match = $regex.Match($line) - if ([string]::IsNullOrWhiteSpace($match.Groups["ConfigString"].Value) -or [string]::IsNullOrWhiteSpace($match.Groups["Platform"].Value)) - { - Write-Warning "Could not parse configuration entry $line from file $solutionFile." - continue; - } - if ($match.Groups["Configuration"].Value.Trim() -eq $Configuration -and $match.Groups["Platform"].Value.Trim() -eq $Platform) - { - $configurationIsSupported = $true; - } - } -} - -if (-not $configurationIsSupported) -{ - Write-Output "[$ProjectName] `u{23E9} Skipped. Configuration $Configuration|$Platform not supported." - exit 0 -} - -$errorLogFilePath = "$LogFilesDirectory\$ProjectName.err" -$warnLogFilePath = "$LogFilesDirectory\$ProjectName.wrn" -Write-Output "[$ProjectName] `u{2692} Building project..." -msbuild $solutionFile -clp:Verbosity=m -t:clean,build -property:Configuration=$Configuration -property:Platform=$Platform -p:TargetVersion=Windows10 -p:InfVerif_AdditionalOptions="/msft /sw1205 /sw1324 /sw1420 /sw1421" -p:SignToolWS=/fdws -p:DriverCFlagAddOn=/wd4996 -flp1:errorsonly`;logfile=$errorLogFilePath -flp2:WarningsOnly`;logfile=$warnLogFilePath -noLogo -if ($LASTEXITCODE -ne 0) -{ - Write-Warning "`u{274C} Build failed. Log available at $errorLogFilePath" - exit 1 -} diff --git a/Build-ProjectSet.ps1 b/Build-ProjectSet.ps1 deleted file mode 100644 index 2557b5b9..00000000 --- a/Build-ProjectSet.ps1 +++ /dev/null @@ -1,65 +0,0 @@ -param( - [hashtable]$ProjectSet, - [string]$Configuration = $env:Configuration, - [string]$Platform = $env:Platform -) - -if ([string]::IsNullOrEmpty($Configuration)) -{ - $Configuration = "Debug" -} - -if ([string]::IsNullOrEmpty($Platform)) -{ - $Platform = "x64" -} - -$oldPreference = $ErrorActionPreference -$ErrorActionPreference = "stop" -try -{ - # Check that msbuild can be called before trying anything. - Get-Command "msbuild" | Out-Null -} -catch -{ - Write-Host "`u{274C} msbuild cannot be called from current environment. Check that msbuild is set in current path (for example, that it is called from a Visual Studio developer command)." - Write-Error "msbuild cannot be called from current environment." - exit 1 -} -finally -{ - $ErrorActionPreference = $oldPreference -} - - -$exclusionsSet = @{} -$failSet = @() -Import-Csv 'exclusions.csv' | ForEach-Object { - $exclusionsSet[$_.Path.Replace($root, '').Trim('\').Replace('\', '.').ToLower()] = $_.Reason -} - -$ProjectSet.GetEnumerator() | ForEach-Object { - $projectName = $_.Key - if ($exclusionsSet.ContainsKey($projectName)) - { - Write-Output "[$projectName] `u{23E9} Excluded and skipped. Reason: $($exclusionsSet[$projectName])" - return; - } - $directory = $_.Value - .\Build-Project -Directory $directory -ProjectName $ProjectName -Configuration $Configuration -Platform $Platform - if ($LASTEXITCODE -ne 0) - { - $failSet += $ProjectName - } -} - -if ($failSet.Count -gt 0) -{ - Write-Output "Some projects were built with errors:" - foreach ($failedProject in $failSet) - { - Write-Output "$failedProject" - } - Write-Error "Some projects were built with errors." -}
\ No newline at end of file diff --git a/Build-Sample.ps1 b/Build-Sample.ps1 new file mode 100644 index 00000000..57f0ce7e --- /dev/null +++ b/Build-Sample.ps1 @@ -0,0 +1,153 @@ +<# +.SYNOPSIS +Builds an specific directory containing a sample solution. + +.DESCRIPTION +This script attempts to build a directory containing a driver sample Solution for the specified configurations and platforms. + +.PARAMETER Directory +Path to a directory containing a valid Visual Studio Solution (.sln file). This is the solution that will be built. + +.PARAMETER SampleName +A friendly name to refer to the sample. Is unspecified, a name will be automatically generated one from the sample path. + +.PARAMETER Configuration +Configuration name that will be used to build the solution. Common available values are "Debug" and "Release". + +.PARAMETER Platform +Platform to build the solution for (e.g. "x64", "arm64"). + +.PARAMETER LogFilesDirectoy +Path to a directory where the log files will be written to. If not provided, outputs will be logged to the current working directory. + +.INPUTS +None. + +.OUTPUTS +Verbose output about the execution of this script will be provided only if -Verbose is provided. Otherwise, no output will be generated. + +.EXAMPLE +.\Build-Sample -Directory .\usb\kmdf_fx2 + +.EXAMPLE +.\Build-Sample -Directory .\usb\kmdf_fx2 -Configuration 'Release' -Platform 'x64' -Verbose -LogFilesDirectory .\_logs + +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $true, + HelpMessage = 'Enter one directory path', + Position = 0)] + [string]$Directory, + [string]$SampleName, + [string]$Configuration = "Debug", + [string]$Platform = "x64", + $LogFilesDirectory = (Get-Location) +) + +$Verbose = $false +if ($PSBoundParameters.ContainsKey('Verbose')) { + $Verbose = $PsBoundParameters.Get_Item('Verbose') +} + +$oldPreference = $ErrorActionPreference +$ErrorActionPreference = "stop" +try +{ + # Check that msbuild can be called before trying anything. + Get-Command "msbuild" | Out-Null +} +catch +{ + Write-Verbose "`u{274C} msbuild cannot be called from current environment. Check that msbuild is set in current path (for example, that it is called from a Visual Studio developer command)." + Write-Error "msbuild cannot be called from current environment." + exit 1 +} +finally +{ + $ErrorActionPreference = $oldPreference +} + +if (-not (Test-Path -Path $Directory -PathType Container)) +{ + Write-Warning "`u{274C} A valid directory could not be found under $Directory" + exit 1 +} + +New-Item -ItemType Directory -Force -Path $LogFilesDirectory | Out-Null + +if (-not (Test-Path -Path $LogFilesDirectory -PathType Container)) +{ + Write-Warning "`u{274C} A valid directory for storing log files could not be created under $LogFilesDirectory" + # No exit here: process will continue but logs won't be available. +} + +if ([string]::IsNullOrWhitespace($SampleName)) +{ + $SampleName = (Resolve-Path $Directory).Path.Replace((Get-Location), '').Replace('\', '.').Trim('.').ToLower() +} + +$solutionFile = Get-ChildItem -Path $Directory -Filter *.sln | Select-Object -ExpandProperty FullName -First 1 + +if ($null -eq $solutionFile) +{ + Write-Warning "`u{274C} A solution could not be found under $Directory" + exit 1 +} + +$configurationIsSupported = $false +$inSolutionConfigurationPlatformsSection = $false +foreach ($line in Get-Content -Path $solutionFile) +{ + if (-not $inSolutionConfigurationPlatformsSection -and $line -match "\s*GlobalSection\(SolutionConfigurationPlatforms\).*") + { + $inSolutionConfigurationPlatformsSection = $true; + continue; + } + elseif ($line -match "\s*EndGlobalSection.*") + { + $inSolutionConfigurationPlatformsSection = $false; + continue; + } + + if ($inSolutionConfigurationPlatformsSection) + { + [regex]$regex = ".*=\s*(?<ConfigString>(?<Configuration>.*)\|(?<Platform>.*))\s*" + $match = $regex.Match($line) + if ([string]::IsNullOrWhiteSpace($match.Groups["ConfigString"].Value) -or [string]::IsNullOrWhiteSpace($match.Groups["Platform"].Value)) + { + Write-Warning "Could not parse configuration entry $line from file $solutionFile." + continue; + } + if ($match.Groups["Configuration"].Value.Trim() -eq $Configuration -and $match.Groups["Platform"].Value.Trim() -eq $Platform) + { + $configurationIsSupported = $true; + } + } +} + +if (-not $configurationIsSupported) +{ + Write-Verbose "[$SampleName] `u{23E9} Skipped. Configuration $Configuration|$Platform not supported." + exit 2 +} + +$errorLogFilePath = "$LogFilesDirectory\$SampleName.$Configuration.$Platform.err" +$warnLogFilePath = "$LogFilesDirectory\$SampleName.$Configuration.$Platform.wrn" +$OutLogFilePath = "$LogFilesDirectory\$SampleName.$Configuration.$Platform.out" + +Write-Verbose "Building Sample: $SampleName; Configuration: $Configuration; Platform: $Platform {" + +msbuild $solutionFile -clp:Verbosity=m -t:clean,build -property:Configuration=$Configuration -property:Platform=$Platform -p:TargetVersion=Windows10 -p:InfVerif_AdditionalOptions="/msft /sw1205 /sw1324 /sw1420 /sw1421" -p:SignToolWS=/fdws -p:DriverCFlagAddOn=/wd4996 -flp1:errorsonly`;logfile=$errorLogFilePath -flp2:WarningsOnly`;logfile=$warnLogFilePath -noLogo > $OutLogFilePath + +if ($LASTEXITCODE -ne 0) +{ + if ($Verbose) + { + Write-Warning "`u{274C} Build failed. Log available at $errorLogFilePath" + } + exit 1 +} + +Write-Verbose "Building Sample: $SampleName; Configuration: $Configuration; Platform: $Platform }" diff --git a/Build-SampleSet.ps1 b/Build-SampleSet.ps1 new file mode 100644 index 00000000..8ab2d4e5 --- /dev/null +++ b/Build-SampleSet.ps1 @@ -0,0 +1,190 @@ +[CmdletBinding()] +param( + [hashtable]$SampleSet, + [string[]]$Configurations = @([string]::IsNullOrEmpty($env:Configuration) ? "Debug" : $env:Configuration), + [string[]]$Platforms = @([string]::IsNullOrEmpty($env:Platform) ? "x64" : $env:Platform), + $LogFilesDirectory = (Get-Location) +) + +$Verbose = $false +if ($PSBoundParameters.ContainsKey('Verbose')) { + $Verbose = $PsBoundParameters.Get_Item('Verbose') +} + +New-Item -ItemType Directory -Force -Path $LogFilesDirectory | Out-Null +$sampleBuilderFilePath = "$LogFilesDirectory\overview.htm" + + +Remove-Item -Recurse -Path $LogFilesDirectory 2>&1 | Out-Null +New-Item -ItemType Directory -Force -Path $LogFilesDirectory | Out-Null + +$NumberOfLogicalProcessors = (Get-CIMInstance -Class 'CIM_Processor' -Verbose:$false).NumberOfLogicalProcessors +$SolutionsInParallel = 5 * $NumberOfLogicalProcessors + +Write-Verbose "Log files directory: $LogFilesDirectory" +Write-Verbose "Results overview report: $sampleBuilderFilePath" +Write-Verbose "Logical Processors: $NumberOfLogicalProcessors" +Write-Verbose "Solutions in Parallel: $SolutionsInParallel" + +$oldPreference = $ErrorActionPreference +$ErrorActionPreference = "stop" +try { + # Check that msbuild can be called before trying anything. + Get-Command "msbuild" | Out-Null +} +catch { + Write-Host "`u{274C} msbuild cannot be called from current environment. Check that msbuild is set in current path (for example, that it is called from a Visual Studio developer command)." + Write-Error "msbuild cannot be called from current environment." + exit 1 +} +finally { + $ErrorActionPreference = $oldPreference +} + +# TODO: Make exclusion more granular; allow for configuration|platform exclusions +$exclusionsSet = @{} +$failSet = @() +Import-Csv 'exclusions.csv' | ForEach-Object { + $exclusionsSet[$_.Path.Replace($root, '').Trim('\').Replace('\', '.').ToLower()] = $_.Reason +} + +$jresult = @{ + SolutionsBuilt = 0 + SolutionsExcluded = 0 + SolutionsFailed = 0 + Results = @() + lock = [System.Threading.Mutex]::new($false) +} + +$SolutionsTotal = $sampleSet.Count * $Configurations.Count * $Platforms.Count + +Write-Output "T: Total solutions: $SolutionsTotal" +Write-Output "B: Built" +Write-Output "R: Build is running currently" +Write-Output "P: Build is pending an available build slot" +Write-Output "" +Write-Output "S: Built and result was 'Succeeded'" +Write-Output "E: Built and result was 'Excluded'" +Write-Output "U: Built and result was 'Unsupported' (Platform and Configuration combination)" +Write-Output "F: Built and result was 'Failed'" +Write-Output "" +Write-Output "Building driver solutions..." + +$Results = @() + +$sw = [Diagnostics.Stopwatch]::StartNew() + +$SampleSet.GetEnumerator() | ForEach-Object -ThrottleLimit $SolutionsInParallel -Parallel { + $LogFilesDirectory = $using:LogFilesDirectory + $exclusionsSet = $using:exclusionsSet + $Configurations = $using:Configurations + $Platforms = $using:Platforms + + $sampleName = $_.Key + $directory = $_.Value + + $ResultElement = new-object psobject + Add-Member -InputObject $ResultElement -MemberType NoteProperty -Name Sample -Value "$sampleName" + + foreach ($configuration in $Configurations) { + foreach ($platform in $Platforms) { + $thisunsupported = 0 + $thisfailed = 0 + $thisexcluded = 0 + $thissucceeded = 0 + $thisresult = "Not run" + + if ($exclusionsSet.ContainsKey($sampleName)) { + # Verbose + if ($thisexcluded -eq 0) { + Write-Verbose "[$sampleName] `u{23E9} Excluded and skipped. Reason: $($exclusionsSet[$sampleName])" + } + $thisexcluded += 1 + $thisresult = "Excluded" + } + else { + .\Build-Sample -Directory $directory -SampleName $sampleName -LogFilesDirectory $LogFilesDirectory -Configuration $configuration -Platform $platform -Verbose:$Verbose + if ($LASTEXITCODE -eq 0) { + $thissucceeded += 1 + $thisresult = "Succeeded" + } + elseif ($LASTEXITCODE -eq 1) { + $failSet += "$sampleName $configuration|$platform" + $thisfailed += 1 + $thisresult = "Failed" + } + else { + # ($LASTEXITCODE -eq 2) + $thisunsupported += 1 + $thisresult = "Unsupported" + } + } + Add-Member -InputObject $ResultElement -MemberType NoteProperty -Name "$configuration|$platform" -Value "$thisresult" + + $null = ($using:jresult).lock.WaitOne() + try { + ($using:jresult).SolutionsBuilt += 1 + ($using:jresult).SolutionsSucceeded += $thissucceeded + ($using:jresult).SolutionsExcluded += $thisexcluded + ($using:jresult).SolutionsUnsupported += $thisunsupported + ($using:jresult).SolutionsFailed += $thisfailed + $SolutionsTotal = $using:SolutionsTotal + $SolutionsInParallel = $using:SolutionsInParallel + $SolutionsBuilt = ($using:jresult).SolutionsBuilt + $SolutionsRemaining = $SolutionsTotal - $SolutionsBuilt + $SolutionsRunning = $SolutionsRemaining -ge $SolutionsInParallel ? ($SolutionsInParallel) : ($SolutionsRemaining) + $SolutionsPending = $SolutionsRemaining -ge $SolutionsInParallel ? ($SolutionsRemaining - $SolutionsInParallel) : (0) + $SolutionsBuiltPercent = [Math]::Round(100 * ($SolutionsBuilt / $using:SolutionsTotal)) + $TBRP = "T:" + ($SolutionsTotal) + "; B:" + (($using:jresult).SolutionsBuilt) + "; R:" + ($SolutionsRunning) + "; P:" + ($SolutionsPending) + $rstr = "S:" + (($using:jresult).SolutionsSucceeded) + "; E:" + (($using:jresult).SolutionsExcluded) + "; U:" + (($using:jresult).SolutionsUnsupported) + "; F:" + (($using:jresult).SolutionsFailed) + Write-Progress -Activity "Building driver solutions" -Status "$SolutionsBuilt of $using:SolutionsTotal solutions built ($SolutionsBuiltPercent%) | $TBRP | $rstr" -PercentComplete $SolutionsBuiltPercent + } + finally { + ($using:jresult).lock.ReleaseMutex() + } + } + } + $null = ($using:jresult).lock.WaitOne() + try { + ($using:jresult).Results += $ResultElement + } + finally { + ($using:jresult).lock.ReleaseMutex() + } +} + +$sw.Stop() + +if ($failSet.Count -gt 0) { + Write-Output "Some samples were built with errors:" + foreach ($failedSample in $failSet) { + Write-Output "$failedSample" + } + Write-Error "Some samples were built with errors." +} + +# Display timer statistics to host +$min = $sw.Elapsed.Minutes +$seconds = $sw.Elapsed.Seconds + +$SolutionsSucceeded = $jresult.SolutionsSucceeded +$SolutionsExcluded = $jresult.SolutionsExcluded +$SolutionsUnsupported = $jresult.SolutionsUnsupported +$SolutionsFailed = $jresult.SolutionsFailed +$Results = $jresult.Results + +Write-Output "" +Write-Output "Built solutions." +Write-Output "" +Write-Output "Total elapsed time: $min minutes, $seconds seconds." +Write-Output "SolutionsTotal: $SolutionsTotal" +Write-Output "SolutionsSucceeded: $SolutionsSucceeded" +Write-Output "SolutionsExcluded: $SolutionsExcluded" +Write-Output "SolutionsUnsupported: $SolutionsUnsupported" +Write-Output "SolutionsFailed: $SolutionsFailed" +Write-Output "" +Write-Output "Results saved to $sampleBuilderFilePath" +Write-Output "" + +$Results | Sort-Object { $_.Sample } | ConvertTo-Html -Title "Overview" | Out-File $sampleBuilderFilePath +Invoke-Item $sampleBuilderFilePath diff --git a/Building-Locally.md b/Building-Locally.md new file mode 100644 index 00000000..df8c0093 --- /dev/null +++ b/Building-Locally.md @@ -0,0 +1,57 @@ +# How to build locally + +## Step 1: Install git and pwsh 7.3.0 +``` +winget install --id Microsoft.Powershell --source winget +winget install --id Git.Git --source winget` +``` + +## Step 2: Create a "driver build environment" + +There are multiple ways to achieve this. For example, [install Visual Studio and the Windows Driver Kit](https://learn.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk#download-and-install-the-windows-11-version-22h2-wdk). You can just download and mount the EWDK as well. + +In the following example that is what we will do: + * Download the Windows 11, version 22H2 EWDK ISO image from the [official site](https://learn.microsoft.com/en-us/legal/windows/hardware/enterprise-wdk-license-2022) + * Mount ISO image + * From a terminal, run `.\LaunchBuildEnv` + +## Step 3: Clone Windows Driver Samples and checkout main branch + +``` +cd path\to\your\repos +git clone --recurse-submodules https://github.com/microsoft/Windows-driver-samples.git +cd Windows-driver-samples +``` + +## Step 4: Check all samples builds with expected results for all flavors + +``` +pwsh +.\Build-AllSamples.ps1 -Configurations 'Debug','Release' -Platforms 'x64','arm64' -LogFilesDirectory '_logs' +``` + +Expected output: +``` +T: Total solutions: 612 +B: Built +R: Build is running currently +P: Build is pending an available build slot + +S: Built and result was 'Succeeded' +E: Built and result was 'Excluded' +U: Built and result was 'Unsupported' (Platform and Configuration combination) +F: Built and result was 'Failed' + +Building driver solutions... + +Built solutions. + +Total elapsed time: 11 minutes, 18 seconds. +SolutionsTotal: 612 +SolutionsSucceeded: 316 +SolutionsExcluded: 56 +SolutionsUnsupported: 240 +SolutionsFailed: 0 + +Results saved to _logs\overview.htm +```
\ No newline at end of file |
