12ccfa855SEd Maste # Copyright (c) 2021-2022 Yubico AB. All rights reserved. 2f540a430SEd Maste # Use of this source code is governed by a BSD-style 3f540a430SEd Maste # license that can be found in the LICENSE file. 42ccfa855SEd Maste # SPDX-License-Identifier: BSD-2-Clause 5f540a430SEd Maste 60afa8e06SEd Maste param( 70afa8e06SEd Maste [string]$CMakePath = "C:\Program Files\CMake\bin\cmake.exe", 80afa8e06SEd Maste [string]$GitPath = "C:\Program Files\Git\bin\git.exe", 90afa8e06SEd Maste [string]$SevenZPath = "C:\Program Files\7-Zip\7z.exe", 100afa8e06SEd Maste [string]$GPGPath = "C:\Program Files (x86)\GnuPG\bin\gpg.exe", 110afa8e06SEd Maste [string]$WinSDK = "", 12f540a430SEd Maste [string]$Config = "Release", 13f540a430SEd Maste [string]$Arch = "x64", 14f540a430SEd Maste [string]$Type = "dynamic", 150afa8e06SEd Maste [string]$Fido2Flags = "" 160afa8e06SEd Maste ) 170afa8e06SEd Maste 18f540a430SEd Maste $ErrorActionPreference = "Stop" 190afa8e06SEd Maste [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 200afa8e06SEd Maste 21f540a430SEd Maste . "$PSScriptRoot\const.ps1" 220afa8e06SEd Maste 23f540a430SEd Maste Function ExitOnError() { 24f540a430SEd Maste if ($LastExitCode -ne 0) { 25f540a430SEd Maste throw "A command exited with status $LastExitCode" 26f540a430SEd Maste } 27f540a430SEd Maste } 280afa8e06SEd Maste 29f540a430SEd Maste Function GitClone(${REPO}, ${BRANCH}, ${DIR}) { 30f540a430SEd Maste Write-Host "Cloning ${REPO}..." 31f540a430SEd Maste & $Git -c advice.detachedHead=false clone --quiet --depth=1 ` 32f540a430SEd Maste --branch "${BRANCH}" "${REPO}" "${DIR}" 33f540a430SEd Maste Write-Host "${REPO}'s ${BRANCH} HEAD is:" 34f540a430SEd Maste & $Git -C "${DIR}" show -s HEAD 350afa8e06SEd Maste } 360afa8e06SEd Maste 370afa8e06SEd Maste # Find Git. 38f540a430SEd Maste $Git = $(Get-Command git -ErrorAction Ignore | ` 39f540a430SEd Maste Select-Object -ExpandProperty Source) 400afa8e06SEd Maste if ([string]::IsNullOrEmpty($Git)) { 410afa8e06SEd Maste $Git = $GitPath 420afa8e06SEd Maste } 43f540a430SEd Maste if (-Not (Test-Path $Git)) { 44f540a430SEd Maste throw "Unable to find Git at $Git" 45f540a430SEd Maste } 46f540a430SEd Maste 47f540a430SEd Maste # Find CMake. 48f540a430SEd Maste $CMake = $(Get-Command cmake -ErrorAction Ignore | ` 49f540a430SEd Maste Select-Object -ExpandProperty Source) 50f540a430SEd Maste if ([string]::IsNullOrEmpty($CMake)) { 51f540a430SEd Maste $CMake = $CMakePath 52f540a430SEd Maste } 53f540a430SEd Maste if (-Not (Test-Path $CMake)) { 54f540a430SEd Maste throw "Unable to find CMake at $CMake" 55f540a430SEd Maste } 560afa8e06SEd Maste 570afa8e06SEd Maste # Find 7z. 58f540a430SEd Maste $SevenZ = $(Get-Command 7z -ErrorAction Ignore | ` 59f540a430SEd Maste Select-Object -ExpandProperty Source) 600afa8e06SEd Maste if ([string]::IsNullOrEmpty($SevenZ)) { 610afa8e06SEd Maste $SevenZ = $SevenZPath 620afa8e06SEd Maste } 63f540a430SEd Maste if (-Not (Test-Path $SevenZ)) { 64f540a430SEd Maste throw "Unable to find 7z at $SevenZ" 65f540a430SEd Maste } 660afa8e06SEd Maste 670afa8e06SEd Maste # Find GPG. 68f540a430SEd Maste $GPG = $(Get-Command gpg -ErrorAction Ignore | ` 69f540a430SEd Maste Select-Object -ExpandProperty Source) 700afa8e06SEd Maste if ([string]::IsNullOrEmpty($GPG)) { 710afa8e06SEd Maste $GPG = $GPGPath 720afa8e06SEd Maste } 73f540a430SEd Maste if (-Not (Test-Path $GPG)) { 74f540a430SEd Maste throw "Unable to find GPG at $GPG" 75f540a430SEd Maste } 760afa8e06SEd Maste 770afa8e06SEd Maste # Override CMAKE_SYSTEM_VERSION if $WinSDK is set. 780afa8e06SEd Maste if (-Not ([string]::IsNullOrEmpty($WinSDK))) { 790afa8e06SEd Maste $CMAKE_SYSTEM_VERSION = "-DCMAKE_SYSTEM_VERSION='$WinSDK'" 800afa8e06SEd Maste } else { 810afa8e06SEd Maste $CMAKE_SYSTEM_VERSION = '' 820afa8e06SEd Maste } 830afa8e06SEd Maste 84f540a430SEd Maste Write-Host "WinSDK: $WinSDK" 85f540a430SEd Maste Write-Host "Config: $Config" 86f540a430SEd Maste Write-Host "Arch: $Arch" 87f540a430SEd Maste Write-Host "Type: $Type" 880afa8e06SEd Maste Write-Host "Git: $Git" 890afa8e06SEd Maste Write-Host "CMake: $CMake" 900afa8e06SEd Maste Write-Host "7z: $SevenZ" 910afa8e06SEd Maste Write-Host "GPG: $GPG" 920afa8e06SEd Maste 93f540a430SEd Maste # Create build directories. 94f540a430SEd Maste New-Item -Type Directory "${BUILD}" -Force 95f540a430SEd Maste New-Item -Type Directory "${BUILD}\${Arch}" -Force 96f540a430SEd Maste New-Item -Type Directory "${BUILD}\${Arch}\${Type}" -Force 97f540a430SEd Maste New-Item -Type Directory "${STAGE}\${LIBRESSL}" -Force 98f540a430SEd Maste New-Item -Type Directory "${STAGE}\${LIBCBOR}" -Force 99f540a430SEd Maste New-Item -Type Directory "${STAGE}\${ZLIB}" -Force 1000afa8e06SEd Maste 101f540a430SEd Maste # Create output directories. 102f540a430SEd Maste New-Item -Type Directory "${OUTPUT}" -Force 103f540a430SEd Maste New-Item -Type Directory "${OUTPUT}\${Arch}" -Force 104f540a430SEd Maste New-Item -Type Directory "${OUTPUT}\${Arch}\${Type}" -force 105f540a430SEd Maste 106f540a430SEd Maste # Fetch and verify dependencies. 1070afa8e06SEd Maste Push-Location ${BUILD} 1080afa8e06SEd Maste try { 109f540a430SEd Maste if (-Not (Test-Path .\${LIBRESSL})) { 1100afa8e06SEd Maste if (-Not (Test-Path .\${LIBRESSL}.tar.gz -PathType leaf)) { 1110afa8e06SEd Maste Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz ` 1120afa8e06SEd Maste -OutFile .\${LIBRESSL}.tar.gz 1130afa8e06SEd Maste } 1140afa8e06SEd Maste if (-Not (Test-Path .\${LIBRESSL}.tar.gz.asc -PathType leaf)) { 1150afa8e06SEd Maste Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz.asc ` 1160afa8e06SEd Maste -OutFile .\${LIBRESSL}.tar.gz.asc 1170afa8e06SEd Maste } 1180afa8e06SEd Maste 1190afa8e06SEd Maste Copy-Item "$PSScriptRoot\libressl.gpg" -Destination "${BUILD}" 1200afa8e06SEd Maste & $GPG --list-keys 121f540a430SEd Maste & $GPG --quiet --no-default-keyring --keyring ./libressl.gpg ` 1220afa8e06SEd Maste --verify .\${LIBRESSL}.tar.gz.asc .\${LIBRESSL}.tar.gz 1230afa8e06SEd Maste if ($LastExitCode -ne 0) { 1240afa8e06SEd Maste throw "GPG signature verification failed" 1250afa8e06SEd Maste } 1260afa8e06SEd Maste & $SevenZ e .\${LIBRESSL}.tar.gz 1270afa8e06SEd Maste & $SevenZ x .\${LIBRESSL}.tar 1280afa8e06SEd Maste Remove-Item -Force .\${LIBRESSL}.tar 1290afa8e06SEd Maste } 130f540a430SEd Maste if (-Not (Test-Path .\${LIBCBOR})) { 131f540a430SEd Maste GitClone "${LIBCBOR_GIT}" "${LIBCBOR_BRANCH}" ".\${LIBCBOR}" 132f540a430SEd Maste } 1330afa8e06SEd Maste if (-Not (Test-Path .\${ZLIB})) { 134f540a430SEd Maste GitClone "${ZLIB_GIT}" "${ZLIB_BRANCH}" ".\${ZLIB}" 1350afa8e06SEd Maste } 1360afa8e06SEd Maste } catch { 1370afa8e06SEd Maste throw "Failed to fetch and verify dependencies" 1380afa8e06SEd Maste } finally { 1390afa8e06SEd Maste Pop-Location 1400afa8e06SEd Maste } 1410afa8e06SEd Maste 142f540a430SEd Maste # Build LibreSSL. 143f540a430SEd Maste Push-Location ${STAGE}\${LIBRESSL} 144f540a430SEd Maste try { 145f540a430SEd Maste & $CMake ..\..\..\${LIBRESSL} -A "${Arch}" ` 1460afa8e06SEd Maste -DBUILD_SHARED_LIBS="${SHARED}" -DLIBRESSL_TESTS=OFF ` 147f540a430SEd Maste -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" ` 148f540a430SEd Maste -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" ` 149f540a430SEd Maste -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` 150f540a430SEd Maste ExitOnError 151f540a430SEd Maste & $CMake --build . --config ${Config} --verbose; ExitOnError 152f540a430SEd Maste & $CMake --build . --config ${Config} --target install --verbose; ` 153f540a430SEd Maste ExitOnError 154f540a430SEd Maste } catch { 155f540a430SEd Maste throw "Failed to build LibreSSL" 156f540a430SEd Maste } finally { 1570afa8e06SEd Maste Pop-Location 1580afa8e06SEd Maste } 1590afa8e06SEd Maste 160f540a430SEd Maste # Build libcbor. 161f540a430SEd Maste Push-Location ${STAGE}\${LIBCBOR} 162f540a430SEd Maste try { 163f540a430SEd Maste & $CMake ..\..\..\${LIBCBOR} -A "${Arch}" ` 164f540a430SEd Maste -DWITH_EXAMPLES=OFF ` 1650afa8e06SEd Maste -DBUILD_SHARED_LIBS="${SHARED}" ` 1662ccfa855SEd Maste -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG} /wd4703" ` 1672ccfa855SEd Maste -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE} /wd4703" ` 168f540a430SEd Maste -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` 169f540a430SEd Maste ExitOnError 170f540a430SEd Maste & $CMake --build . --config ${Config} --verbose; ExitOnError 171f540a430SEd Maste & $CMake --build . --config ${Config} --target install --verbose; ` 172f540a430SEd Maste ExitOnError 173f540a430SEd Maste } catch { 174f540a430SEd Maste throw "Failed to build libcbor" 175f540a430SEd Maste } finally { 1760afa8e06SEd Maste Pop-Location 1770afa8e06SEd Maste } 1780afa8e06SEd Maste 179f540a430SEd Maste # Build zlib. 180f540a430SEd Maste Push-Location ${STAGE}\${ZLIB} 181f540a430SEd Maste try { 182f540a430SEd Maste & $CMake ..\..\..\${ZLIB} -A "${Arch}" ` 1830afa8e06SEd Maste -DBUILD_SHARED_LIBS="${SHARED}" ` 184f540a430SEd Maste -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" ` 185f540a430SEd Maste -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" ` 186*60a517b6SEd Maste -DCMAKE_MSVC_RUNTIME_LIBRARY="${CMAKE_MSVC_RUNTIME_LIBRARY}" ` 187f540a430SEd Maste -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` 188f540a430SEd Maste ExitOnError 189f540a430SEd Maste & $CMake --build . --config ${Config} --verbose; ExitOnError 190f540a430SEd Maste & $CMake --build . --config ${Config} --target install --verbose; ` 191f540a430SEd Maste ExitOnError 1922ccfa855SEd Maste # Patch up zlib's various names. 193f540a430SEd Maste if ("${Type}" -eq "Dynamic") { 1942ccfa855SEd Maste ((Get-ChildItem -Path "${PREFIX}/lib") -Match "zlib[d]?.lib") | 1952ccfa855SEd Maste Copy-Item -Destination "${PREFIX}/lib/zlib1.lib" -Force 1962ccfa855SEd Maste ((Get-ChildItem -Path "${PREFIX}/bin") -Match "zlibd1.dll") | 1972ccfa855SEd Maste Copy-Item -Destination "${PREFIX}/bin/zlib1.dll" -Force 198f540a430SEd Maste } else { 1992ccfa855SEd Maste ((Get-ChildItem -Path "${PREFIX}/lib") -Match "zlibstatic[d]?.lib") | 2002ccfa855SEd Maste Copy-item -Destination "${PREFIX}/lib/zlib1.lib" -Force 201f540a430SEd Maste } 202f540a430SEd Maste } catch { 203f540a430SEd Maste throw "Failed to build zlib" 204f540a430SEd Maste } finally { 2050afa8e06SEd Maste Pop-Location 206f540a430SEd Maste } 2070afa8e06SEd Maste 208f540a430SEd Maste # Build libfido2. 209f540a430SEd Maste Push-Location ${STAGE} 210f540a430SEd Maste try { 211f540a430SEd Maste & $CMake ..\..\.. -A "${Arch}" ` 212f540a430SEd Maste -DCMAKE_BUILD_TYPE="${Config}" ` 2130afa8e06SEd Maste -DBUILD_SHARED_LIBS="${SHARED}" ` 214f540a430SEd Maste -DCBOR_INCLUDE_DIRS="${PREFIX}\include" ` 215f540a430SEd Maste -DCBOR_LIBRARY_DIRS="${PREFIX}\lib" ` 216f540a430SEd Maste -DCBOR_BIN_DIRS="${PREFIX}\bin" ` 217f540a430SEd Maste -DZLIB_INCLUDE_DIRS="${PREFIX}\include" ` 218f540a430SEd Maste -DZLIB_LIBRARY_DIRS="${PREFIX}\lib" ` 219f540a430SEd Maste -DZLIB_BIN_DIRS="${PREFIX}\bin" ` 220f540a430SEd Maste -DCRYPTO_INCLUDE_DIRS="${PREFIX}\include" ` 221f540a430SEd Maste -DCRYPTO_LIBRARY_DIRS="${PREFIX}\lib" ` 222f540a430SEd Maste -DCRYPTO_BIN_DIRS="${PREFIX}\bin" ` 2232ccfa855SEd Maste -DCRYPTO_LIBRARIES="${CRYPTO_LIBRARIES}" ` 224f540a430SEd Maste -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG} ${Fido2Flags}" ` 225f540a430SEd Maste -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE} ${Fido2Flags}" ` 226f540a430SEd Maste -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` 227f540a430SEd Maste ExitOnError 228f540a430SEd Maste & $CMake --build . --config ${Config} --verbose; ExitOnError 2292ccfa855SEd Maste & $CMake --build . --config ${Config} --target regress --verbose; ` 2302ccfa855SEd Maste ExitOnError 231f540a430SEd Maste & $CMake --build . --config ${Config} --target install --verbose; ` 232f540a430SEd Maste ExitOnError 233f540a430SEd Maste # Copy DLLs. 2340afa8e06SEd Maste if ("${SHARED}" -eq "ON") { 2352ccfa855SEd Maste "cbor.dll", "${CRYPTO_LIBRARIES}.dll", "zlib1.dll" | ` 236f540a430SEd Maste %{ Copy-Item "${PREFIX}\bin\$_" ` 237f540a430SEd Maste -Destination "examples\${Config}" } 2380afa8e06SEd Maste } 239f540a430SEd Maste } catch { 240f540a430SEd Maste throw "Failed to build libfido2" 241f540a430SEd Maste } finally { 2420afa8e06SEd Maste Pop-Location 243f540a430SEd Maste } 244