diff --git a/scripts/win-installer/build-win-installer.ps1 b/scripts/win-installer/build-win-installer.ps1 index 4265edf8e..d08ee186c 100644 --- a/scripts/win-installer/build-win-installer.ps1 +++ b/scripts/win-installer/build-win-installer.ps1 @@ -89,18 +89,53 @@ Write-Output "Windows version info: $VersionInfo" #----------------------------------------------------------------------------- # Locate OpenSSL root from local installation. -$SslRoot = @{ - "x64" = "C:\Program Files\OpenSSL-Win64"; - "Win32" = "C:\Program Files (x86)\OpenSSL-Win32" +# After version 3.something, OpenSSL has changed its installation layout. +# We have to look for OpenSSL libraries in various locations. +$SSL = @{ + "x64" = @{ + "alt" = "Win64"; + "bits" = 64; + "root" = "C:\Program Files\OpenSSL-Win64" + }; + "Win32" = @{ + "alt" = "x86"; + "bits" = 32; + "root" = "C:\Program Files (x86)\OpenSSL-Win32" + } } -# Verify OpenSSL directories. +# Verify OpenSSL directories and static libraries. +Write-Output "Searching OpenSSL libraries ..." $Missing = 0 -foreach ($file in @($SslRoot["x64"], $SslRoot["Win32"])) { - if (-not (Test-Path $file)) { - Write-Output "**** Missing $file" +foreach ($arch in @("x64", "Win32")) { + $root = $SSL[$arch]["root"] + $bits = $SSL[$arch]["bits"] + $alt = $SSL[$arch]["alt"] + if (-not (Test-Path $root)) { + Write-Output "**** Missing $root" $Missing = $Missing + 1 } + else { + foreach ($lib in @("ssl", "crypto")) { + foreach ($conf in @("MD", "MDd")) { + $name = "lib${lib}${conf}" + $SSL[$arch][$name] = "" + foreach ($try in @("$root\lib\VC\static\lib${lib}${bits}${conf}.lib", + "$root\lib\VC\${arch}\${conf}\lib${lib}_static.lib", + "$root\lib\VC\${alt}\${conf}\lib${lib}_static.lib")) { + if (Test-Path $try) { + $SSL[$arch][$name] = $try + New-Variable "lib${lib}${bits}${conf}" "$try" + break + } + } + if (-not $SSL[$arch][$name]) { + Write-Output "**** OpenSSL static library for $name not found" + $Missing = $Missing + 1 + } + } + } + } } if ($Missing -gt 0) { Exit-Script "Missing $Missing OpenSSL files, use install-openssl.ps1 to install OpenSSL" @@ -157,7 +192,7 @@ foreach ($Platform in @("x64", "Win32")) { # Run CMake. Write-Output "Configuring build for platform $Platform ..." - $SRoot = $SslRoot[$Platform] + $SRoot = $SSL[$Platform]["root"] & $CMake -S $RepoDir -B $BuildDir -A $Platform ` -DENABLE_STDCXX_SYNC=ON ` -DOPENSSL_ROOT_DIR="$SRoot" ` @@ -210,6 +245,14 @@ Write-Output "Building installer ..." /DOutDir="$OutDir" ` /DBuildRoot="$TmpDir" ` /DRepoDir="$RepoDir" ` + /Dlibssl32MD="$libssl32MD" ` + /Dlibssl32MDd="$libssl32MDd" ` + /Dlibcrypto32MD="$libcrypto32MD" ` + /Dlibcrypto32MDd="$libcrypto32MDd" ` + /Dlibssl64MD="$libssl64MD" ` + /Dlibssl64MDd="$libssl64MDd" ` + /Dlibcrypto64MD="$libcrypto64MD" ` + /Dlibcrypto64MDd="$libcrypto64MDd" ` "$ScriptDir\libsrt.nsi" if (-not (Test-Path $InstallExe)) { diff --git a/scripts/win-installer/install-openssl.ps1 b/scripts/win-installer/install-openssl.ps1 index 83b59954f..e24cecc57 100644 --- a/scripts/win-installer/install-openssl.ps1 +++ b/scripts/win-installer/install-openssl.ps1 @@ -1,7 +1,7 @@ #----------------------------------------------------------------------------- # # SRT - Secure, Reliable, Transport -# Copyright (c) 2021, Thierry Lelegard +# Copyright (c) 2021-2024, Thierry Lelegard # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -36,7 +36,26 @@ param( ) Write-Output "OpenSSL download and installation procedure" -$OpenSSLHomePage = "http://slproweb.com/products/Win32OpenSSL.html" + +# A bit of history: Where to load OpenSSL binaries from? +# +# The packages are built by "slproweb". The binaries are downloadable from +# their Web page at: http://slproweb.com/products/Win32OpenSSL.html +# +# Initially, the HTML for this page was built on server-side. This script +# grabbed the URL content, parse the HTML and extracted the URL of the +# binaries for the latest OpenSSL packages from the "href" of the links. +# +# At some point in 2024, the site changed policy. The Web page is no longer +# built on server-side, but on client-side. The downloaded HTML contains some +# JavaScript which dynamically builds the URL of the binaries for the latest +# OpenSSL binaries. The previous method now finds no valid package URL from +# the downloaded page (a full browser is needed to execute the JavaScript). +# The JavaScript downloads a JSON file which contains all references to +# the OpenSSL binaries. This script now uses the same method: download that +# JSON file and parse it. + +$PackageList = "https://github.com/slproweb/opensslhashes/raw/master/win32_openssl_hashes.json" # A function to exit this script. function Exit-Script([string]$Message = "") @@ -62,11 +81,11 @@ $TmpDir = "$RootDir\tmp" # Without this, Invoke-WebRequest is awfully slow. $ProgressPreference = 'SilentlyContinue' -# Get the HTML page for OpenSSL downloads. +# Get the JSON configuration file for OpenSSL downloads. $status = 0 $message = "" try { - $response = Invoke-WebRequest -UseBasicParsing -UserAgent Download -Uri $OpenSSLHomePage + $response = Invoke-WebRequest -UseBasicParsing -UserAgent Download -Uri $PackageList $status = [int] [Math]::Floor($response.StatusCode / 100) } catch { @@ -77,22 +96,27 @@ if ($status -ne 1 -and $status -ne 2) { Exit-Script "Status code $($response.StatusCode), $($response.StatusDescription)" } else { - Exit-Script "#### Error accessing ${OpenSSLHomePage}: $message" + Exit-Script "#### Error accessing ${PackageList}: $message" } } +$config = ConvertFrom-Json $Response.Content + +# Download and install MSI packages for 32 and 64 bit. +foreach ($bits in @(32, 64)) { + + # Get the URL of the MSI installer from the JSON config. + $Url = $config.files | Get-Member | ForEach-Object { + $name = $_.name + $info = $config.files.$($_.name) + if (-not $info.light -and $info.installer -like "msi" -and $info.bits -eq $bits -and $info.arch -like "intel") { + $info.url + } + } | Select-Object -Last 1 + if (-not $Url) { + Exit-Script "#### No MSI installer found for Win${bits}" + } -# Parse HTML page to locate the latest MSI files. -$Ref32 = $response.Links.href | Where-Object { $_ -like "*/Win32OpenSSL-*.msi" } | Select-Object -First 1 -$Ref64 = $response.Links.href | Where-Object { $_ -like "*/Win64OpenSSL-*.msi" } | Select-Object -First 1 - -# Build the absolute URL's from base URL (the download page) and href links. -$Url32 = New-Object -TypeName 'System.Uri' -ArgumentList ([System.Uri]$OpenSSLHomePage, $Ref32) -$Url64 = New-Object -TypeName 'System.Uri' -ArgumentList ([System.Uri]$OpenSSLHomePage, $Ref64) - -# Download and install one MSI package. -function Download-Install([string]$Url) -{ - $MsiName = (Split-Path -Leaf $Url.toString()) + $MsiName = (Split-Path -Leaf $Url) $MsiPath = "$TmpDir\$MsiName" if (-not $ForceDownload -and (Test-Path $MsiPath)) { @@ -113,7 +137,4 @@ function Download-Install([string]$Url) } } -# Download and install the two MSI packages. -Download-Install $Url32 -Download-Install $Url64 Exit-Script diff --git a/scripts/win-installer/libsrt.nsi b/scripts/win-installer/libsrt.nsi index 1dffc3fd1..022ceb617 100644 --- a/scripts/win-installer/libsrt.nsi +++ b/scripts/win-installer/libsrt.nsi @@ -31,8 +31,6 @@ Caption "SRT Libraries Installer" !define ProductName "libsrt" !define Build32Dir "${BuildRoot}\build.Win32" !define Build64Dir "${BuildRoot}\build.x64" -!define SSL32Dir "C:\Program Files (x86)\OpenSSL-Win32" -!define SSL64Dir "C:\Program Files\OpenSSL-Win64" ; Installer file information. VIProductVersion ${VersionInfo} @@ -142,26 +140,26 @@ Section "Install" CreateDirectory "$INSTDIR\lib\Release-x64" SetOutPath "$INSTDIR\lib\Release-x64" File /oname=srt.lib "${Build64Dir}\Release\srt_static.lib" - File /oname=libcrypto.lib "${SSL64Dir}\lib\VC\static\libcrypto64MD.lib" - File /oname=libssl.lib "${SSL64Dir}\lib\VC\static\libssl64MD.lib" + File /oname=libcrypto.lib "${libcrypto64MD}" + File /oname=libssl.lib "${libssl64MD}" CreateDirectory "$INSTDIR\lib\Debug-x64" SetOutPath "$INSTDIR\lib\Debug-x64" File /oname=srt.lib "${Build64Dir}\Debug\srt_static.lib" - File /oname=libcrypto.lib "${SSL64Dir}\lib\VC\static\libcrypto64MDd.lib" - File /oname=libssl.lib "${SSL64Dir}\lib\VC\static\libssl64MDd.lib" + File /oname=libcrypto.lib "${libcrypto64MDd}" + File /oname=libssl.lib "${libssl64MDd}" CreateDirectory "$INSTDIR\lib\Release-Win32" SetOutPath "$INSTDIR\lib\Release-Win32" File /oname=srt.lib "${Build32Dir}\Release\srt_static.lib" - File /oname=libcrypto.lib "${SSL32Dir}\lib\VC\static\libcrypto32MD.lib" - File /oname=libssl.lib "${SSL32Dir}\lib\VC\static\libssl32MD.lib" + File /oname=libcrypto.lib "${libcrypto32MD}" + File /oname=libssl.lib "${libssl32MD}" CreateDirectory "$INSTDIR\lib\Debug-Win32" SetOutPath "$INSTDIR\lib\Debug-Win32" File /oname=srt.lib "${Build32Dir}\Debug\srt_static.lib" - File /oname=libcrypto.lib "${SSL32Dir}\lib\VC\static\libcrypto32MDd.lib" - File /oname=libssl.lib "${SSL32Dir}\lib\VC\static\libssl32MDd.lib" + File /oname=libcrypto.lib "${libcrypto32MDd}" + File /oname=libssl.lib "${libssl32MDd}" ; Add an environment variable to installation root. WriteRegStr HKLM ${EnvironmentKey} "LIBSRT" "$INSTDIR"