1 ################################################################################ 2 # Windows SRT Build Script 3 #============================ 4 # Usable on a Windows PC with Powershell and Visual studio, 5 # or called by CI systems like AppVeyor 6 # 7 # By default produces a VS2019 64-bit Release binary using C++11 threads, without 8 # encryption or unit tests enabled, but including test apps. 9 # Before enabling any encryption options, install OpenSSL or set VCKPG flag to build 10 ################################################################################ 11 12 param ( 13 [Parameter()][String]$VS_VERSION = "2019", 14 [Parameter()][String]$CONFIGURATION = "Release", 15 [Parameter()][String]$DEVENV_PLATFORM = "x64", 16 [Parameter()][String]$ENABLE_ENCRYPTION = "OFF", 17 [Parameter()][String]$STATIC_LINK_SSL = "OFF", 18 [Parameter()][String]$CXX11 = "ON", 19 [Parameter()][String]$BUILD_APPS = "ON", 20 [Parameter()][String]$UNIT_TESTS = "OFF", 21 [Parameter()][String]$BUILD_DIR = "_build", 22 [Parameter()][String]$VCPKG_OPENSSL = "OFF" 23 ) 24 25 # cmake can be optionally installed (useful when running interactively on a developer station). 26 # The URL for automatic download is defined later in the script, but it should be possible to just vary the 27 # specific version set below and the URL should be stable enough to still work - you have been warned. 28 $cmakeVersion = "3.17.3" 29 30 # make all errors trigger a script stop, rather than just carry on 31 $ErrorActionPreference = "Stop" 32 33 $projectRoot = Join-Path $PSScriptRoot "/.." -Resolve 34 35 # if running within AppVeyor, use environment variables to set params instead of passed-in values 36 if ( $Env:APPVEYOR ) { 37 if ( $Env:PLATFORM -eq 'x86' ) { $DEVENV_PLATFORM = 'Win32' } else { $DEVENV_PLATFORM = 'x64' } 38 if ( $Env:APPVEYOR_BUILD_WORKER_IMAGE -eq 'Visual Studio 2019' ) { $VS_VERSION='2019' } 39 if ( $Env:APPVEYOR_BUILD_WORKER_IMAGE -eq 'Visual Studio 2015' ) { $VS_VERSION='2015' } 40 if ( $Env:APPVEYOR_BUILD_WORKER_IMAGE -eq 'Visual Studio 2013' ) { $VS_VERSION='2013' } 41 42 #if not statically linking OpenSSL, set flag to gather the specific openssl package from the build server into package 43 if ( $STATIC_LINK_SSL -eq 'OFF' ) { $Env:GATHER_SSL_INTO_PACKAGE = $true } 44 45 #if unit tests are on, set flag to actually execute ctest step 46 if ( $UNIT_TESTS -eq 'ON' ) { $Env:RUN_UNIT_TESTS = $true } 47 48 $CONFIGURATION = $Env:CONFIGURATION 49 50 #appveyor has many openssl installations - place the latest one in the default location unless VS2013 51 if( $VS_VERSION -ne '2013' ) { 52 Remove-Item -Path "C:\OpenSSL-Win32" -Recurse -Force -ErrorAction SilentlyContinue | Out-Null 53 Remove-Item -Path "C:\OpenSSL-Win64" -Recurse -Force -ErrorAction SilentlyContinue | Out-Null 54 Copy-Item -Path "C:\OpenSSL-v111-Win32" "C:\OpenSSL-Win32" -Recurse | Out-Null 55 Copy-Item -Path "C:\OpenSSL-v111-Win64" "C:\OpenSSL-Win64" -Recurse | Out-Null 56 } 57 } 58 59 # persist VS_VERSION so it can be used in an artifact name later 60 $Env:VS_VERSION = $VS_VERSION 61 62 # select the appropriate cmake generator string given the environment 63 if ( $VS_VERSION -eq '2019' ) { $CMAKE_GENERATOR = 'Visual Studio 16 2019'; $MSBUILDVER = "16.0"; } 64 if ( $VS_VERSION -eq '2015' -and $DEVENV_PLATFORM -eq 'Win32' ) { $CMAKE_GENERATOR = 'Visual Studio 14 2015'; $MSBUILDVER = "14.0"; } 65 if ( $VS_VERSION -eq '2015' -and $DEVENV_PLATFORM -eq 'x64' ) { $CMAKE_GENERATOR = 'Visual Studio 14 2015 Win64'; $MSBUILDVER = "14.0"; } 66 if ( $VS_VERSION -eq '2013' -and $DEVENV_PLATFORM -eq 'Win32' ) { $CMAKE_GENERATOR = 'Visual Studio 12 2013'; $MSBUILDVER = "12.0"; } 67 if ( $VS_VERSION -eq '2013' -and $DEVENV_PLATFORM -eq 'x64' ) { $CMAKE_GENERATOR = 'Visual Studio 12 2013 Win64'; $MSBUILDVER = "12.0"; } 68 69 # clear any previous build and create & enter the build directory 70 $buildDir = Join-Path "$projectRoot" "$BUILD_DIR" 71 Write-Output "Creating (or cleaning if already existing) the folder $buildDir for project files and outputs" 72 Remove-Item -Path $buildDir -Recurse -Force -ErrorAction SilentlyContinue | Out-Null 73 New-Item -ItemType Directory -Path $buildDir -ErrorAction SilentlyContinue | Out-Null 74 Push-Location $buildDir 75 76 # check cmake is installed 77 if ( $null -eq (Get-Command "cmake.exe" -ErrorAction SilentlyContinue) ) { 78 $installCmake = Read-Host "Unable to find cmake in your PATH - would you like to download and install automatically? [yes/no]" 79 80 if ( $installCmake -eq "y" -or $installCmake -eq "yes" ) { 81 # download cmake and run MSI for user 82 $client = New-Object System.Net.WebClient 83 $tempDownloadFile = New-TemporaryFile 84 85 $cmakeUrl = "https://github.com/Kitware/CMake/releases/download/v$cmakeVersion/cmake-$cmakeVersion-win64-x64.msi" 86 $cmakeMsiFile = "$tempDownloadFile.cmake-$cmakeVersion-win64-x64.msi" 87 Write-Output "Downloading cmake from $cmakeUrl (temporary file location $cmakeMsiFile)" 88 Write-Output "Note: select the option to add cmake to path for this script to operate" 89 $client.DownloadFile("$cmakeUrl", "$cmakeMsiFile") 90 Start-Process $cmakeMsiFile -Wait 91 Remove-Item $cmakeMsiFile 92 Write-Output "Cmake should have installed, this script will now exit because of path updates - please now re-run this script" 93 throw 94 } 95 else{ 96 Write-Output "Quitting because cmake is required" 97 throw 98 } 99 } 100 101 # get pthreads from nuget if CXX11 is not enabled 102 if ( $CXX11 -eq "OFF" ) { 103 # get pthreads (this is legacy, and is only availble in nuget for VS2015 and VS2013) 104 if ( $VS_VERSION -gt 2015 ) { 105 Write-Output "Pthreads is not recommended for use beyond VS2015 and is not supported by this build script - aborting build" 106 throw 107 } 108 if ( $DEVENV_PLATFORM -eq 'Win32' ) { 109 nuget install cinegy.pthreads-win32-$VS_VERSION -version 2.9.1.24 -OutputDirectory ../_packages 110 } 111 else { 112 nuget install cinegy.pthreads-win64-$VS_VERSION -version 2.9.1.24 -OutputDirectory ../_packages 113 } 114 } 115 116 # check to see if static SSL linking was requested, and enable encryption if not already ON 117 if ( $STATIC_LINK_SSL -eq "ON" ) { 118 if ( $ENABLE_ENCRYPTION -eq "OFF" ) { 119 # requesting a static link implicitly requires encryption support 120 Write-Output "Static linking to OpenSSL requested, will force encryption feature ON" 121 $ENABLE_ENCRYPTION = "ON" 122 } 123 } 124 125 # check to see if VCPKG is marked to provide OpenSSL, and enable encryption if not already ON 126 if ( $VCPKG_OPENSSL -eq "ON" ) { 127 if ( $ENABLE_ENCRYPTION -eq "OFF" ) { 128 # requesting VCPKG to provide OpenSSL requires encryption support 129 Write-Output "VCPKG compilation of OpenSSL requested, will force encryption feature ON" 130 $ENABLE_ENCRYPTION = "ON" 131 } 132 } 133 134 # build the cmake command flags from arguments 135 $cmakeFlags = "-DCMAKE_BUILD_TYPE=$CONFIGURATION " + 136 "-DENABLE_STDCXX_SYNC=$CXX11 " + 137 "-DENABLE_APPS=$BUILD_APPS " + 138 "-DENABLE_ENCRYPTION=$ENABLE_ENCRYPTION " + 139 "-DENABLE_UNITTESTS=$UNIT_TESTS" 140 141 # if VCPKG is flagged to provide OpenSSL, checkout VCPKG and install package 142 if ( $VCPKG_OPENSSL -eq 'ON' ) { 143 Push-Location $projectRoot 144 Write-Output "Cloning VCPKG into: $(Get-Location)" 145 if (Test-Path -Path ".\vcpkg") { 146 Set-Location .\vcpkg 147 git pull 148 } else { 149 git clone https://github.com/microsoft/vcpkg 150 Set-Location .\vcpkg 151 } 152 153 .\bootstrap-vcpkg.bat 154 155 if($DEVENV_PLATFORM -EQ "x64"){ 156 if($STATIC_LINK_SSL -EQ "ON"){ 157 .\vcpkg install openssl:x64-windows-static 158 $cmakeFlags += " -DVCPKG_TARGET_TRIPLET=x64-windows-static" 159 } 160 else{ 161 .\vcpkg install openssl:x64-windows 162 } 163 } 164 else{ 165 if($STATIC_LINK_SSL -EQ "ON"){ 166 .\vcpkg install openssl:x86-windows-static 167 $cmakeFlags += " -DVCPKG_TARGET_TRIPLET=x86-windows-static" 168 } 169 else{ 170 .\vcpkg install openssl:x86-windows 171 } 172 } 173 174 .\vcpkg integrate install 175 Pop-Location 176 $cmakeFlags += " -DCMAKE_TOOLCHAIN_FILE=$projectRoot\vcpkg\scripts\buildsystems\vcpkg.cmake" 177 } 178 else { 179 $cmakeFlags += " -DOPENSSL_USE_STATIC_LIBS=$STATIC_LINK_SSL " 180 } 181 182 # cmake uses a flag for architecture from vs2019, so add that as a suffix 183 if ( $VS_VERSION -eq '2019' ) { 184 $cmakeFlags += " -A `"$DEVENV_PLATFORM`"" 185 } 186 187 # fire cmake to build project files 188 $execVar = "cmake ../ -G`"$CMAKE_GENERATOR`" $cmakeFlags" 189 Write-Output $execVar 190 191 # Reset reaction to Continue for cmake as it sometimes tends to print 192 # things on stderr, which is understood by PowerShell as error. The 193 # exit code from cmake will be checked anyway. 194 $ErrorActionPreference = "Continue" 195 Invoke-Expression "& $execVar" 196 197 # check build ran OK, exit if cmake failed 198 if( $LASTEXITCODE -ne 0 ) { 199 Write-Output "Non-zero exit code from cmake: $LASTEXITCODE" 200 throw 201 } 202 203 $ErrorActionPreference = "Stop" 204 205 # run the set-version-metadata script to inject build numbers into appveyors console and the resulting DLL 206 . $PSScriptRoot/set-version-metadata.ps1 207 208 # look for msbuild 209 $msBuildPath = Get-Command "msbuild.exe" -ErrorAction SilentlyContinue 210 if ( $null -eq $msBuildPath ) { 211 # no mbsuild in the path, so try to locate with 'vswhere' 212 $vsWherePath = Get-Command "vswhere.exe" -ErrorAction SilentlyContinue 213 if ( $null -eq $vsWherePath ) { 214 # no vswhere in the path, so check the Microsoft published location (true since VS2017 Update 2) 215 $vsWherePath = Get-Command "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -ErrorAction SilentlyContinue 216 if ( $null -eq $vsWherePath ) { 217 Write-Output "Cannot find vswhere (used to locate msbuild). Please install VS2017 update 2 (or later) or add vswhere to your path and try again" 218 throw 219 } 220 } 221 $msBuildPath = & $vsWherePath -products * -version $MSBUILDVER -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe | select-object -first 1 222 if ( $null -eq $msBuildPath ) { 223 Write-Output "vswhere.exe cannot find msbuild for the specified Visual Studio version - please check the installation" 224 throw 225 } 226 } 227 228 & $msBuildPath SRT.sln -m /p:Configuration=$CONFIGURATION /p:Platform=$DEVENV_PLATFORM 229 230 # return to the directory previously occupied before running the script 231 Pop-Location 232 233 # if msbuild returned non-zero, throw to cause failure in CI 234 if( $LASTEXITCODE -ne 0 ) { 235 throw 236 } 237