1 # Copyright (c) 2021 Yubico AB. All rights reserved. 2 # Use of this source code is governed by a BSD-style 3 # license that can be found in the LICENSE file. 4 5 param( 6 [string]$CMakePath = "C:\Program Files\CMake\bin\cmake.exe", 7 [string]$GitPath = "C:\Program Files\Git\bin\git.exe", 8 [string]$SevenZPath = "C:\Program Files\7-Zip\7z.exe", 9 [string]$GPGPath = "C:\Program Files (x86)\GnuPG\bin\gpg.exe", 10 [string]$WinSDK = "", 11 [string]$Config = "Release", 12 [string]$Arch = "x64", 13 [string]$Type = "dynamic", 14 [string]$Fido2Flags = "" 15 ) 16 17 $ErrorActionPreference = "Stop" 18 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 19 20 . "$PSScriptRoot\const.ps1" 21 22 Function ExitOnError() { 23 if ($LastExitCode -ne 0) { 24 throw "A command exited with status $LastExitCode" 25 } 26 } 27 28 Function GitClone(${REPO}, ${BRANCH}, ${DIR}) { 29 Write-Host "Cloning ${REPO}..." 30 & $Git -c advice.detachedHead=false clone --quiet --depth=1 ` 31 --branch "${BRANCH}" "${REPO}" "${DIR}" 32 Write-Host "${REPO}'s ${BRANCH} HEAD is:" 33 & $Git -C "${DIR}" show -s HEAD 34 } 35 36 # Find Git. 37 $Git = $(Get-Command git -ErrorAction Ignore | ` 38 Select-Object -ExpandProperty Source) 39 if ([string]::IsNullOrEmpty($Git)) { 40 $Git = $GitPath 41 } 42 if (-Not (Test-Path $Git)) { 43 throw "Unable to find Git at $Git" 44 } 45 46 # Find CMake. 47 $CMake = $(Get-Command cmake -ErrorAction Ignore | ` 48 Select-Object -ExpandProperty Source) 49 if ([string]::IsNullOrEmpty($CMake)) { 50 $CMake = $CMakePath 51 } 52 if (-Not (Test-Path $CMake)) { 53 throw "Unable to find CMake at $CMake" 54 } 55 56 # Find 7z. 57 $SevenZ = $(Get-Command 7z -ErrorAction Ignore | ` 58 Select-Object -ExpandProperty Source) 59 if ([string]::IsNullOrEmpty($SevenZ)) { 60 $SevenZ = $SevenZPath 61 } 62 if (-Not (Test-Path $SevenZ)) { 63 throw "Unable to find 7z at $SevenZ" 64 } 65 66 # Find GPG. 67 $GPG = $(Get-Command gpg -ErrorAction Ignore | ` 68 Select-Object -ExpandProperty Source) 69 if ([string]::IsNullOrEmpty($GPG)) { 70 $GPG = $GPGPath 71 } 72 if (-Not (Test-Path $GPG)) { 73 throw "Unable to find GPG at $GPG" 74 } 75 76 # Override CMAKE_SYSTEM_VERSION if $WinSDK is set. 77 if (-Not ([string]::IsNullOrEmpty($WinSDK))) { 78 $CMAKE_SYSTEM_VERSION = "-DCMAKE_SYSTEM_VERSION='$WinSDK'" 79 } else { 80 $CMAKE_SYSTEM_VERSION = '' 81 } 82 83 Write-Host "WinSDK: $WinSDK" 84 Write-Host "Config: $Config" 85 Write-Host "Arch: $Arch" 86 Write-Host "Type: $Type" 87 Write-Host "Git: $Git" 88 Write-Host "CMake: $CMake" 89 Write-Host "7z: $SevenZ" 90 Write-Host "GPG: $GPG" 91 92 # Create build directories. 93 New-Item -Type Directory "${BUILD}" -Force 94 New-Item -Type Directory "${BUILD}\${Arch}" -Force 95 New-Item -Type Directory "${BUILD}\${Arch}\${Type}" -Force 96 New-Item -Type Directory "${STAGE}\${LIBRESSL}" -Force 97 New-Item -Type Directory "${STAGE}\${LIBCBOR}" -Force 98 New-Item -Type Directory "${STAGE}\${ZLIB}" -Force 99 100 # Create output directories. 101 New-Item -Type Directory "${OUTPUT}" -Force 102 New-Item -Type Directory "${OUTPUT}\${Arch}" -Force 103 New-Item -Type Directory "${OUTPUT}\${Arch}\${Type}" -force 104 105 # Fetch and verify dependencies. 106 Push-Location ${BUILD} 107 try { 108 if (-Not (Test-Path .\${LIBRESSL})) { 109 if (-Not (Test-Path .\${LIBRESSL}.tar.gz -PathType leaf)) { 110 Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz ` 111 -OutFile .\${LIBRESSL}.tar.gz 112 } 113 if (-Not (Test-Path .\${LIBRESSL}.tar.gz.asc -PathType leaf)) { 114 Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz.asc ` 115 -OutFile .\${LIBRESSL}.tar.gz.asc 116 } 117 118 Copy-Item "$PSScriptRoot\libressl.gpg" -Destination "${BUILD}" 119 & $GPG --list-keys 120 & $GPG --quiet --no-default-keyring --keyring ./libressl.gpg ` 121 --verify .\${LIBRESSL}.tar.gz.asc .\${LIBRESSL}.tar.gz 122 if ($LastExitCode -ne 0) { 123 throw "GPG signature verification failed" 124 } 125 & $SevenZ e .\${LIBRESSL}.tar.gz 126 & $SevenZ x .\${LIBRESSL}.tar 127 Remove-Item -Force .\${LIBRESSL}.tar 128 } 129 if (-Not (Test-Path .\${LIBCBOR})) { 130 GitClone "${LIBCBOR_GIT}" "${LIBCBOR_BRANCH}" ".\${LIBCBOR}" 131 } 132 if (-Not (Test-Path .\${ZLIB})) { 133 GitClone "${ZLIB_GIT}" "${ZLIB_BRANCH}" ".\${ZLIB}" 134 } 135 } catch { 136 throw "Failed to fetch and verify dependencies" 137 } finally { 138 Pop-Location 139 } 140 141 # Build LibreSSL. 142 Push-Location ${STAGE}\${LIBRESSL} 143 try { 144 & $CMake ..\..\..\${LIBRESSL} -A "${Arch}" ` 145 -DBUILD_SHARED_LIBS="${SHARED}" -DLIBRESSL_TESTS=OFF ` 146 -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" ` 147 -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" ` 148 -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` 149 ExitOnError 150 & $CMake --build . --config ${Config} --verbose; ExitOnError 151 & $CMake --build . --config ${Config} --target install --verbose; ` 152 ExitOnError 153 } catch { 154 throw "Failed to build LibreSSL" 155 } finally { 156 Pop-Location 157 } 158 159 # Build libcbor. 160 Push-Location ${STAGE}\${LIBCBOR} 161 try { 162 & $CMake ..\..\..\${LIBCBOR} -A "${Arch}" ` 163 -DWITH_EXAMPLES=OFF ` 164 -DBUILD_SHARED_LIBS="${SHARED}" ` 165 -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" ` 166 -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" ` 167 -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` 168 ExitOnError 169 & $CMake --build . --config ${Config} --verbose; ExitOnError 170 & $CMake --build . --config ${Config} --target install --verbose; ` 171 ExitOnError 172 } catch { 173 throw "Failed to build libcbor" 174 } finally { 175 Pop-Location 176 } 177 178 # Build zlib. 179 Push-Location ${STAGE}\${ZLIB} 180 try { 181 & $CMake ..\..\..\${ZLIB} -A "${Arch}" ` 182 -DBUILD_SHARED_LIBS="${SHARED}" ` 183 -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" ` 184 -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" ` 185 -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` 186 ExitOnError 187 & $CMake --build . --config ${Config} --verbose; ExitOnError 188 & $CMake --build . --config ${Config} --target install --verbose; ` 189 ExitOnError 190 # Patch up zlib's resulting names when built with --config Debug. 191 if ("${Config}" -eq "Debug") { 192 if ("${Type}" -eq "Dynamic") { 193 Copy-Item "${PREFIX}/lib/zlibd.lib" ` 194 -Destination "${PREFIX}/lib/zlib.lib" -Force 195 Copy-Item "${PREFIX}/bin/zlibd1.dll" ` 196 -Destination "${PREFIX}/bin/zlib1.dll" -Force 197 } else { 198 Copy-Item "${PREFIX}/lib/zlibstaticd.lib" ` 199 -Destination "${PREFIX}/lib/zlib.lib" -Force 200 } 201 } 202 } catch { 203 throw "Failed to build zlib" 204 } finally { 205 Pop-Location 206 } 207 208 # Build libfido2. 209 Push-Location ${STAGE} 210 try { 211 & $CMake ..\..\.. -A "${Arch}" ` 212 -DCMAKE_BUILD_TYPE="${Config}" ` 213 -DBUILD_SHARED_LIBS="${SHARED}" ` 214 -DCBOR_INCLUDE_DIRS="${PREFIX}\include" ` 215 -DCBOR_LIBRARY_DIRS="${PREFIX}\lib" ` 216 -DCBOR_BIN_DIRS="${PREFIX}\bin" ` 217 -DZLIB_INCLUDE_DIRS="${PREFIX}\include" ` 218 -DZLIB_LIBRARY_DIRS="${PREFIX}\lib" ` 219 -DZLIB_BIN_DIRS="${PREFIX}\bin" ` 220 -DCRYPTO_INCLUDE_DIRS="${PREFIX}\include" ` 221 -DCRYPTO_LIBRARY_DIRS="${PREFIX}\lib" ` 222 -DCRYPTO_BIN_DIRS="${PREFIX}\bin" ` 223 -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG} ${Fido2Flags}" ` 224 -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE} ${Fido2Flags}" ` 225 -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` 226 ExitOnError 227 & $CMake --build . --config ${Config} --verbose; ExitOnError 228 & $CMake --build . --config ${Config} --target install --verbose; ` 229 ExitOnError 230 # Copy DLLs. 231 if ("${SHARED}" -eq "ON") { 232 "cbor.dll", "crypto-47.dll", "zlib1.dll" | ` 233 %{ Copy-Item "${PREFIX}\bin\$_" ` 234 -Destination "examples\${Config}" } 235 } 236 } catch { 237 throw "Failed to build libfido2" 238 } finally { 239 Pop-Location 240 } 241