build-scripts/winrtbuild.ps1
author David Ludwig <dludwig@pobox.com>
Mon, 30 Nov 2015 21:11:33 -0500
changeset 9935 93fd2ca0ed98
parent 9735 35d8f8976d32
child 9940 f2d5ed0d9686
permissions -rw-r--r--
WinRT: made WinRT build script create Win10/UWP .dll files
     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 
    42 # Gets the .bat file that sets up an MSBuild environment, given one of
    43 # Visual Studio's, "PlatformToolset"s.
    44 function Get-MSBuild-Env-Launcher
    45 {
    46     param(
    47         [Parameter(Mandatory=$true,Position=1)][string]$PlatformToolset
    48     )
    49 
    50     if ($PlatformToolset -eq "v110") {      # Windows 8.0 (not Windows Phone), via VS 2012
    51         return "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"
    52     }
    53     if ($PlatformToolset -eq "v110_wp80") { # Windows Phone 8.0, via VS 2012
    54         return "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\WPSDK\WP80\vcvarsphoneall.bat"
    55     }
    56     if ($PlatformToolset -eq "v120") {      # Windows 8.1 (not Windows Phone), via VS 2013
    57         return "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
    58     }
    59     if ($PlatformToolset -eq "v120_wp81") { # Windows Phone 8.1, via VS 2013
    60         return "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
    61     }
    62     if ($PlatformToolset -eq "v140") {      # Windows 10, via VS 2015
    63         return "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
    64     }
    65     return ""
    66 }
    67 
    68 # Gets a string that identifies the build-variant of SDL/WinRT that is specific
    69 # to a particular Visual Studio PlatformToolset.
    70 function Get-SDL-WinRT-Variant-Name
    71 {
    72     param(
    73         [Parameter(Mandatory=$true,Position=1)][string]$PlatformToolset,
    74 
    75         # If true, append a string to this function's output, identifying the
    76         # build-variant's minimum-supported version of Visual Studio.
    77         [switch]$IncludeVSSuffix = $false
    78     )
    79 
    80     if ($PlatformToolset -eq "v110") {      # Windows 8.0 (not Windows Phone), via VS 2012 project files
    81         if ($IncludeVSSuffix) {
    82             return "WinRT80_VS2012"
    83         } else {
    84             return "WinRT80"
    85         }
    86     }
    87     if ($PlatformToolset -eq "v110_wp80") { # Windows Phone 8.0, via VS 2012 project files
    88         if ($IncludeVSSuffix) {
    89             return "WinPhone80_VS2012"
    90         } else {
    91             return "WinPhone80"
    92         }
    93     }
    94     if ($PlatformToolset -eq "v120") {      # Windows 8.1 (not Windows Phone), via VS 2013 project files
    95         if ($IncludeVSSuffix) {
    96             return "WinRT81_VS2013"
    97         } else {
    98             return "WinRT81"
    99         }
   100     }
   101     if ($PlatformToolset -eq "v120_wp81") { # Windows Phone 8.1, via VS 2013 project files
   102         if ($IncludeVSSuffix) {
   103             return "WinPhone81_VS2013"
   104         } else {
   105             return "WinPhone81"
   106         }
   107     }
   108     if ($PlatformToolset -eq "v140") {      # Windows 10, via VS 2015 project files
   109         if ($IncludeVSSuffix) {
   110             return "UWP_VS2015"
   111         } else {
   112             return "UWP"
   113         }
   114     }
   115     return ""
   116 }
   117 
   118 # Returns the internal name of a Visual Studio Project.
   119 #
   120 # The internal name of a VS Project is encoded inside the project file
   121 # itself, inside a set of <ProjectName></ProjectName> XML tags.
   122 function Get-VS-ProjectName
   123 {
   124     param(
   125         [Parameter(Mandatory=$true,Position=1)]$VSProjectPath
   126     )
   127 
   128     # For now, just do a regex for the project name:
   129     $matches = (Get-Content $VSProjectPath | Select-String -Pattern ".*<ProjectName>([^<]+)<.*").Matches
   130     foreach ($match in $matches) {
   131         if ($match.Groups.Count -ge 1) {
   132             return $match.Groups[1].Value
   133         }
   134     }
   135     return $null
   136 }
   137 
   138 # Build a specific variant of SDL/WinRT
   139 function Build-SDL-WinRT-Variant
   140 {
   141     #
   142     # Read in arguments:
   143     #
   144     param (
   145         # name of an SDL project file, minus extensions and
   146         # platform-identifying suffixes
   147         [Parameter(Mandatory=$true,Position=1)][string]$SDLProjectName,
   148 
   149         [Parameter(Mandatory=$true,Position=2)][string]$PlatformToolset,
   150 
   151         [Parameter(Mandatory=$true,Position=3)][string]$Platform
   152     )
   153 
   154     #
   155     # Derive other properties from read-in arguments:
   156     #
   157 
   158     # The .bat file to setup a platform-appropriate MSBuild environment:
   159     $BatchFileForMSBuildEnv = Get-MSBuild-Env-Launcher $PlatformToolset
   160 
   161     # The full path to the VS Project that'll be built:
   162     $VSProjectPath = "$PSScriptRoot\..\VisualC-WinRT\$(Get-SDL-WinRT-Variant-Name $PlatformToolset -IncludeVSSuffix)\$SDLProjectName-$(Get-SDL-WinRT-Variant-Name $PlatformToolset).vcxproj"
   163 
   164     # The internal name of the VS Project, used in some post-build steps:
   165     $VSProjectName = Get-VS-ProjectName $VSProjectPath
   166 
   167     # Where to place output binaries (.dll, .lib, and .pdb files):
   168     $OutDir = "$PSScriptRoot\..\VisualC-WinRT\lib\$PlatformToolset\$Platform"
   169 
   170     # Where to place intermediate build files:
   171     $IntermediateDir = "$PSScriptRoot\..\VisualC-WinRT\obj\$SDLProjectName-$(Get-SDL-WinRT-Variant-Name $PlatformToolset)\$Platform"
   172 
   173     #
   174     # Build the VS Project:
   175     #
   176     cmd.exe /c " ""$BatchFileForMSBuildEnv"" x86 & msbuild ""$VSProjectPath"" /p:Configuration=Release /p:Platform=$Platform /p:OutDir=""$OutDir\\"" /p:IntDir=""$IntermediateDir\\""" | Out-Host
   177     $BuildResult = $?
   178 
   179     #
   180     # Move .dll files into place.  This fixes a problem whereby MSBuild may
   181     # put output files into a sub-directory of $OutDir, rather than $OutDir
   182     # itself.
   183     #
   184     if (Test-Path "$OutDir\$VSProjectName\") {
   185         Move-Item -Force "$OutDir\$VSProjectName\*" "$OutDir"
   186     }
   187 
   188     #
   189     # Clean up unneeded files in $OutDir:
   190     #
   191     if (Test-Path "$OutDir\$VSProjectName\") {
   192         Remove-Item -Recurse "$OutDir\$VSProjectName"
   193     }
   194     Remove-Item "$OutDir\*.exp"
   195     Remove-Item "$OutDir\*.ilk"
   196     Remove-Item "$OutDir\*.pri"
   197 
   198     #
   199     # All done.  Indicate success, or failure, to the caller:
   200     #
   201     #echo "RESULT: $BuildResult" | Out-Host
   202     return $BuildResult
   203 }
   204 
   205 
   206 #
   207 # Build each variant, with corresponding .dll, .lib, and .pdb files:
   208 #
   209 $DidAnyFail = $false
   210 
   211 # Build for Windows Phone 8.0, via VC++ 2012:
   212 if ( ! (Build-SDL-WinRT-Variant "SDL" "v110_wp80" "ARM"))   { $DidAnyFail = $true }
   213 if ( ! (Build-SDL-WinRT-Variant "SDL" "v110_wp80" "Win32")) { $DidAnyFail = $true }
   214 
   215 # Build for Windows Phone 8.1, via VC++ 2013:
   216 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120_wp81" "ARM"))   { $DidAnyFail = $true }
   217 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120_wp81" "Win32")) { $DidAnyFail = $true }
   218 
   219 # Build for Windows 8.0 and Windows RT 8.0, via VC++ 2012:
   220 if ( ! (Build-SDL-WinRT-Variant "SDL" "v110" "ARM"))        { $DidAnyFail = $true }
   221 if ( ! (Build-SDL-WinRT-Variant "SDL" "v110" "Win32"))      { $DidAnyFail = $true }
   222 if ( ! (Build-SDL-WinRT-Variant "SDL" "v110" "x64"))        { $DidAnyFail = $true }
   223 
   224 # Build for Windows 8.1 and Windows RT 8.1, via VC++ 2013:
   225 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120" "ARM"))        { $DidAnyFail = $true }
   226 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120" "Win32"))      { $DidAnyFail = $true }
   227 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120" "x64"))        { $DidAnyFail = $true }
   228 
   229 # Build for Windows 10, via VC++ 2015
   230 if ( ! (Build-SDL-WinRT-Variant "SDL" "v140" "ARM"))        { $DidAnyFail = $true }
   231 if ( ! (Build-SDL-WinRT-Variant "SDL" "v140" "Win32"))      { $DidAnyFail = $true }
   232 if ( ! (Build-SDL-WinRT-Variant "SDL" "v140" "x64"))        { $DidAnyFail = $true }
   233 
   234 # Let the script's caller know whether or not any errors occurred.
   235 # Exit codes compatible with Buildbot are used (1 for error, 0 for success).
   236 if ($DidAnyFail -eq $true) {
   237     exit 1
   238 } else {
   239     exit 0
   240 }