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