xref: /freebsd/contrib/libfido2/windows/build.ps1 (revision f540a43052c12c76d3453ead881248d5467a1ab0)
1*f540a430SEd Maste # Copyright (c) 2021 Yubico AB. All rights reserved.
2*f540a430SEd Maste # Use of this source code is governed by a BSD-style
3*f540a430SEd Maste # license that can be found in the LICENSE file.
4*f540a430SEd Maste 
50afa8e06SEd Maste param(
60afa8e06SEd Maste 	[string]$CMakePath = "C:\Program Files\CMake\bin\cmake.exe",
70afa8e06SEd Maste 	[string]$GitPath = "C:\Program Files\Git\bin\git.exe",
80afa8e06SEd Maste 	[string]$SevenZPath = "C:\Program Files\7-Zip\7z.exe",
90afa8e06SEd Maste 	[string]$GPGPath = "C:\Program Files (x86)\GnuPG\bin\gpg.exe",
100afa8e06SEd Maste 	[string]$WinSDK = "",
11*f540a430SEd Maste 	[string]$Config = "Release",
12*f540a430SEd Maste 	[string]$Arch = "x64",
13*f540a430SEd Maste 	[string]$Type = "dynamic",
140afa8e06SEd Maste 	[string]$Fido2Flags = ""
150afa8e06SEd Maste )
160afa8e06SEd Maste 
17*f540a430SEd Maste $ErrorActionPreference = "Stop"
180afa8e06SEd Maste [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
190afa8e06SEd Maste 
20*f540a430SEd Maste . "$PSScriptRoot\const.ps1"
210afa8e06SEd Maste 
22*f540a430SEd Maste Function ExitOnError() {
23*f540a430SEd Maste 	if ($LastExitCode -ne 0) {
24*f540a430SEd Maste 		throw "A command exited with status $LastExitCode"
25*f540a430SEd Maste 	}
26*f540a430SEd Maste }
270afa8e06SEd Maste 
28*f540a430SEd Maste Function GitClone(${REPO}, ${BRANCH}, ${DIR}) {
29*f540a430SEd Maste 	Write-Host "Cloning ${REPO}..."
30*f540a430SEd Maste 	& $Git -c advice.detachedHead=false clone --quiet --depth=1 `
31*f540a430SEd Maste 	    --branch "${BRANCH}" "${REPO}" "${DIR}"
32*f540a430SEd Maste 	Write-Host "${REPO}'s ${BRANCH} HEAD is:"
33*f540a430SEd Maste 	& $Git -C "${DIR}" show -s HEAD
340afa8e06SEd Maste }
350afa8e06SEd Maste 
360afa8e06SEd Maste # Find Git.
37*f540a430SEd Maste $Git = $(Get-Command git -ErrorAction Ignore | `
38*f540a430SEd Maste     Select-Object -ExpandProperty Source)
390afa8e06SEd Maste if ([string]::IsNullOrEmpty($Git)) {
400afa8e06SEd Maste 	$Git = $GitPath
410afa8e06SEd Maste }
42*f540a430SEd Maste if (-Not (Test-Path $Git)) {
43*f540a430SEd Maste 	throw "Unable to find Git at $Git"
44*f540a430SEd Maste }
45*f540a430SEd Maste 
46*f540a430SEd Maste # Find CMake.
47*f540a430SEd Maste $CMake = $(Get-Command cmake -ErrorAction Ignore | `
48*f540a430SEd Maste     Select-Object -ExpandProperty Source)
49*f540a430SEd Maste if ([string]::IsNullOrEmpty($CMake)) {
50*f540a430SEd Maste 	$CMake = $CMakePath
51*f540a430SEd Maste }
52*f540a430SEd Maste if (-Not (Test-Path $CMake)) {
53*f540a430SEd Maste 	throw "Unable to find CMake at $CMake"
54*f540a430SEd Maste }
550afa8e06SEd Maste 
560afa8e06SEd Maste # Find 7z.
57*f540a430SEd Maste $SevenZ = $(Get-Command 7z -ErrorAction Ignore | `
58*f540a430SEd Maste     Select-Object -ExpandProperty Source)
590afa8e06SEd Maste if ([string]::IsNullOrEmpty($SevenZ)) {
600afa8e06SEd Maste 	$SevenZ = $SevenZPath
610afa8e06SEd Maste }
62*f540a430SEd Maste if (-Not (Test-Path $SevenZ)) {
63*f540a430SEd Maste 	throw "Unable to find 7z at $SevenZ"
64*f540a430SEd Maste }
650afa8e06SEd Maste 
660afa8e06SEd Maste # Find GPG.
67*f540a430SEd Maste $GPG = $(Get-Command gpg -ErrorAction Ignore | `
68*f540a430SEd Maste     Select-Object -ExpandProperty Source)
690afa8e06SEd Maste if ([string]::IsNullOrEmpty($GPG)) {
700afa8e06SEd Maste 	$GPG = $GPGPath
710afa8e06SEd Maste }
72*f540a430SEd Maste if (-Not (Test-Path $GPG)) {
73*f540a430SEd Maste 	throw "Unable to find GPG at $GPG"
74*f540a430SEd Maste }
750afa8e06SEd Maste 
760afa8e06SEd Maste # Override CMAKE_SYSTEM_VERSION if $WinSDK is set.
770afa8e06SEd Maste if (-Not ([string]::IsNullOrEmpty($WinSDK))) {
780afa8e06SEd Maste 	$CMAKE_SYSTEM_VERSION = "-DCMAKE_SYSTEM_VERSION='$WinSDK'"
790afa8e06SEd Maste } else {
800afa8e06SEd Maste 	$CMAKE_SYSTEM_VERSION = ''
810afa8e06SEd Maste }
820afa8e06SEd Maste 
83*f540a430SEd Maste Write-Host "WinSDK: $WinSDK"
84*f540a430SEd Maste Write-Host "Config: $Config"
85*f540a430SEd Maste Write-Host "Arch: $Arch"
86*f540a430SEd Maste Write-Host "Type: $Type"
870afa8e06SEd Maste Write-Host "Git: $Git"
880afa8e06SEd Maste Write-Host "CMake: $CMake"
890afa8e06SEd Maste Write-Host "7z: $SevenZ"
900afa8e06SEd Maste Write-Host "GPG: $GPG"
910afa8e06SEd Maste 
92*f540a430SEd Maste # Create build directories.
93*f540a430SEd Maste New-Item -Type Directory "${BUILD}" -Force
94*f540a430SEd Maste New-Item -Type Directory "${BUILD}\${Arch}" -Force
95*f540a430SEd Maste New-Item -Type Directory "${BUILD}\${Arch}\${Type}" -Force
96*f540a430SEd Maste New-Item -Type Directory "${STAGE}\${LIBRESSL}" -Force
97*f540a430SEd Maste New-Item -Type Directory "${STAGE}\${LIBCBOR}" -Force
98*f540a430SEd Maste New-Item -Type Directory "${STAGE}\${ZLIB}" -Force
990afa8e06SEd Maste 
100*f540a430SEd Maste # Create output directories.
101*f540a430SEd Maste New-Item -Type Directory "${OUTPUT}" -Force
102*f540a430SEd Maste New-Item -Type Directory "${OUTPUT}\${Arch}" -Force
103*f540a430SEd Maste New-Item -Type Directory "${OUTPUT}\${Arch}\${Type}" -force
104*f540a430SEd Maste 
105*f540a430SEd Maste # Fetch and verify dependencies.
1060afa8e06SEd Maste Push-Location ${BUILD}
1070afa8e06SEd Maste try {
108*f540a430SEd Maste 	if (-Not (Test-Path .\${LIBRESSL})) {
1090afa8e06SEd Maste 		if (-Not (Test-Path .\${LIBRESSL}.tar.gz -PathType leaf)) {
1100afa8e06SEd Maste 			Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz `
1110afa8e06SEd Maste 			    -OutFile .\${LIBRESSL}.tar.gz
1120afa8e06SEd Maste 		}
1130afa8e06SEd Maste 		if (-Not (Test-Path .\${LIBRESSL}.tar.gz.asc -PathType leaf)) {
1140afa8e06SEd Maste 			Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz.asc `
1150afa8e06SEd Maste 			    -OutFile .\${LIBRESSL}.tar.gz.asc
1160afa8e06SEd Maste 		}
1170afa8e06SEd Maste 
1180afa8e06SEd Maste 		Copy-Item "$PSScriptRoot\libressl.gpg" -Destination "${BUILD}"
1190afa8e06SEd Maste 		& $GPG --list-keys
120*f540a430SEd Maste 		& $GPG --quiet --no-default-keyring --keyring ./libressl.gpg `
1210afa8e06SEd Maste 		    --verify .\${LIBRESSL}.tar.gz.asc .\${LIBRESSL}.tar.gz
1220afa8e06SEd Maste 		if ($LastExitCode -ne 0) {
1230afa8e06SEd Maste 			throw "GPG signature verification failed"
1240afa8e06SEd Maste 		}
1250afa8e06SEd Maste 		& $SevenZ e .\${LIBRESSL}.tar.gz
1260afa8e06SEd Maste 		& $SevenZ x .\${LIBRESSL}.tar
1270afa8e06SEd Maste 		Remove-Item -Force .\${LIBRESSL}.tar
1280afa8e06SEd Maste 	}
129*f540a430SEd Maste 	if (-Not (Test-Path .\${LIBCBOR})) {
130*f540a430SEd Maste 		GitClone "${LIBCBOR_GIT}" "${LIBCBOR_BRANCH}" ".\${LIBCBOR}"
131*f540a430SEd Maste 	}
1320afa8e06SEd Maste 	if (-Not (Test-Path .\${ZLIB})) {
133*f540a430SEd Maste 		GitClone "${ZLIB_GIT}" "${ZLIB_BRANCH}" ".\${ZLIB}"
1340afa8e06SEd Maste 	}
1350afa8e06SEd Maste } catch {
1360afa8e06SEd Maste 	throw "Failed to fetch and verify dependencies"
1370afa8e06SEd Maste } finally {
1380afa8e06SEd Maste 	Pop-Location
1390afa8e06SEd Maste }
1400afa8e06SEd Maste 
141*f540a430SEd Maste # Build LibreSSL.
142*f540a430SEd Maste Push-Location ${STAGE}\${LIBRESSL}
143*f540a430SEd Maste try {
144*f540a430SEd Maste 	& $CMake ..\..\..\${LIBRESSL} -A "${Arch}" `
1450afa8e06SEd Maste 	    -DBUILD_SHARED_LIBS="${SHARED}" -DLIBRESSL_TESTS=OFF `
146*f540a430SEd Maste 	    -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" `
147*f540a430SEd Maste 	    -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" `
148*f540a430SEd Maste 	    -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; `
149*f540a430SEd Maste 	    ExitOnError
150*f540a430SEd Maste 	& $CMake --build . --config ${Config} --verbose; ExitOnError
151*f540a430SEd Maste 	& $CMake --build . --config ${Config} --target install --verbose; `
152*f540a430SEd Maste 	    ExitOnError
153*f540a430SEd Maste } catch {
154*f540a430SEd Maste 	throw "Failed to build LibreSSL"
155*f540a430SEd Maste } finally {
1560afa8e06SEd Maste 	Pop-Location
1570afa8e06SEd Maste }
1580afa8e06SEd Maste 
159*f540a430SEd Maste # Build libcbor.
160*f540a430SEd Maste Push-Location ${STAGE}\${LIBCBOR}
161*f540a430SEd Maste try {
162*f540a430SEd Maste 	& $CMake ..\..\..\${LIBCBOR} -A "${Arch}" `
163*f540a430SEd Maste 	    -DWITH_EXAMPLES=OFF `
1640afa8e06SEd Maste 	    -DBUILD_SHARED_LIBS="${SHARED}" `
165*f540a430SEd Maste 	    -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" `
166*f540a430SEd Maste 	    -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" `
167*f540a430SEd Maste 	    -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; `
168*f540a430SEd Maste 	    ExitOnError
169*f540a430SEd Maste 	& $CMake --build . --config ${Config} --verbose; ExitOnError
170*f540a430SEd Maste 	& $CMake --build . --config ${Config} --target install --verbose; `
171*f540a430SEd Maste 	    ExitOnError
172*f540a430SEd Maste } catch {
173*f540a430SEd Maste 	throw "Failed to build libcbor"
174*f540a430SEd Maste } finally {
1750afa8e06SEd Maste 	Pop-Location
1760afa8e06SEd Maste }
1770afa8e06SEd Maste 
178*f540a430SEd Maste # Build zlib.
179*f540a430SEd Maste Push-Location ${STAGE}\${ZLIB}
180*f540a430SEd Maste try {
181*f540a430SEd Maste 	& $CMake ..\..\..\${ZLIB} -A "${Arch}" `
1820afa8e06SEd Maste 	    -DBUILD_SHARED_LIBS="${SHARED}" `
183*f540a430SEd Maste 	    -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" `
184*f540a430SEd Maste 	    -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" `
185*f540a430SEd Maste 	    -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; `
186*f540a430SEd Maste 	    ExitOnError
187*f540a430SEd Maste 	& $CMake --build . --config ${Config} --verbose; ExitOnError
188*f540a430SEd Maste 	& $CMake --build . --config ${Config} --target install --verbose; `
189*f540a430SEd Maste 	    ExitOnError
190*f540a430SEd Maste 	# Patch up zlib's resulting names when built with --config Debug.
191*f540a430SEd Maste 	if ("${Config}" -eq "Debug") {
192*f540a430SEd Maste 		if ("${Type}" -eq "Dynamic") {
193*f540a430SEd Maste 			Copy-Item "${PREFIX}/lib/zlibd.lib" `
194*f540a430SEd Maste 			    -Destination "${PREFIX}/lib/zlib.lib" -Force
195*f540a430SEd Maste 			Copy-Item "${PREFIX}/bin/zlibd1.dll" `
196*f540a430SEd Maste 			    -Destination "${PREFIX}/bin/zlib1.dll" -Force
197*f540a430SEd Maste 		} else {
198*f540a430SEd Maste 			Copy-Item "${PREFIX}/lib/zlibstaticd.lib" `
199*f540a430SEd Maste 			    -Destination "${PREFIX}/lib/zlib.lib" -Force
200*f540a430SEd Maste 		}
201*f540a430SEd Maste 	}
202*f540a430SEd Maste } catch {
203*f540a430SEd Maste 	throw "Failed to build zlib"
204*f540a430SEd Maste } finally {
2050afa8e06SEd Maste 	Pop-Location
206*f540a430SEd Maste }
2070afa8e06SEd Maste 
208*f540a430SEd Maste # Build libfido2.
209*f540a430SEd Maste Push-Location ${STAGE}
210*f540a430SEd Maste try {
211*f540a430SEd Maste 	& $CMake ..\..\.. -A "${Arch}" `
212*f540a430SEd Maste 	    -DCMAKE_BUILD_TYPE="${Config}" `
2130afa8e06SEd Maste 	    -DBUILD_SHARED_LIBS="${SHARED}" `
214*f540a430SEd Maste 	    -DCBOR_INCLUDE_DIRS="${PREFIX}\include" `
215*f540a430SEd Maste 	    -DCBOR_LIBRARY_DIRS="${PREFIX}\lib" `
216*f540a430SEd Maste 	    -DCBOR_BIN_DIRS="${PREFIX}\bin" `
217*f540a430SEd Maste 	    -DZLIB_INCLUDE_DIRS="${PREFIX}\include" `
218*f540a430SEd Maste 	    -DZLIB_LIBRARY_DIRS="${PREFIX}\lib" `
219*f540a430SEd Maste 	    -DZLIB_BIN_DIRS="${PREFIX}\bin" `
220*f540a430SEd Maste 	    -DCRYPTO_INCLUDE_DIRS="${PREFIX}\include" `
221*f540a430SEd Maste 	    -DCRYPTO_LIBRARY_DIRS="${PREFIX}\lib" `
222*f540a430SEd Maste 	    -DCRYPTO_BIN_DIRS="${PREFIX}\bin" `
223*f540a430SEd Maste 	    -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG} ${Fido2Flags}" `
224*f540a430SEd Maste 	    -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE} ${Fido2Flags}" `
225*f540a430SEd Maste 	    -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; `
226*f540a430SEd Maste 	    ExitOnError
227*f540a430SEd Maste 	& $CMake --build . --config ${Config} --verbose; ExitOnError
228*f540a430SEd Maste 	& $CMake --build . --config ${Config} --target install --verbose; `
229*f540a430SEd Maste 	    ExitOnError
230*f540a430SEd Maste 	# Copy DLLs.
2310afa8e06SEd Maste 	if ("${SHARED}" -eq "ON") {
232*f540a430SEd Maste 		"cbor.dll", "crypto-46.dll", "zlib1.dll" | `
233*f540a430SEd Maste 		    %{ Copy-Item "${PREFIX}\bin\$_" `
234*f540a430SEd Maste 		    -Destination "examples\${Config}" }
2350afa8e06SEd Maste 	}
236*f540a430SEd Maste } catch {
237*f540a430SEd Maste 	throw "Failed to build libfido2"
238*f540a430SEd Maste } finally {
2390afa8e06SEd Maste 	Pop-Location
240*f540a430SEd Maste }
241