build-windows.ps1 10 KB

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