winrtbuild.ps1 (12820B)
1 # 2 # winrtbuild.ps1 -- A Powershell script to build all SDL/WinRT variants, 3 # across all WinRT platforms, in all of their supported, CPU architectures. 4 # 5 # Initial version written by David Ludwig <dludwig@pobox.com> 6 # 7 # This script can be launched from Windows Explorer by double-clicking 8 # on winrtbuild.bat 9 # 10 # Output will be placed in the following subdirectories of the SDL source 11 # tree: 12 # * VisualC-WinRT\lib\ -- final .dll, .lib, and .pdb files 13 # * VisualC-WinRT\obj\ -- intermediate build files 14 # 15 # Recommended Dependencies: 16 # * Windows 8.1 or higher 17 # * Powershell 4.0 or higher (included as part of Windows 8.1) 18 # * Visual C++ 2012, for building Windows 8.0 and Windows Phone 8.0 binaries. 19 # * Visual C++ 2013, for building Windows 8.1 and Windows Phone 8.1 binaries 20 # * SDKs for Windows 8.0, Windows 8.1, Windows Phone 8.0, and 21 # Windows Phone 8.1, as needed 22 # 23 # Commom parameters/variables may include, but aren't strictly limited to: 24 # * PlatformToolset: the name of one of Visual Studio's build platforms. 25 # Different PlatformToolsets output different binaries. One 26 # PlatformToolset exists for each WinRT platform. Possible values 27 # may include: 28 # - "v110": Visual Studio 2012 build tools, plus the Windows 8.0 SDK 29 # - "v110_wp80": Visual Studio 2012 build tools, plus the Windows Phone 8.0 SDK 30 # - "v120": Visual Studio 2013 build tools, plus the Windows 8.1 SDK 31 # - "v120_wp81": Visual Studio 2013 build tools, plus the Windows Phone 8.1 SDK 32 # * VSProjectPath: the full path to a Visual Studio or Visual C++ project file 33 # * VSProjectName: the internal name of a Visual Studio or Visual C++ project 34 # file. Some of Visual Studio's own build tools use this name when 35 # calculating paths for build-output. 36 # * Platform: a Visual Studio platform name, which often maps to a CPU 37 # CPU architecture. Possible values may include: "Win32" (for 32-bit x86), 38 # "ARM", or "x64" (for 64-bit x86). 39 # 40 41 # Base version of SDL, used for packaging purposes 42 $SDLVersion = "2.0.14" 43 44 # Gets the .bat file that sets up an MSBuild environment, given one of 45 # Visual Studio's, "PlatformToolset"s. 46 function Get-MSBuild-Env-Launcher 47 { 48 param( 49 [Parameter(Mandatory=$true,Position=1)][string]$PlatformToolset 50 ) 51 52 if ($PlatformToolset -eq "v110") { # Windows 8.0 (not Windows Phone), via VS 2012 53 return "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" 54 } 55 if ($PlatformToolset -eq "v110_wp80") { # Windows Phone 8.0, via VS 2012 56 return "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\WPSDK\WP80\vcvarsphoneall.bat" 57 } 58 if ($PlatformToolset -eq "v120") { # Windows 8.1 (not Windows Phone), via VS 2013 59 return "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" 60 } 61 if ($PlatformToolset -eq "v120_wp81") { # Windows Phone 8.1, via VS 2013 62 return "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" 63 } 64 if ($PlatformToolset -eq "v140") { # Windows 10, via VS 2015 65 return "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" 66 } 67 return "" 68 } 69 70 # Gets a string that identifies the build-variant of SDL/WinRT that is specific 71 # to a particular Visual Studio PlatformToolset. 72 function Get-SDL-WinRT-Variant-Name 73 { 74 param( 75 [Parameter(Mandatory=$true,Position=1)][string]$PlatformToolset, 76 77 # If true, append a string to this function's output, identifying the 78 # build-variant's minimum-supported version of Visual Studio. 79 [switch]$IncludeVSSuffix = $false 80 ) 81 82 if ($PlatformToolset -eq "v110") { # Windows 8.0 (not Windows Phone), via VS 2012 project files 83 if ($IncludeVSSuffix) { 84 return "WinRT80_VS2012" 85 } else { 86 return "WinRT80" 87 } 88 } 89 if ($PlatformToolset -eq "v110_wp80") { # Windows Phone 8.0, via VS 2012 project files 90 if ($IncludeVSSuffix) { 91 return "WinPhone80_VS2012" 92 } else { 93 return "WinPhone80" 94 } 95 } 96 if ($PlatformToolset -eq "v120") { # Windows 8.1 (not Windows Phone), via VS 2013 project files 97 if ($IncludeVSSuffix) { 98 return "WinRT81_VS2013" 99 } else { 100 return "WinRT81" 101 } 102 } 103 if ($PlatformToolset -eq "v120_wp81") { # Windows Phone 8.1, via VS 2013 project files 104 if ($IncludeVSSuffix) { 105 return "WinPhone81_VS2013" 106 } else { 107 return "WinPhone81" 108 } 109 } 110 if ($PlatformToolset -eq "v140") { # Windows 10, via VS 2015 project files 111 if ($IncludeVSSuffix) { 112 return "UWP_VS2015" 113 } else { 114 return "UWP" 115 } 116 } 117 return "" 118 } 119 120 # Returns the internal name of a Visual Studio Project. 121 # 122 # The internal name of a VS Project is encoded inside the project file 123 # itself, inside a set of <ProjectName></ProjectName> XML tags. 124 function Get-VS-ProjectName 125 { 126 param( 127 [Parameter(Mandatory=$true,Position=1)]$VSProjectPath 128 ) 129 130 # For now, just do a regex for the project name: 131 $matches = (Get-Content $VSProjectPath | Select-String -Pattern ".*<ProjectName>([^<]+)<.*").Matches 132 foreach ($match in $matches) { 133 if ($match.Groups.Count -ge 1) { 134 return $match.Groups[1].Value 135 } 136 } 137 return $null 138 } 139 140 # Build a specific variant of SDL/WinRT 141 function Build-SDL-WinRT-Variant 142 { 143 # 144 # Read in arguments: 145 # 146 param ( 147 # name of an SDL project file, minus extensions and 148 # platform-identifying suffixes 149 [Parameter(Mandatory=$true,Position=1)][string]$SDLProjectName, 150 151 [Parameter(Mandatory=$true,Position=2)][string]$PlatformToolset, 152 153 [Parameter(Mandatory=$true,Position=3)][string]$Platform 154 ) 155 156 # 157 # Derive other properties from read-in arguments: 158 # 159 160 # The .bat file to setup a platform-appropriate MSBuild environment: 161 $BatchFileForMSBuildEnv = Get-MSBuild-Env-Launcher $PlatformToolset 162 163 # The full path to the VS Project that'll be built: 164 $VSProjectPath = "$PSScriptRoot\..\VisualC-WinRT\$(Get-SDL-WinRT-Variant-Name $PlatformToolset -IncludeVSSuffix)\$SDLProjectName-$(Get-SDL-WinRT-Variant-Name $PlatformToolset).vcxproj" 165 166 # The internal name of the VS Project, used in some post-build steps: 167 $VSProjectName = Get-VS-ProjectName $VSProjectPath 168 169 # Where to place output binaries (.dll, .lib, and .pdb files): 170 $OutDir = "$PSScriptRoot\..\VisualC-WinRT\lib\$(Get-SDL-WinRT-Variant-Name $PlatformToolset)\$Platform" 171 172 # Where to place intermediate build files: 173 $IntermediateDir = "$PSScriptRoot\..\VisualC-WinRT\obj\$SDLProjectName-$(Get-SDL-WinRT-Variant-Name $PlatformToolset)\$Platform" 174 175 # 176 # Build the VS Project: 177 # 178 cmd.exe /c " ""$BatchFileForMSBuildEnv"" x86 & msbuild ""$VSProjectPath"" /p:Configuration=Release /p:Platform=$Platform /p:OutDir=""$OutDir\\"" /p:IntDir=""$IntermediateDir\\""" | Out-Host 179 $BuildResult = $? 180 181 # 182 # Move .dll files into place. This fixes a problem whereby MSBuild may 183 # put output files into a sub-directory of $OutDir, rather than $OutDir 184 # itself. 185 # 186 if (Test-Path "$OutDir\$VSProjectName\") { 187 Move-Item -Force "$OutDir\$VSProjectName\*" "$OutDir" 188 } 189 190 # 191 # Clean up unneeded files in $OutDir: 192 # 193 if (Test-Path "$OutDir\$VSProjectName\") { 194 Remove-Item -Recurse "$OutDir\$VSProjectName" 195 } 196 Remove-Item "$OutDir\*.exp" 197 Remove-Item "$OutDir\*.ilk" 198 Remove-Item "$OutDir\*.pri" 199 200 # 201 # All done. Indicate success, or failure, to the caller: 202 # 203 #echo "RESULT: $BuildResult" | Out-Host 204 return $BuildResult 205 } 206 207 208 # 209 # Build each variant, with corresponding .dll, .lib, and .pdb files: 210 # 211 $DidAnyDLLBuildFail = $false 212 $DidAnyNugetBuildFail = $false 213 214 # Ryan disabled WP8.0, because it doesn't appear to have mmdeviceapi.h that SDL_wasapi needs. 215 # My assumption is that no one will miss this, but send patches otherwise! --ryan. 216 # Build for Windows Phone 8.0, via VC++ 2012: 217 #if ( ! (Build-SDL-WinRT-Variant "SDL" "v110_wp80" "ARM")) { $DidAnyDLLBuildFail = $true } 218 #if ( ! (Build-SDL-WinRT-Variant "SDL" "v110_wp80" "Win32")) { $DidAnyDLLBuildFail = $true } 219 220 # Build for Windows Phone 8.1, via VC++ 2013: 221 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120_wp81" "ARM")) { $DidAnyDLLBuildFail = $true } 222 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120_wp81" "Win32")) { $DidAnyDLLBuildFail = $true } 223 224 # Build for Windows 8.0 and Windows RT 8.0, via VC++ 2012: 225 # 226 # Win 8.0 auto-building was disabled on 2017-Feb-25, by David Ludwig <dludwig@pobox.com>. 227 # Steam's OS-usage surveys indicate that Windows 8.0 use is pretty much nil, plus 228 # Microsoft hasn't supported Windows 8.0 development for a few years now. 229 # The commented-out lines below may still work on some systems, though. 230 # 231 #if ( ! (Build-SDL-WinRT-Variant "SDL" "v110" "ARM")) { $DidAnyDLLBuildFail = $true } 232 #if ( ! (Build-SDL-WinRT-Variant "SDL" "v110" "Win32")) { $DidAnyDLLBuildFail = $true } 233 #if ( ! (Build-SDL-WinRT-Variant "SDL" "v110" "x64")) { $DidAnyDLLBuildFail = $true } 234 235 # Build for Windows 8.1 and Windows RT 8.1, via VC++ 2013: 236 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120" "ARM")) { $DidAnyDLLBuildFail = $true } 237 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120" "Win32")) { $DidAnyDLLBuildFail = $true } 238 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120" "x64")) { $DidAnyDLLBuildFail = $true } 239 240 # Build for Windows 10, via VC++ 2015 241 if ( ! (Build-SDL-WinRT-Variant "SDL" "v140" "ARM")) { $DidAnyDLLBuildFail = $true } 242 if ( ! (Build-SDL-WinRT-Variant "SDL" "v140" "Win32")) { $DidAnyDLLBuildFail = $true } 243 if ( ! (Build-SDL-WinRT-Variant "SDL" "v140" "x64")) { $DidAnyDLLBuildFail = $true } 244 245 # Build NuGet packages, if possible 246 if ($DidAnyDLLBuildFail -eq $true) { 247 Write-Warning -Message "Unable to build all variants. NuGet packages will not be built." 248 $DidAnyNugetBuildFail = $true 249 } else { 250 $NugetPath = (Get-Command -CommandType Application nuget.exe | %{$_.Path}) 2> $null 251 if ("$NugetPath" -eq "") { 252 Write-Warning -Message "Unable to find nuget.exe. NuGet packages will not be built." 253 $DidAnyNugetBuildFail = $true 254 } else { 255 Write-Host -ForegroundColor Cyan "Building SDL2 NuGet packages..." 256 Write-Host -ForegroundColor Cyan "... via NuGet install: $NugetPath" 257 $NugetOutputDir = "$PSScriptRoot\..\VisualC-WinRT\lib\nuget" 258 Write-Host -ForegroundColor Cyan "... output directory: $NugetOutputDir" 259 $SDLHGRevision = $($(hg log -l 1 --repository "$PSScriptRoot\.." | select-string "changeset") -Replace "changeset:\W*(\d+).*",'$1') 2>$null 260 Write-Host -ForegroundColor Cyan "... HG Revision: $SDLHGRevision" 261 262 # Base options to nuget.exe 263 $NugetOptions = @("pack", "PACKAGE_NAME_WILL_GO_HERE", "-Output", "$NugetOutputDir") 264 265 # Try attaching hg revision to NuGet package: 266 $NugetOptions += "-Version" 267 if ("$SDLHGRevision" -eq "") { 268 Write-Warning -Message "Unable to find the Mercurial revision (maybe hg.exe can't be found?). NuGet packages will not have this attached to their name." 269 $NugetOptions += "$SDLVersion-Unofficial" 270 } else { 271 $NugetOptions += "$SDLVersion.$SDLHGRevision-Unofficial" 272 } 273 274 # Create NuGet output dir, if not yet created: 275 if ($(Test-Path "$NugetOutputDir") -eq $false) { 276 New-Item "$NugetOutputDir" -type directory 277 } 278 279 # Package SDL2: 280 $NugetOptions[1] = "$PSScriptRoot\..\VisualC-WinRT\SDL2-WinRT.nuspec" 281 &"$NugetPath" $NugetOptions -Symbols 282 if ( ! $? ) { $DidAnyNugetBuildFail = $true } 283 284 # Package SDL2main: 285 $NugetOptions[1] = "$PSScriptRoot\..\VisualC-WinRT\SDL2main-WinRT-NonXAML.nuspec" 286 &"$NugetPath" $NugetOptions 287 if ( ! $? ) { $DidAnyNugetBuildFail = $true } 288 } 289 } 290 291 292 # Let the script's caller know whether or not any errors occurred. 293 # Exit codes compatible with Buildbot are used (1 for error, 0 for success). 294 if ($DidAnyDLLBuildFail -eq $true) { 295 Write-Error -Message "Unable to build all known variants of SDL2 for WinRT" 296 exit 1 297 } elseif ($DidAnyNugetBuildFail -eq $true) { 298 Write-Warning -Message "Unable to build NuGet packages" 299 exit 0 # Should NuGet package build failure lead to a non-failing result code instead? 300 } else { 301 exit 0 302 }