2016-09-19 11:50:08 +08:00
[ CmdletBinding ( ) ]
param (
2018-06-13 08:12:33 +08:00
$badParam ,
[ Parameter ( Mandatory = $False ) ] [ switch ] $disableMetrics = $false ,
2018-06-14 02:21:12 +08:00
[ Parameter ( Mandatory = $False ) ] [ switch ] $win64 = $false ,
2018-06-09 04:31:57 +08:00
[ Parameter ( Mandatory = $False ) ] [ string ] $withVSPath = " " ,
[ Parameter ( Mandatory = $False ) ] [ string ] $withWinSDK = " "
2016-09-19 11:50:08 +08:00
)
2018-03-01 10:44:57 +08:00
Set-StrictMode -Version Latest
2018-06-13 08:12:33 +08:00
# Powershell2-compatible way of forcing named-parameters
if ( $badParam )
{
if ( $disableMetrics -and $badParam -eq " 1 " )
{
Write-Warning " 'disableMetrics 1' is deprecated, please change to 'disableMetrics' (without '1') "
}
else
{
throw " Only named parameters are allowed "
}
}
2018-01-23 10:18:53 +08:00
$scriptsDir = split-path -parent $script:MyInvocation . MyCommand . Definition
2018-05-05 19:23:19 +08:00
$withVSPath = $withVSPath -replace " \\ $ " # Remove potential trailing backslash
2018-05-20 09:07:09 +08:00
2018-05-20 08:54:50 +08:00
function vcpkgHasProperty([Parameter(Mandatory=$true)][AllowNull()]$object , [ Parameter ( Mandatory = $true ) ] $propertyName )
{
2019-02-23 02:47:48 +08:00
if ( $null -eq $object )
2018-05-20 08:54:50 +08:00
{
return $false
}
return [ bool ] ( $object . psobject . Properties | Where-Object { $_ . Name -eq " $propertyName " } )
}
function getProgramFiles32bit ( )
{
$out = $ { env : PROGRAMFILES ( X86 ) }
2019-02-23 02:47:48 +08:00
if ( $null -eq $out )
2018-05-20 08:54:50 +08:00
{
$out = $ { env : PROGRAMFILES }
}
2019-02-23 02:47:48 +08:00
if ( $null -eq $out )
2018-05-20 08:54:50 +08:00
{
throw " Could not find [Program Files 32-bit] "
}
return $out
}
2018-02-23 11:56:08 +08:00
2018-05-20 10:38:45 +08:00
$vcpkgRootDir = $scriptsDir
2018-05-05 19:23:19 +08:00
while ( ! ( $vcpkgRootDir -eq " " ) -and ! ( Test-Path " $vcpkgRootDir \.vcpkg-root " ) )
2017-08-26 14:25:41 +08:00
{
2018-05-05 19:23:19 +08:00
Write-Verbose " Examining $vcpkgRootDir for .vcpkg-root "
$vcpkgRootDir = Split-path $vcpkgRootDir -Parent
2017-08-26 14:25:41 +08:00
}
2018-05-05 19:23:19 +08:00
Write-Verbose " Examining $vcpkgRootDir for .vcpkg-root - Found "
2018-02-23 11:56:08 +08:00
2016-09-20 09:46:02 +08:00
$vcpkgSourcesPath = " $vcpkgRootDir \toolsrc "
2016-09-19 11:50:08 +08:00
if ( ! ( Test-Path $vcpkgSourcesPath ) )
{
2017-11-01 14:41:24 +08:00
Write-Error " Unable to determine vcpkg sources directory. ' $vcpkgSourcesPath ' does not exist. "
return
2016-09-19 11:50:08 +08:00
}
2018-05-20 08:54:12 +08:00
function getVisualStudioInstances ( )
{
$programFiles = getProgramFiles32bit
$results = New-Object System . Collections . ArrayList
$vswhereExe = " $programFiles \Microsoft Visual Studio\Installer\vswhere.exe "
if ( Test-Path $vswhereExe )
{
$output = & $vswhereExe -prerelease -legacy -products * -format xml
[ xml ] $asXml = $output
foreach ( $instance in $asXml . instances . instance )
{
$installationPath = $instance . InstallationPath -replace " \\ $ " # Remove potential trailing backslash
$installationVersion = $instance . InstallationVersion
$isPrerelease = -7
if ( vcpkgHasProperty -object $instance -propertyName " isPrerelease " )
{
$isPrerelease = $instance . isPrerelease
}
if ( $isPrerelease -eq 0 )
{
$releaseType = " PreferenceWeight3::StableRelease "
}
elseif ( $isPrerelease -eq 1 )
{
$releaseType = " PreferenceWeight2::PreRelease "
}
else
{
$releaseType = " PreferenceWeight1::Legacy "
}
# Placed like that for easy sorting according to preference
2018-05-20 09:07:09 +08:00
$results . Add ( " ${releaseType} :: ${installationVersion} :: ${installationPath} " ) > $null
2018-05-20 08:54:12 +08:00
}
}
else
{
Write-Verbose " Could not locate vswhere at $vswhereExe "
}
if ( " $env:vs140comntools " -ne " " )
{
$installationPath = Split-Path -Parent $ ( Split-Path -Parent " $env:vs140comntools " )
$clExe = " $installationPath \VC\bin\cl.exe "
$vcvarsallbat = " $installationPath \VC\vcvarsall.bat "
if ( ( Test-Path $clExe ) -And ( Test-Path $vcvarsallbat ) )
{
2018-05-20 09:07:09 +08:00
$results . Add ( " PreferenceWeight1::Legacy::14.0:: $installationPath " ) > $null
2018-05-20 08:54:12 +08:00
}
}
$installationPath = " $programFiles \Microsoft Visual Studio 14.0 "
$clExe = " $installationPath \VC\bin\cl.exe "
$vcvarsallbat = " $installationPath \VC\vcvarsall.bat "
if ( ( Test-Path $clExe ) -And ( Test-Path $vcvarsallbat ) )
{
2018-05-20 09:07:09 +08:00
$results . Add ( " PreferenceWeight1::Legacy::14.0:: $installationPath " ) > $null
2018-05-20 08:54:12 +08:00
}
$results . Sort ( )
$results . Reverse ( )
return $results
}
2018-05-05 19:23:19 +08:00
function findAnyMSBuildWithCppPlatformToolset([string]$withVSPath )
{
2018-05-20 08:54:12 +08:00
$VisualStudioInstances = getVisualStudioInstances
2019-02-23 02:47:48 +08:00
if ( $null -eq $VisualStudioInstances )
2018-05-05 19:23:19 +08:00
{
throw " Could not find Visual Studio. VS2015 or VS2017 (with C++) needs to be installed. "
}
Write-Verbose " VS Candidates: `n `r $( [ system.String ] :: Join ( [ Environment ] :: NewLine , $VisualStudioInstances ) ) "
2018-05-20 09:07:09 +08:00
foreach ( $instanceCandidate in $VisualStudioInstances )
2018-05-05 19:23:19 +08:00
{
Write-Verbose " Inspecting: $instanceCandidate "
$split = $instanceCandidate -split " :: "
# $preferenceWeight = $split[0]
# $releaseType = $split[1]
$version = $split [ 2 ]
$path = $split [ 3 ]
if ( $withVSPath -ne " " -and $withVSPath -ne $path )
{
Write-Verbose " Skipping: $instanceCandidate "
continue
}
$majorVersion = $version . Substring ( 0 , 2 ) ;
2018-12-11 16:31:44 +08:00
if ( $majorVersion -eq " 16 " )
{
$VCFolder = " $path \VC\Tools\MSVC\ "
if ( Test-Path $VCFolder )
{
Write-Verbose " Picking: $instanceCandidate "
2019-01-26 06:56:05 +08:00
return " $path \MSBuild\Current\Bin\MSBuild.exe " , " v142 "
2018-12-11 16:31:44 +08:00
}
}
2018-05-05 19:23:19 +08:00
if ( $majorVersion -eq " 15 " )
{
$VCFolder = " $path \VC\Tools\MSVC\ "
if ( Test-Path $VCFolder )
{
Write-Verbose " Picking: $instanceCandidate "
return " $path \MSBuild\15.0\Bin\MSBuild.exe " , " v141 "
}
}
if ( $majorVersion -eq " 14 " )
{
$clExe = " $path \VC\bin\cl.exe "
if ( Test-Path $clExe )
{
Write-Verbose " Picking: $instanceCandidate "
$programFilesPath = getProgramFiles32bit
return " $programFilesPath \MSBuild\14.0\Bin\MSBuild.exe " , " v140 "
}
}
}
2019-01-26 06:56:05 +08:00
throw " Could not find MSBuild version with C++ support. VS2015, VS2017, or VS2019 (with C++) needs to be installed. "
2018-05-05 19:23:19 +08:00
}
2018-05-20 08:50:51 +08:00
function getWindowsSDK ( [ Parameter ( Mandatory = $False ) ] [ switch ] $DisableWin10SDK = $False ,
2018-06-09 04:31:57 +08:00
[ Parameter ( Mandatory = $False ) ] [ switch ] $DisableWin81SDK = $False ,
[ Parameter ( Mandatory = $False ) ] [ string ] $withWinSDK )
2018-05-20 08:50:51 +08:00
{
if ( $DisableWin10SDK -and $DisableWin81SDK )
{
throw " Both Win10SDK and Win81SDK were disabled. "
}
Write-Verbose " Finding WinSDK "
$validInstances = New-Object System . Collections . ArrayList
# Windows 10 SDK
function CheckWindows10SDK($path )
{
2019-02-23 02:47:48 +08:00
if ( $null -eq $path )
2018-05-20 08:50:51 +08:00
{
return
}
$folder = ( Join-Path $path " Include " )
if ( ! ( Test-Path $folder ) )
{
Write-Verbose " $folder - Not Found "
return
}
Write-Verbose " $folder - Found "
$win10sdkVersions = @ ( Get-ChildItem $folder | Where-Object { $_ . Name -match " ^10 " } | Sort-Object )
[ array ] :: Reverse ( $win10sdkVersions ) # Newest SDK first
2019-09-01 20:09:34 +08:00
foreach ( $win10sdk in $win10sdkVersions )
2018-05-20 08:50:51 +08:00
{
2019-09-01 20:09:34 +08:00
$win10sdkV = $win10sdk . Name
2018-05-20 08:50:51 +08:00
$windowsheader = " $folder \ $win10sdkV \um\windows.h "
if ( ! ( Test-Path $windowsheader ) )
{
Write-Verbose " $windowsheader - Not Found "
continue
}
Write-Verbose " $windowsheader - Found "
$ddkheader = " $folder \ $win10sdkV \shared\sdkddkver.h "
if ( ! ( Test-Path $ddkheader ) )
{
Write-Verbose " $ddkheader - Not Found "
continue
}
Write-Verbose " $ddkheader - Found "
$win10sdkVersionString = $win10sdkV . ToString ( )
Write-Verbose " Found $win10sdkVersionString "
$validInstances . Add ( $win10sdkVersionString ) > $null
}
}
Write-Verbose " `n "
Write-Verbose " Looking for Windows 10 SDK "
$regkey10 = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots\' -Name 'KitsRoot10' -ErrorAction SilentlyContinue
$regkey10Wow6432 = Get-ItemProperty -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots\' -Name 'KitsRoot10' -ErrorAction SilentlyContinue
if ( vcpkgHasProperty -object $regkey10 " KitsRoot10 " ) { CheckWindows10SDK ( $regkey10 . KitsRoot10 ) }
if ( vcpkgHasProperty -object $regkey10Wow6432 " KitsRoot10 " ) { CheckWindows10SDK ( $regkey10Wow6432 . KitsRoot10 ) }
CheckWindows10SDK ( " $env:ProgramFiles \Windows Kits\10 " )
CheckWindows10SDK ( " $ {env:ProgramFiles(x86)}\Windows Kits\10 " )
# Windows 8.1 SDK
function CheckWindows81SDK($path )
{
2019-02-23 02:47:48 +08:00
if ( $null -eq $path )
2018-05-20 08:50:51 +08:00
{
return
}
$folder = " $path \Include "
if ( ! ( Test-Path $folder ) )
{
Write-Verbose " $folder - Not Found "
return
}
Write-Verbose " $folder - Found "
$win81sdkVersionString = " 8.1 "
Write-Verbose " Found $win81sdkVersionString "
$validInstances . Add ( $win81sdkVersionString ) > $null
}
Write-Verbose " `n "
Write-Verbose " Looking for Windows 8.1 SDK "
$regkey81 = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots\' -Name 'KitsRoot81' -ErrorAction SilentlyContinue
$regkey81Wow6432 = Get-ItemProperty -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots\' -Name 'KitsRoot81' -ErrorAction SilentlyContinue
if ( vcpkgHasProperty -object $regkey81 " KitsRoot81 " ) { CheckWindows81SDK ( $regkey81 . KitsRoot81 ) }
if ( vcpkgHasProperty -object $regkey81Wow6432 " KitsRoot81 " ) { CheckWindows81SDK ( $regkey81Wow6432 . KitsRoot81 ) }
CheckWindows81SDK ( " $env:ProgramFiles \Windows Kits\8.1 " )
CheckWindows81SDK ( " $ {env:ProgramFiles(x86)}\Windows Kits\8.1 " )
Write-Verbose " `n `n `n "
Write-Verbose " The following Windows SDKs were found: "
foreach ( $instance in $validInstances )
{
Write-Verbose $instance
}
# Selecting
2018-06-09 04:31:57 +08:00
if ( $withWinSDK -ne " " )
{
foreach ( $instance in $validInstances )
{
if ( $instance -eq $withWinSDK )
{
return $instance
}
}
throw " Could not find the requested Windows SDK version: $withWinSDK "
}
2018-05-20 08:50:51 +08:00
foreach ( $instance in $validInstances )
{
if ( ! $DisableWin10SDK -and $instance -match " 10. " )
{
return $instance
}
if ( ! $DisableWin81SDK -and $instance -match " 8.1 " )
{
return $instance
}
}
throw " Could not detect a Windows SDK / TargetPlatformVersion "
}
2018-05-05 19:23:19 +08:00
$msbuildExeWithPlatformToolset = findAnyMSBuildWithCppPlatformToolset $withVSPath
2018-01-26 08:48:32 +08:00
$msbuildExe = $msbuildExeWithPlatformToolset [ 0 ]
$platformToolset = $msbuildExeWithPlatformToolset [ 1 ]
2018-06-09 04:31:57 +08:00
$windowsSDK = getWindowsSDK -withWinSDK $withWinSDK
2018-01-23 10:19:30 +08:00
2018-06-13 08:12:33 +08:00
$disableMetricsValue = " 0 "
if ( $disableMetrics )
{
$disableMetricsValue = " 1 "
}
2018-06-14 02:21:12 +08:00
$platform = " x86 "
2018-10-31 07:40:38 +08:00
$vcpkgReleaseDir = " $vcpkgSourcesPath \msbuild.x86.release "
2019-06-17 14:09:07 +08:00
if ( $PSVersionTable . PSVersion . Major -le 2 )
{
$architecture = ( Get-WmiObject win32_operatingsystem | Select-Object osarchitecture ) . osarchitecture
}
else
{
$architecture = ( Get-CimInstance win32_operatingsystem | Select-Object osarchitecture ) . osarchitecture
}
2018-06-14 02:54:33 +08:00
if ( $win64 )
2018-06-14 02:21:12 +08:00
{
2018-07-09 11:57:51 +08:00
if ( -not $architecture -like " *64* " )
2018-06-14 02:54:33 +08:00
{
throw " Cannot build 64-bit on non-64-bit system "
}
2018-06-14 02:21:12 +08:00
$platform = " x64 "
2018-10-31 07:40:38 +08:00
$vcpkgReleaseDir = " $vcpkgSourcesPath \msbuild.x64.release "
2018-06-14 02:21:12 +08:00
}
2019-05-21 06:48:59 +08:00
if ( $architecture -like " *64* " )
{
$PreferredToolArchitecture = " x64 "
}
else
{
$PreferredToolArchitecture = " x86 "
}
2018-01-26 08:48:32 +08:00
$arguments = (
2018-05-20 09:08:10 +08:00
" `" /p:VCPKG_VERSION=-nohash `" " ,
2018-06-13 08:12:33 +08:00
" `" /p:DISABLE_METRICS= $disableMetricsValue `" " ,
2018-07-03 16:18:02 +08:00
" /p:Configuration=Release " ,
2018-06-14 02:21:12 +08:00
" /p:Platform= $platform " ,
2018-01-26 08:48:32 +08:00
" /p:PlatformToolset= $platformToolset " ,
" /p:TargetPlatformVersion= $windowsSDK " ,
2019-05-21 06:48:59 +08:00
" /p:PreferredToolArchitecture= $PreferredToolArchitecture " ,
2018-05-05 19:23:19 +08:00
" /verbosity:minimal " ,
2018-01-26 08:48:32 +08:00
" /m " ,
2018-05-05 19:23:19 +08:00
" /nologo " ,
2018-01-26 09:03:37 +08:00
" `" $vcpkgSourcesPath \dirs.proj `" " ) -join " "
2016-09-19 11:50:08 +08:00
2018-05-05 19:23:19 +08:00
function vcpkgInvokeCommandClean ( )
{
param ( [ Parameter ( Mandatory = $true ) ] [ string ] $executable ,
[ string ] $arguments = " " )
Write-Verbose " Clean-Executing: ${executable} ${arguments} "
$scriptsDir = split-path -parent $script:MyInvocation . MyCommand . Definition
2018-05-20 09:24:50 +08:00
$cleanEnvScript = " $scriptsDir \cleanEnvironmentHelper.ps1 "
2018-05-05 19:23:19 +08:00
$tripleQuotes = " `" `" `" "
$argumentsWithEscapedQuotes = $arguments -replace " `" " , $tripleQuotes
$command = " . $tripleQuotes $cleanEnvScript $tripleQuotes ; & $tripleQuotes $executable $tripleQuotes $argumentsWithEscapedQuotes "
$arg = " -NoProfile " , " -ExecutionPolicy Bypass " , " -command $command "
$process = Start-Process -FilePath powershell . exe -ArgumentList $arg -PassThru -NoNewWindow
Wait-Process -InputObject $process
$ec = $process . ExitCode
Write-Verbose " Execution terminated with exit code $ec . "
return $ec
}
2018-01-26 08:48:32 +08:00
# vcpkgInvokeCommandClean cmd "/c echo %PATH%"
2018-05-05 19:23:19 +08:00
Write-Host " `n Building vcpkg.exe ... `n "
2018-01-26 08:48:32 +08:00
$ec = vcpkgInvokeCommandClean $msbuildExe $arguments
2016-09-19 11:50:08 +08:00
2018-01-26 08:48:32 +08:00
if ( $ec -ne 0 )
2017-08-26 14:25:41 +08:00
{
2018-01-26 08:48:32 +08:00
Write-Error " Building vcpkg.exe failed. Please ensure you have installed Visual Studio with the Desktop C++ workload and the Windows SDK for Desktop C++. "
return
2016-09-19 11:50:08 +08:00
}
2018-05-05 19:23:19 +08:00
Write-Host " `n Building vcpkg.exe... done. `n "
2018-01-26 08:48:32 +08:00
2019-01-26 06:56:05 +08:00
Write-Verbose " Placing vcpkg.exe in the correct location "
2018-01-26 08:48:32 +08:00
2018-11-01 16:36:51 +08:00
Copy-Item " $vcpkgReleaseDir \vcpkg.exe " " $vcpkgRootDir \vcpkg.exe "
Copy-Item " $vcpkgReleaseDir \vcpkgmetricsuploader.exe " " $vcpkgRootDir \scripts\vcpkgmetricsuploader.exe "
2018-11-01 16:36:37 +08:00
Remove-Item " $vcpkgReleaseDir " -Force -Recurse -ErrorAction SilentlyContinue