build-scripts/winrtbuild.ps1
author Ryan C. Gordon
Mon, 21 Aug 2017 00:42:06 -0400
changeset 11334 749cb40916f2
parent 10911 1863707d9df8
child 11791 c2827923649c
permissions -rw-r--r--
x11: specify event mask for buttons when grabbing pointer (thanks, Stas!).

This fixes a strange corner case (notes appended below), and should be
safe to do anyhow.

Fixes Bugzilla #3674.

"I did more tests.
It appears the bug only happens if there is
another window on the screen that has "always
on top" property. For me it is xawtv - it is
always opened in a screen corner. Closing
xawtv or removing "always on top" property
from it makes the problem to go away.
Plus, it doesn't appear like the buttons are
not delivered at all. It appears that instead
the button presses are delivered on some mouse
positions, but not delivered when you move the
mouse to other part of the window... So this is
really weird and is likely somewhere deep in the
Xorg.
Maybe somehow it happens that the cursor is
actually above the xawtv window, but, because
my app uses grab, it is not visible there, and
in that case the events are not delivered to
my app?
But with my patch the button events are
always delivered flawlessly, it seems.

Hmm, and that indeed seems to explain my problem:
if the mask is set properly and my app uses
grab, then, even if the mouse is above some
other window, the events would still be delivered
to the grabbing app, which is what actually wanted
because my app uses relative mouse mode, so it
doesn't know the pointer can cross some other window
(my app draws the pointer itself).
So my current theory is that my patch only enforces
the mouse grab, which otherwise can be tricked by
some other window preventing the button events
delivery (but motion events are still delivered
via xinput2, which makes it all look very obscure)."
     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.4"
    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 # Build for Windows Phone 8.0, via VC++ 2012:
   215 if ( ! (Build-SDL-WinRT-Variant "SDL" "v110_wp80" "ARM"))   { $DidAnyDLLBuildFail = $true }
   216 if ( ! (Build-SDL-WinRT-Variant "SDL" "v110_wp80" "Win32")) { $DidAnyDLLBuildFail = $true }
   217 
   218 # Build for Windows Phone 8.1, via VC++ 2013:
   219 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120_wp81" "ARM"))   { $DidAnyDLLBuildFail = $true }
   220 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120_wp81" "Win32")) { $DidAnyDLLBuildFail = $true }
   221 
   222 # Build for Windows 8.0 and Windows RT 8.0, via VC++ 2012:
   223 #
   224 # Win 8.0 auto-building was disabled on 2017-Feb-25, by David Ludwig <dludwig@pobox.com>.
   225 # Steam's OS-usage surveys indicate that Windows 8.0 use is pretty much nil, plus
   226 # Microsoft hasn't supported Windows 8.0 development for a few years now.
   227 # The commented-out lines below may still work on some systems, though.
   228 # 
   229 #if ( ! (Build-SDL-WinRT-Variant "SDL" "v110" "ARM"))        { $DidAnyDLLBuildFail = $true }
   230 #if ( ! (Build-SDL-WinRT-Variant "SDL" "v110" "Win32"))      { $DidAnyDLLBuildFail = $true }
   231 #if ( ! (Build-SDL-WinRT-Variant "SDL" "v110" "x64"))        { $DidAnyDLLBuildFail = $true }
   232 
   233 # Build for Windows 8.1 and Windows RT 8.1, via VC++ 2013:
   234 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120" "ARM"))        { $DidAnyDLLBuildFail = $true }
   235 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120" "Win32"))      { $DidAnyDLLBuildFail = $true }
   236 if ( ! (Build-SDL-WinRT-Variant "SDL" "v120" "x64"))        { $DidAnyDLLBuildFail = $true }
   237 
   238 # Build for Windows 10, via VC++ 2015
   239 if ( ! (Build-SDL-WinRT-Variant "SDL" "v140" "ARM"))        { $DidAnyDLLBuildFail = $true }
   240 if ( ! (Build-SDL-WinRT-Variant "SDL" "v140" "Win32"))      { $DidAnyDLLBuildFail = $true }
   241 if ( ! (Build-SDL-WinRT-Variant "SDL" "v140" "x64"))        { $DidAnyDLLBuildFail = $true }
   242 
   243 # Build NuGet packages, if possible
   244 if ($DidAnyDLLBuildFail -eq $true) {
   245     Write-Warning -Message "Unable to build all variants.  NuGet packages will not be built."
   246     $DidAnyNugetBuildFail = $true
   247 } else {
   248     $NugetPath = (Get-Command -CommandType Application nuget.exe | %{$_.Path}) 2> $null
   249     if ("$NugetPath" -eq "") {
   250         Write-Warning -Message "Unable to find nuget.exe.  NuGet packages will not be built."
   251         $DidAnyNugetBuildFail = $true
   252     } else {
   253         Write-Host -ForegroundColor Cyan "Building SDL2 NuGet packages..."
   254         Write-Host -ForegroundColor Cyan "... via NuGet install: $NugetPath"
   255         $NugetOutputDir = "$PSScriptRoot\..\VisualC-WinRT\lib\nuget"
   256         Write-Host -ForegroundColor Cyan "...  output directory: $NugetOutputDir"
   257         $SDLHGRevision = $($(hg log -l 1 --repository "$PSScriptRoot\.." | select-string "changeset") -Replace "changeset:\W*(\d+).*",'$1') 2>$null
   258         Write-Host -ForegroundColor Cyan "...       HG Revision: $SDLHGRevision"
   259 
   260         # Base options to nuget.exe
   261         $NugetOptions = @("pack", "PACKAGE_NAME_WILL_GO_HERE", "-Output", "$NugetOutputDir")
   262 
   263         # Try attaching hg revision to NuGet package:
   264         $NugetOptions += "-Version"
   265         if ("$SDLHGRevision" -eq "") {
   266             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."
   267             $NugetOptions += "$SDLVersion-Unofficial"
   268         } else {
   269             $NugetOptions += "$SDLVersion.$SDLHGRevision-Unofficial"
   270         }
   271 
   272         # Create NuGet output dir, if not yet created:
   273         if ($(Test-Path "$NugetOutputDir") -eq $false) {
   274             New-Item "$NugetOutputDir" -type directory
   275         }
   276 
   277         # Package SDL2:
   278         $NugetOptions[1] = "$PSScriptRoot\..\VisualC-WinRT\SDL2-WinRT.nuspec"
   279         &"$NugetPath" $NugetOptions -Symbols
   280         if ( ! $? ) { $DidAnyNugetBuildFail = $true }
   281 
   282         # Package SDL2main:
   283         $NugetOptions[1] = "$PSScriptRoot\..\VisualC-WinRT\SDL2main-WinRT-NonXAML.nuspec"
   284         &"$NugetPath" $NugetOptions
   285         if ( ! $? ) { $DidAnyNugetBuildFail = $true }
   286     }
   287 }
   288 
   289 
   290 # Let the script's caller know whether or not any errors occurred.
   291 # Exit codes compatible with Buildbot are used (1 for error, 0 for success).
   292 if ($DidAnyDLLBuildFail -eq $true) {
   293     Write-Error -Message "Unable to build all known variants of SDL2 for WinRT"
   294     exit 1
   295 } elseif ($DidAnyNugetBuildFail -eq $true) {
   296     Write-Warning -Message "Unable to build NuGet packages"
   297     exit 0  # Should NuGet package build failure lead to a non-failing result code instead?
   298 } else {
   299     exit 0
   300 }