diff --git a/scripts/VcpkgPowershellUtils.ps1 b/scripts/VcpkgPowershellUtils.ps1 index 3ea18116b8..259df4acb6 100644 --- a/scripts/VcpkgPowershellUtils.ps1 +++ b/scripts/VcpkgPowershellUtils.ps1 @@ -1,8 +1,3 @@ -function vcpkgHasModule([Parameter(Mandatory=$true)][string]$moduleName) -{ - return [bool](Get-Module -ListAvailable -Name $moduleName) -} - function vcpkgHasProperty([Parameter(Mandatory=$true)][AllowNull()]$object, [Parameter(Mandatory=$true)]$propertyName) { if ($object -eq $null) @@ -10,320 +5,21 @@ function vcpkgHasProperty([Parameter(Mandatory=$true)][AllowNull()]$object, [Par return $false } - return [bool]($object.psobject.Properties | where { $_.Name -eq "$propertyName"}) + return [bool]($object.psobject.Properties | Where-Object { $_.Name -eq "$propertyName"}) } -function vcpkgCreateDirectoryIfNotExists([Parameter(Mandatory=$true)][string]$dirPath) +function getProgramFiles32bit() { - if (!(Test-Path $dirPath)) + $out = ${env:PROGRAMFILES(X86)} + if ($out -eq $null) { - New-Item -ItemType Directory -Path $dirPath | Out-Null - } -} - -function vcpkgCreateParentDirectoryIfNotExists([Parameter(Mandatory=$true)][string]$path) -{ - $parentDir = split-path -parent $path - if ([string]::IsNullOrEmpty($parentDir)) - { - return + $out = ${env:PROGRAMFILES} } - if (!(Test-Path $parentDir)) + if ($out -eq $null) { - New-Item -ItemType Directory -Path $parentDir | Out-Null - } -} - -function vcpkgIsDirectory([Parameter(Mandatory=$true)][string]$path) -{ - return (Get-Item $path) -is [System.IO.DirectoryInfo] -} - -function vcpkgRemoveItem([Parameter(Mandatory=$true)][string]$path) -{ - if ([string]::IsNullOrEmpty($path)) - { - return + throw "Could not find [Program Files 32-bit]" } - if (Test-Path $path) - { - # Remove-Item -Recurse occasionally fails. This is a workaround - if (vcpkgIsDirectory $path) - { - & cmd.exe /c rd /s /q $path - } - else - { - Remove-Item $path -Force - } - } -} - -function vcpkgHasCommand([Parameter(Mandatory=$true)][string]$commandName) -{ - return [bool](Get-Command -Name $commandName -ErrorAction SilentlyContinue) -} - -function vcpkgHasCommandParameter([Parameter(Mandatory=$true)][string]$commandName, [Parameter(Mandatory=$true)][string]$parameterName) -{ - return (Get-Command $commandName).Parameters.Keys -contains $parameterName -} - -function vcpkgGetCredentials() -{ - if (vcpkgHasCommandParameter -commandName 'Get-Credential' -parameterName 'Message') - { - return Get-Credential -Message "Enter credentials for Proxy Authentication" - } - else - { - Write-Host "Enter credentials for Proxy Authentication" - return Get-Credential - } -} - -function vcpkgGetSHA512([Parameter(Mandatory=$true)][string]$filePath) -{ - if (vcpkgHasCommand -commandName 'Microsoft.PowerShell.Utility\Get-FileHash') - { - Write-Verbose("Hashing with Microsoft.PowerShell.Utility\Get-FileHash") - $hashresult = Microsoft.PowerShell.Utility\Get-FileHash -Path $filePath -Algorithm SHA512 -ErrorVariable hashError - if ($hashError) - { - Start-Sleep 3 - $hashresult = Microsoft.PowerShell.Utility\Get-FileHash -Path $filePath -Algorithm SHA512 -ErrorVariable Stop - } - $hash = $hashresult.Hash - } - elseif(vcpkgHasCommand -commandName 'Pscx\Get-Hash') - { - Write-Verbose("Hashing with Pscx\Get-Hash") - $hash = (Pscx\Get-Hash -Path $filePath -Algorithm SHA512).HashString - } - else - { - Write-Verbose("Hashing with .NET") - $hashAlgorithm = [Security.Cryptography.HashAlgorithm]::Create("SHA512") - $fileAsByteArray = [io.File]::ReadAllBytes($filePath) - $hashByteArray = $hashAlgorithm.ComputeHash($fileAsByteArray) - $hash = -Join ($hashByteArray | ForEach-Object {"{0:x2}" -f $_}) - } - - return $hash.ToLower() -} - -function vcpkgCheckEqualFileHash( [Parameter(Mandatory=$true)][string]$url, - [Parameter(Mandatory=$true)][string]$filePath, - [Parameter(Mandatory=$true)][string]$expectedHash) -{ - $actualHash = vcpkgGetSHA512 $filePath - if ($expectedHash -ne $actualHash) - { - Write-Host ("`nFile does not have expected hash:`n" + - " url: [ $url ]`n" + - " File path: [ $filePath ]`n" + - " Expected hash: [ $expectedHash ]`n" + - " Actual hash: [ $actualHash ]`n") - throw - } -} - -function vcpkgDownloadFile( [Parameter(Mandatory=$true)][string]$url, - [Parameter(Mandatory=$true)][string]$downloadPath, - [Parameter(Mandatory=$true)][string]$sha512) -{ - if ($url -match "github") - { - if ([System.Enum]::IsDefined([Net.SecurityProtocolType], "Tls12")) - { - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - } - else - { - Write-Warning "Github has dropped support for TLS versions prior to 1.2, which is not available on your system" - Write-Warning "Please manually download $url to $downloadPath" - Write-Warning "To solve this issue for future downloads, you can also install Windows Management Framework 5.1+" - throw "Download failed" - } - } - - vcpkgCreateParentDirectoryIfNotExists $downloadPath - - $downloadPartPath = "$downloadPath.part" - vcpkgRemoveItem $downloadPartPath - - $wc = New-Object System.Net.WebClient - if (!$wc.Proxy.IsBypassed($url)) - { - $wc.Proxy.Credentials = vcpkgGetCredentials - } - - $wc.DownloadFile($url, $downloadPartPath) - vcpkgCheckEqualFileHash -url $url -filePath $downloadPartPath -expectedHash $sha512 - Move-Item -Path $downloadPartPath -Destination $downloadPath -} - -function vcpkgDownloadFileWithAria2( [Parameter(Mandatory=$true)][string]$aria2exe, - [Parameter(Mandatory=$true)][string]$url, - [Parameter(Mandatory=$true)][string]$downloadPath, - [Parameter(Mandatory=$true)][string]$sha512) -{ - vcpkgCreateParentDirectoryIfNotExists $downloadPath - $downloadPartPath = "$downloadPath.part" - vcpkgRemoveItem $downloadPartPath - - $parentDir = split-path -parent $downloadPath - $filename = split-path -leaf $downloadPath - - if ((Test-Path $url) -or ($url.StartsWith("file://"))) # if is local file - { - vcpkgDownloadFile $url $downloadPath $sha512 - return - } - - $ec = vcpkgInvokeCommand "$aria2exe" "--dir=`"$parentDir`" --out=`"$filename.part`" $url" - if ($ec -ne 0) - { - Write-Host "Could not download $url" - throw - } - - vcpkgCheckEqualFileHash -url $url -filePath $downloadPartPath -expectedHash $sha512 - Move-Item -Path $downloadPartPath -Destination $downloadPath -} - -function vcpkgExtractFileWith7z([Parameter(Mandatory=$true)][string]$sevenZipExe, - [Parameter(Mandatory=$true)][string]$archivePath, - [Parameter(Mandatory=$true)][string]$destinationDir) -{ - vcpkgRemoveItem $destinationDir - $destinationPartial = "$destinationDir.partial" - vcpkgRemoveItem $destinationPartial - vcpkgCreateDirectoryIfNotExists $destinationPartial - $ec = vcpkgInvokeCommand "$sevenZipExe" "x `"$archivePath`" -o`"$destinationPartial`" -y" - if ($ec -ne 0) - { - Write-Host "Could not extract $archivePath" - throw - } - Rename-Item -Path "$destinationPartial" -NewName $destinationDir -ErrorVariable renameResult - if ($renameResult) - { - Start-Sleep 3 - Rename-Item -Path "$destinationPartial" -NewName $destinationDir -ErrorAction Stop - } -} - -function vcpkgExtractZipFile( [Parameter(Mandatory=$true)][string]$archivePath, - [Parameter(Mandatory=$true)][string]$destinationDir) -{ - vcpkgRemoveItem $destinationDir - $destinationPartial = "$destinationDir.partial" - vcpkgRemoveItem $destinationPartial - vcpkgCreateDirectoryIfNotExists $destinationPartial - - - if (vcpkgHasCommand -commandName 'Microsoft.PowerShell.Archive\Expand-Archive') - { - Write-Verbose("Extracting with Microsoft.PowerShell.Archive\Expand-Archive") - Microsoft.PowerShell.Archive\Expand-Archive -path $archivePath -destinationpath $destinationPartial - } - elseif (vcpkgHasCommand -commandName 'Pscx\Expand-Archive') - { - Write-Verbose("Extracting with Pscx\Expand-Archive") - Pscx\Expand-Archive -path $archivePath -OutputPath $destinationPartial - } - else - { - Write-Verbose("Extracting via shell") - $shell = new-object -com shell.application - $zip = $shell.NameSpace($(Get-Item $archivePath).fullname) - foreach($item in $zip.items()) - { - # Piping to Out-Null is used to block until finished - $shell.Namespace($destinationPartial).copyhere($item) | Out-Null - } - } - - Rename-Item -Path "$destinationPartial" -NewName $destinationDir -} - -function vcpkgInvokeCommand() -{ - param ( [Parameter(Mandatory=$true)][string]$executable, - [string]$arguments = "") - - Write-Verbose "Executing: ${executable} ${arguments}" - $process = Start-Process -FilePath "`"$executable`"" -ArgumentList $arguments -PassThru -NoNewWindow - Wait-Process -InputObject $process - $ec = $process.ExitCode - Write-Verbose "Execution terminated with exit code $ec." - return $ec -} - -function vcpkgInvokeCommandClean() -{ - param ( [Parameter(Mandatory=$true)][string]$executable, - [string]$arguments = "") - - Write-Verbose "Clean-Executing: ${executable} ${arguments}" - $scriptsDir = split-path -parent $script:MyInvocation.MyCommand.Definition - $cleanEnvScript = "$scriptsDir\VcpkgPowershellUtils-ClearEnvironment.ps1" - $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 -} - -function vcpkgFormatElapsedTime([TimeSpan]$ts) -{ - if ($ts.TotalHours -ge 1) - { - return [string]::Format( "{0:N2} h", $ts.TotalHours); - } - - if ($ts.TotalMinutes -ge 1) - { - return [string]::Format( "{0:N2} min", $ts.TotalMinutes); - } - - if ($ts.TotalSeconds -ge 1) - { - return [string]::Format( "{0:N2} s", $ts.TotalSeconds); - } - - if ($ts.TotalMilliseconds -ge 1) - { - return [string]::Format( "{0:N2} ms", $ts.TotalMilliseconds); - } - - throw $ts -} - -function vcpkgFindFileRecursivelyUp() -{ - param( - [ValidateNotNullOrEmpty()] - [Parameter(Mandatory=$true)][string]$startingDir, - [ValidateNotNullOrEmpty()] - [Parameter(Mandatory=$true)][string]$filename - ) - - $currentDir = $startingDir - - while (!($currentDir -eq "") -and !(Test-Path "$currentDir\$filename")) - { - Write-Verbose "Examining $currentDir for $filename" - $currentDir = Split-path $currentDir -Parent - } - Write-Verbose "Examining $currentDir for $filename - Found" - return $currentDir -} + return $out +} \ No newline at end of file diff --git a/scripts/addPoshVcpkgToPowershellProfile.ps1 b/scripts/addPoshVcpkgToPowershellProfile.ps1 index dcbd2e0be4..5c13a8d4a5 100644 --- a/scripts/addPoshVcpkgToPowershellProfile.ps1 +++ b/scripts/addPoshVcpkgToPowershellProfile.ps1 @@ -18,10 +18,10 @@ $scriptsDir = split-path -parent $script:MyInvocation.MyCommand.Definition $profileEntry = "Import-Module '$scriptsDir\posh-vcpkg'" $profilePath = $PROFILE # Implicit powershell variable -if (!(Test-Path $profilePath)) +$profileDir = Split-Path $profilePath -Parent +if (!(Test-Path $profileDir)) { - $profileDir = Split-Path $profilePath -Parent - vcpkgCreateDirectoryIfNotExists $profileDir + New-Item -ItemType Directory -Path $profileDir | Out-Null } Write-Host "`nAdding the following line to ${profilePath}:" @@ -38,6 +38,7 @@ if ($existingImports.Count -gt 0) return } +# Modifying the profile will invalidate any signatures. # Posh-git does the following check, so we should too. # https://github.com/dahlbyk/posh-git/blob/master/src/Utils.ps1 # If the profile script exists and is signed, then we should not modify it diff --git a/scripts/bootstrap.ps1 b/scripts/bootstrap.ps1 index c8ba503d84..41ba257467 100644 --- a/scripts/bootstrap.ps1 +++ b/scripts/bootstrap.ps1 @@ -5,35 +5,18 @@ param( ) Set-StrictMode -Version Latest $scriptsDir = split-path -parent $script:MyInvocation.MyCommand.Definition -. "$scriptsDir\VcpkgPowershellUtils.ps1" -$vcpkgRootDir = vcpkgFindFileRecursivelyUp $scriptsDir .vcpkg-root -Write-Verbose("vcpkg Path " + $vcpkgRootDir) -$gitHash = "unknownhash" -$oldpath = $env:path -try +$vcpkgRootDir = $scriptsDir +$withVSPath = $withVSPath -replace "\\$" # Remove potential trailing backslash + +while (!($vcpkgRootDir -eq "") -and !(Test-Path "$vcpkgRootDir\.vcpkg-root")) { - [xml]$asXml = Get-Content "$scriptsDir\vcpkgTools.xml" - $toolData = $asXml.SelectSingleNode("//tools/tool[@name=`"git`"]") - $gitFromDownload = "$vcpkgRootDir\downloads\$($toolData.exeRelativePath)" - $gitDir = split-path -parent $gitFromDownload - - $env:path += ";$gitDir" - if (Get-Command "git" -ErrorAction SilentlyContinue) - { - $gitHash = git log HEAD -n 1 --format="%cd-%H" --date=short - if ($LASTEXITCODE -ne 0) - { - $gitHash = "unknownhash" - } - } + Write-Verbose "Examining $vcpkgRootDir for .vcpkg-root" + $vcpkgRootDir = Split-path $vcpkgRootDir -Parent } -finally -{ - $env:path = $oldpath -} -Write-Verbose("Git repo version string is " + $gitHash) +Write-Verbose "Examining $vcpkgRootDir for .vcpkg-root - Found" +$gitHash = "nohash" $vcpkgSourcesPath = "$vcpkgRootDir\toolsrc" if (!(Test-Path $vcpkgSourcesPath)) @@ -42,7 +25,58 @@ if (!(Test-Path $vcpkgSourcesPath)) return } -$msbuildExeWithPlatformToolset = & $scriptsDir\findAnyMSBuildWithCppPlatformToolset.ps1 $withVSPath +function findAnyMSBuildWithCppPlatformToolset([string]$withVSPath) +{ + $VisualStudioInstances = & $scriptsDir\getVisualStudioInstances.ps1 + if ($VisualStudioInstances -eq $null) + { + 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))" + foreach ($instanceCandidateWithEOL in $VisualStudioInstances) + { + $instanceCandidate = $instanceCandidateWithEOL -replace "::" -replace "::" + 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); + 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" + } + } + } + + throw "Could not find MSBuild version with C++ support. VS2015 or VS2017 (with C++) needs to be installed." +} + +$msbuildExeWithPlatformToolset = findAnyMSBuildWithCppPlatformToolset $withVSPath $msbuildExe = $msbuildExeWithPlatformToolset[0] $platformToolset = $msbuildExeWithPlatformToolset[1] $windowsSDK = & $scriptsDir\getWindowsSDK.ps1 @@ -54,10 +88,33 @@ $arguments = ( "/p:Platform=x86", "/p:PlatformToolset=$platformToolset", "/p:TargetPlatformVersion=$windowsSDK", +"/verbosity:minimal", "/m", +"/nologo", "`"$vcpkgSourcesPath\dirs.proj`"") -join " " +function vcpkgInvokeCommandClean() +{ + param ( [Parameter(Mandatory=$true)][string]$executable, + [string]$arguments = "") + + Write-Verbose "Clean-Executing: ${executable} ${arguments}" + $scriptsDir = split-path -parent $script:MyInvocation.MyCommand.Definition + $cleanEnvScript = "$scriptsDir\VcpkgPowershellUtils-ClearEnvironment.ps1" + $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 +} + # vcpkgInvokeCommandClean cmd "/c echo %PATH%" +Write-Host "`nBuilding vcpkg.exe ...`n" $ec = vcpkgInvokeCommandClean $msbuildExe $arguments if ($ec -ne 0) @@ -65,6 +122,7 @@ if ($ec -ne 0) 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 } +Write-Host "`nBuilding vcpkg.exe... done.`n" Write-Verbose("Placing vcpkg.exe in the correct location") diff --git a/scripts/fetchTool.ps1 b/scripts/fetchTool.ps1 deleted file mode 100644 index eca405b624..0000000000 --- a/scripts/fetchTool.ps1 +++ /dev/null @@ -1,109 +0,0 @@ -[CmdletBinding()] -param( - [Parameter(Mandatory=$true)][string]$tool -) - -Set-StrictMode -Version Latest - -$scriptsDir = split-path -parent $script:MyInvocation.MyCommand.Definition -. "$scriptsDir\VcpkgPowershellUtils.ps1" - -Write-Verbose "Fetching tool: $tool" -$vcpkgRootDir = vcpkgFindFileRecursivelyUp $scriptsDir .vcpkg-root - -$downloadsDir = "$vcpkgRootDir\downloads" -vcpkgCreateDirectoryIfNotExists $downloadsDir -$downloadsDir = Resolve-Path $downloadsDir - -function fetchToolInternal([Parameter(Mandatory=$true)][string]$tool) -{ - $tool = $tool.toLower() - - [xml]$asXml = Get-Content "$scriptsDir\vcpkgTools.xml" - $toolData = $asXml.SelectSingleNode("//tools/tool[@name=`"$tool`"]") # Case-sensitive! - - if ($toolData -eq $null) - { - throw "Unknown tool $tool" - } - - $toolPath="$downloadsDir\tools\$tool-$($toolData.version)-windows" - $exePath = "$toolPath\$($toolData.exeRelativePath)" - - if (Test-Path $exePath) - { - return $exePath - } - - $isArchive = vcpkgHasProperty -object $toolData -propertyName "archiveName" - if ($isArchive) - { - $downloadPath = "$downloadsDir\$($toolData.archiveName)" - } - else - { - $downloadPath = "$toolPath\$($toolData.exeRelativePath)" - } - - [String]$url = $toolData.url - if (!(Test-Path $downloadPath)) - { - Write-Host "Downloading $tool..." - - # Download aria2 with .NET. aria2 will be used to download everything else. - if ($tool -eq "aria2") - { - vcpkgDownloadFile $url $downloadPath $toolData.sha512 - } - else - { - $aria2exe = fetchToolInternal "aria2" - vcpkgDownloadFileWithAria2 $aria2exe $url $downloadPath $toolData.sha512 - } - - Write-Host "Downloading $tool... done." - } - else - { - vcpkgCheckEqualFileHash -url $url -filePath $downloadPath -expectedHash $toolData.sha512 - } - - if ($isArchive) - { - Write-Host "Extracting $tool..." - # Extract 7zip920 with shell because we need it to extract 7zip - # Extract aria2 with shell because we need it to download 7zip - if ($tool -eq "7zip920" -or $tool -eq "aria2") - { - vcpkgExtractZipFile -ArchivePath $downloadPath -DestinationDir $toolPath - } - elseif ($tool -eq "7zip") - { - $sevenZip920 = fetchToolInternal "7zip920" - $ec = vcpkgInvokeCommand "$sevenZip920" "x `"$downloadPath`" -o`"$toolPath`" -y" - if ($ec -ne 0) - { - Write-Host "Could not extract $downloadPath" - throw - } - } - else - { - $sevenZipExe = fetchToolInternal "7zip" - vcpkgExtractFileWith7z -sevenZipExe "$sevenZipExe" -ArchivePath $downloadPath -DestinationDir $toolPath - } - Write-Host "Extracting $tool... done." - } - - if (-not (Test-Path $exePath)) - { - Write-Error "Could not detect or download $tool" - throw - } - - return $exePath -} - -$path = fetchToolInternal $tool -Write-Verbose "Fetching tool: $tool. Done." -return "::$path::" diff --git a/scripts/findAnyMSBuildWithCppPlatformToolset.ps1 b/scripts/findAnyMSBuildWithCppPlatformToolset.ps1 deleted file mode 100644 index d7fd24e249..0000000000 --- a/scripts/findAnyMSBuildWithCppPlatformToolset.ps1 +++ /dev/null @@ -1,58 +0,0 @@ -[CmdletBinding()] -param( - [Parameter(Mandatory=$False)] - [string]$withVSPath = "" -) - -Set-StrictMode -Version Latest -$scriptsDir = split-path -parent $script:MyInvocation.MyCommand.Definition - -$withVSPath = $withVSPath -replace "\\$" # Remove potential trailing backslash - -$VisualStudioInstallationInstances = & $scriptsDir\findVisualStudioInstallationInstances.ps1 -if ($VisualStudioInstallationInstances -eq $null) -{ - 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, $VisualStudioInstallationInstances))" -foreach ($instanceCandidateWithEOL in $VisualStudioInstallationInstances) -{ - $instanceCandidate = $instanceCandidateWithEOL -replace "::" -replace "::" - 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); - 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 = & $scriptsDir\getProgramFiles32bit.ps1 - return "$programFilesPath\MSBuild\14.0\Bin\MSBuild.exe", "v140" - } - } -} - -throw "Could not find MSBuild version with C++ support. VS2015 or VS2017 (with C++) needs to be installed." \ No newline at end of file diff --git a/scripts/findVisualStudioInstallationInstances.ps1 b/scripts/findVisualStudioInstallationInstances.ps1 deleted file mode 100644 index cb51c345d4..0000000000 --- a/scripts/findVisualStudioInstallationInstances.ps1 +++ /dev/null @@ -1,61 +0,0 @@ -[CmdletBinding()] -param( - -) -Set-StrictMode -Version Latest -$scriptsDir = split-path -parent $script:MyInvocation.MyCommand.Definition -. "$scriptsDir\VcpkgPowershellUtils.ps1" - -$vswhereExe = (& $scriptsDir\fetchTool.ps1 "vswhere") -replace "::" -replace "::" - -$output = & $vswhereExe -prerelease -legacy -products * -format xml -[xml]$asXml = $output - -$results = New-Object System.Collections.ArrayList -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 - $results.Add("::${releaseType}::${installationVersion}::${installationPath}::") > $null -} - -# If nothing is found, attempt to find VS2015 Build Tools (not detected by vswhere.exe) -if ($results.Count -eq 0) -{ - $programFiles = & $scriptsDir\getProgramFiles32bit.ps1 - $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)) - { - return "::PreferenceWeight1::Legacy::14.0::$installationPath::" - } -} - - -$results.Sort() -$results.Reverse() - -return $results \ No newline at end of file diff --git a/scripts/getProgramFiles32bit.ps1 b/scripts/getProgramFiles32bit.ps1 deleted file mode 100644 index 6b71915b19..0000000000 --- a/scripts/getProgramFiles32bit.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -[CmdletBinding()] -param( - -) - -$out = ${env:PROGRAMFILES(X86)} -if ($out -eq $null) -{ - $out = ${env:PROGRAMFILES} -} - -if ($out -eq $null) -{ - throw "Could not find [Program Files 32-bit]" -} - -return $out \ No newline at end of file diff --git a/scripts/getProgramFilesPlatformBitness.ps1 b/scripts/getProgramFilesPlatformBitness.ps1 deleted file mode 100644 index 2be4c11371..0000000000 --- a/scripts/getProgramFilesPlatformBitness.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -[CmdletBinding()] -param( - -) - -$out = ${env:ProgramW6432} -if ($out -eq $null) -{ - $out = ${env:PROGRAMFILES} -} - -if ($out -eq $null) -{ - throw "Could not find [Program Files Platform Bitness]" -} - -return $out \ No newline at end of file diff --git a/scripts/getVisualStudioInstances.ps1 b/scripts/getVisualStudioInstances.ps1 new file mode 100644 index 0000000000..83b0b8ebdd --- /dev/null +++ b/scripts/getVisualStudioInstances.ps1 @@ -0,0 +1,74 @@ +[CmdletBinding()] +param( + +) +Set-StrictMode -Version Latest +$scriptsDir = split-path -parent $script:MyInvocation.MyCommand.Definition +. "$scriptsDir\VcpkgPowershellUtils.ps1" + +$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 + $results.Add("::${releaseType}::${installationVersion}::${installationPath}::") > $null + } +} +else +{ + Write-Verbose "Could not locate vswhere at $vswhereExe" +} + +$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)) +{ + $results.Add("::PreferenceWeight1::Legacy::14.0::$installationPath::") > $null +} + +$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)) +{ + $results.Add("::PreferenceWeight1::Legacy::14.0::$installationPath::") > $null +} + +$results.Sort() +$results.Reverse() + +return $results diff --git a/scripts/vcpkgTools.xml b/scripts/vcpkgTools.xml index 1f17102d2b..9d5487577a 100644 --- a/scripts/vcpkgTools.xml +++ b/scripts/vcpkgTools.xml @@ -61,17 +61,10 @@ 18.01.0 - 7za.exe - https://www.7-zip.org/a/7z1801-extra.7z - 9133fc551d76515e37fdd4dd8c1e28d464aea493548246b44565a42bba46715764f41f9cfa14d470d298c3a6e9829d200f8be5168cb67cf8f23d8042fca833bc - 7z1801-extra.7z - - - 9.20.0 - 7za.exe - https://www.7-zip.org/a/7za920.zip - 84e830c91a0e8ae499cc4814080da6569d8a6acbddc585c8b62abc86c809793aeb669b0a741063a379fd281ade85f120bc27efeb67d63bf961be893eec8bc3b3 - 7za920.zip + 7-Zip.CommandLine.18.1.0\tools\7za.exe + https://www.nuget.org/api/v2/package/7-Zip.CommandLine/18.1.0 + 8c75314102e68d2b2347d592f8e3eb05812e1ebb525decbac472231633753f1d4ca31c8e6881a36144a8da26b2571305b3ae3f4e2b85fc4a290aeda63d1a13b8 + 7-zip.commandline.18.1.0.nupkg 18.01.0 diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index 0d089276fe..cf9c788682 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -47,6 +47,7 @@ namespace vcpkg::System ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line); +#if defined(_WIN32) void powershell_execute(const std::string& title, const fs::path& script_path, const std::vector& parameters = {}); @@ -54,6 +55,7 @@ namespace vcpkg::System std::string powershell_execute_and_capture_output(const std::string& title, const fs::path& script_path, const std::vector& parameters = {}); +#endif enum class Color { diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index 6d29b79600..708151dced 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -132,14 +132,14 @@ namespace vcpkg::Commands namespace Hash { std::string get_string_hash(const std::string& s, const std::string& hash_type); - std::string get_file_hash(const VcpkgPaths& paths, const fs::path& path, const std::string& hash_type); + std::string get_file_hash(const Files::Filesystem& fs, const fs::path& path, const std::string& hash_type); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } namespace Fetch { - std::vector find_toolset_instances(const VcpkgPaths& paths); + std::vector find_toolset_instances_prefered_first(const VcpkgPaths& paths); fs::path get_tool_path(const VcpkgPaths& paths, const std::string& tool); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index 9c8f2911a1..a3c90fd330 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -66,6 +66,7 @@ namespace vcpkg fs::path triplets; fs::path scripts; + fs::path tools; fs::path buildsystems; fs::path buildsystems_msbuild_targets; diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp index d96cb98ffb..2ac5f9a152 100644 --- a/toolsrc/src/vcpkg/base/checks.cpp +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -16,6 +16,8 @@ namespace vcpkg::Checks const auto elapsed_us = GlobalState::timer.lock()->microseconds(); + Debug::println("Exiting after %d us", static_cast(elapsed_us)); + auto metrics = Metrics::g_metrics.lock(); metrics->track_metric("elapsed_us", elapsed_us); GlobalState::debugging = false; diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 95c9511f9e..4da4548af2 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -155,6 +155,7 @@ namespace vcpkg::System int cmd_execute_clean(const CStringView cmd_line, const std::unordered_map& extra_env) { + auto timer = Chrono::ElapsedTimer::create_started(); #if defined(_WIN32) static const std::string SYSTEM_ROOT = get_environment_variable("SystemRoot").value_or_exit(VCPKG_LINE_INFO); static const std::string SYSTEM_32 = SYSTEM_ROOT + R"(\system32)"; @@ -271,7 +272,7 @@ namespace vcpkg::System DWORD exit_code = 0; GetExitCodeProcess(process_info.hProcess, &exit_code); - Debug::println("CreateProcessW() returned %lu", exit_code); + Debug::println("CreateProcessW() returned %lu after %d us", exit_code, static_cast(timer.microseconds())); return static_cast(exit_code); #else Debug::println("system(%s)", cmd_line.c_str()); @@ -369,13 +370,20 @@ namespace vcpkg::System #endif } +#if defined(_WIN32) void powershell_execute(const std::string& title, const fs::path& script_path, const std::vector& parameters) { + SetConsoleCP(437); + SetConsoleOutputCP(437); + const std::string cmd = make_powershell_cmd(script_path, parameters); const int rc = System::cmd_execute(cmd); + SetConsoleCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8); + if (rc) { System::println(Color::error, @@ -394,14 +402,22 @@ namespace vcpkg::System Checks::exit_with_code(VCPKG_LINE_INFO, rc); } } +#endif +#if defined(_WIN32) std::string powershell_execute_and_capture_output(const std::string& title, const fs::path& script_path, const std::vector& parameters) { + SetConsoleCP(437); + SetConsoleOutputCP(437); + const std::string cmd = make_powershell_cmd(script_path, parameters); auto rc = System::cmd_execute_and_capture_output(cmd); + SetConsoleCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8); + if (rc.exit_code) { System::println(Color::error, @@ -433,6 +449,7 @@ namespace vcpkg::System return rc.output; } +#endif void println() { putchar('\n'); } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 1ed5e744ae..b8ccb15bf9 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -461,9 +461,9 @@ namespace vcpkg::Build abi_tag_entries.insert(abi_tag_entries.end(), dependency_abis.begin(), dependency_abis.end()); abi_tag_entries.emplace_back( - AbiEntry{"portfile", Commands::Hash::get_file_hash(paths, config.port_dir / "portfile.cmake", "SHA1")}); + AbiEntry{"portfile", Commands::Hash::get_file_hash(fs, config.port_dir / "portfile.cmake", "SHA1")}); abi_tag_entries.emplace_back( - AbiEntry{"control", Commands::Hash::get_file_hash(paths, config.port_dir / "CONTROL", "SHA1")}); + AbiEntry{"control", Commands::Hash::get_file_hash(fs, config.port_dir / "CONTROL", "SHA1")}); abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); @@ -498,7 +498,7 @@ namespace vcpkg::Build const auto abi_file_path = paths.buildtrees / name / (triplet.canonical_name() + ".vcpkg_abi_info.txt"); fs.write_contents(abi_file_path, full_abi_info); - return AbiTagAndFile{Commands::Hash::get_file_hash(paths, abi_file_path, "SHA1"), abi_file_path}; + return AbiTagAndFile{Commands::Hash::get_file_hash(fs, abi_file_path, "SHA1"), abi_file_path}; } System::println( @@ -783,14 +783,12 @@ namespace vcpkg::Build { return it_hash->second; } - auto hash = Commands::Hash::get_file_hash(paths, triplet_file_path, "SHA1"); + auto hash = Commands::Hash::get_file_hash(paths.get_filesystem(), triplet_file_path, "SHA1"); s_hash_cache.emplace(triplet_file_path, hash); return hash; } - else - { - return std::string(); - } + + return std::string(); }(); const auto cmd_launch_cmake = System::make_cmake_cmd(cmake_exe_path, diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index 8b6ffb3d79..09da57705c 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -43,7 +43,7 @@ namespace vcpkg::Commands {"portsdiff", &PortsDiff::perform_and_exit}, {"autocomplete", &Autocomplete::perform_and_exit}, {"hash", &Hash::perform_and_exit}, - // {"fetch", &Fetch::perform_and_exit}, + {"fetch", &Fetch::perform_and_exit}, }; return t; } diff --git a/toolsrc/src/vcpkg/commands.fetch.cpp b/toolsrc/src/vcpkg/commands.fetch.cpp index a6cfec3f0d..d50d13c59a 100644 --- a/toolsrc/src/vcpkg/commands.fetch.cpp +++ b/toolsrc/src/vcpkg/commands.fetch.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include +#include #include #include #include @@ -19,6 +20,7 @@ namespace vcpkg::Commands::Fetch fs::path exe_path; std::string url; fs::path download_path; + bool is_archive; fs::path tool_dir_path; std::string sha512; }; @@ -41,20 +43,85 @@ namespace vcpkg::Commands::Fetch return result; } - static Optional extract_string_between_delimiters(const std::string& input, - const std::string& left_delim, - const std::string& right_delim, - const size_t& starting_offset = 0) + struct VcpkgStringRange { - const size_t from = input.find(left_delim, starting_offset); - if (from == std::string::npos) return nullopt; + VcpkgStringRange() = default; - const size_t substring_start = from + left_delim.length(); + // Implicit by design + VcpkgStringRange(const std::string& s) : begin(s.cbegin()), end(s.cend()) {} - const size_t to = input.find(right_delim, substring_start); - if (from == std::string::npos) return nullopt; + VcpkgStringRange(const std::string::const_iterator begin, const std::string::const_iterator end) + : begin(begin), end(end) + { + } - return input.substr(substring_start, to - substring_start); + std::string::const_iterator begin; + std::string::const_iterator end; + + std::string to_string() const { return std::string(this->begin, this->end); } + }; + + static std::vector find_all_enclosed(const VcpkgStringRange& input, + const std::string& left_delim, + const std::string& right_delim) + { + std::string::const_iterator it_left = input.begin; + std::string::const_iterator it_right = input.begin; + + std::vector output; + + while (true) + { + it_left = std::search(it_right, input.end, left_delim.cbegin(), left_delim.cend()); + if (it_left == input.end) break; + + it_left += left_delim.length(); + + it_right = std::search(it_left, input.end, right_delim.cbegin(), right_delim.cend()); + if (it_right == input.end) break; + + output.emplace_back(it_left, it_right); + + ++it_right; + } + + return output; + } + + static VcpkgStringRange find_exactly_one_enclosed(const VcpkgStringRange& input, + const std::string& left_tag, + const std::string& right_tag) + { + std::vector result = find_all_enclosed(input, left_tag, right_tag); + Checks::check_exit(VCPKG_LINE_INFO, + result.size() == 1, + "Found %d sets of %s.*%s but expected exactly 1, in block:\n%s", + result.size(), + left_tag, + right_tag, + input); + return std::move(result.front()); + } + + static Optional find_at_most_one_enclosed(const VcpkgStringRange& input, + const std::string& left_tag, + const std::string& right_tag) + { + std::vector result = find_all_enclosed(input, left_tag, right_tag); + Checks::check_exit(VCPKG_LINE_INFO, + result.size() <= 1, + "Found %d sets of %s.*%s but expected at most 1, in block:\n%s", + result.size(), + left_tag, + right_tag, + input); + + if (result.empty()) + { + return nullopt; + } + + return result.front(); } static ToolData parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool) @@ -72,21 +139,6 @@ namespace vcpkg::Commands::Fetch #if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) static const std::string XML_VERSION = "2"; static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; - - const auto get_string_inside_tags = - [](const std::string& input, const std::string& left_delim, const std::string& right_delim) -> std::string { - Optional result = extract_string_between_delimiters(input, left_delim, right_delim); - Checks::check_exit(VCPKG_LINE_INFO, - result.has_value(), - "Could not find tag <%s>.*<%s> in %s", - left_delim, - right_delim, - XML_PATH.generic_string()); - - auto r = *result.get(); - return Strings::trim(std::move(r)); - }; - static const std::regex XML_VERSION_REGEX{R"###()###"}; static const std::string XML = paths.get_filesystem().read_contents(XML_PATH).value_or_exit(VCPKG_LINE_INFO); std::smatch match_xml_version; @@ -112,14 +164,14 @@ namespace vcpkg::Commands::Fetch tool, XML_PATH.generic_string()); - const std::string tool_data = get_string_inside_tags(XML, match_tool_entry[0], R"()"); - - const std::string version_as_string = get_string_inside_tags(tool_data, "", R"()"); + const std::string tool_data = find_exactly_one_enclosed(XML, match_tool_entry[0], "").to_string(); + const std::string version_as_string = + find_exactly_one_enclosed(tool_data, "", "").to_string(); const std::string exe_relative_path = - get_string_inside_tags(tool_data, "", R"()"); - const std::string url = get_string_inside_tags(tool_data, "", R"()"); - const std::string sha512 = get_string_inside_tags(tool_data, "", R"()"); - auto archive_name = extract_string_between_delimiters(tool_data, "", R"()"); + find_exactly_one_enclosed(tool_data, "", "").to_string(); + const std::string url = find_exactly_one_enclosed(tool_data, "", "").to_string(); + const std::string sha512 = find_exactly_one_enclosed(tool_data, "", "").to_string(); + auto archive_name = find_at_most_one_enclosed(tool_data, "", ""); const Optional> version = parse_version_string(version_as_string); Checks::check_exit(VCPKG_LINE_INFO, @@ -129,13 +181,14 @@ namespace vcpkg::Commands::Fetch version_as_string); const std::string tool_dir_name = Strings::format("%s-%s-%s", tool, version_as_string, OS_STRING); - const fs::path tool_dir_path = paths.downloads / "tools" / tool_dir_name; + const fs::path tool_dir_path = paths.tools / tool_dir_name; const fs::path exe_path = tool_dir_path / exe_relative_path; return ToolData{*version.get(), exe_path, url, - paths.downloads / archive_name.value_or(exe_relative_path), + paths.downloads / archive_name.value_or(exe_relative_path).to_string(), + archive_name.has_value(), tool_dir_path, sha512}; #endif @@ -163,51 +216,87 @@ namespace vcpkg::Commands::Fetch actual_version[2] >= expected_version[2])); } - static Optional find_if_has_equal_or_greater_version(const std::vector& candidate_paths, + static Optional find_if_has_equal_or_greater_version(Files::Filesystem& fs, + const std::vector& candidate_paths, const std::string& version_check_arguments, const std::array& expected_version) { - auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { + const auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { + if (!fs.exists(p)) return false; const std::string cmd = Strings::format(R"("%s" %s)", p.u8string(), version_check_arguments); return exists_and_has_equal_or_greater_version(cmd, expected_version); }); if (it != candidate_paths.cend()) { - return std::move(*it); + return *it; } return nullopt; } - static std::vector keep_data_lines(const std::string& data_blob) - { - static const std::regex DATA_LINE_REGEX(R"(::(.+?)(?=::))"); - - std::vector data_lines; - - const std::sregex_iterator it(data_blob.cbegin(), data_blob.cend(), DATA_LINE_REGEX); - const std::sregex_iterator end; - for (std::sregex_iterator i = it; i != end; ++i) - { - const std::smatch match = *i; - data_lines.push_back(match[1].str()); - } - - return data_lines; - } - -#if !defined(_WIN32) static void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path) { Files::Filesystem& fs = paths.get_filesystem(); const fs::path to_path_partial = to_path.u8string() + ".partial"; std::error_code ec; + fs.remove_all(to_path, ec); fs.remove_all(to_path_partial, ec); fs.create_directories(to_path_partial, ec); - const auto ext = archive.extension(); +#if defined(_WIN32) + if (ext == ".nupkg") + { + static bool recursion_limiter_sevenzip_old = false; + Checks::check_exit(VCPKG_LINE_INFO, !recursion_limiter_sevenzip_old); + recursion_limiter_sevenzip_old = true; + const auto nuget_exe = get_tool_path(paths, Tools::NUGET); + + const std::string stem = archive.stem().u8string(); + // assuming format of [name].[version in the form d.d.d] + // This assumption may not always hold + std::smatch match; + const bool has_match = std::regex_match(stem, match, std::regex{R"###(^(.+)\.(\d+\.\d+\.\d+)$)###"}); + Checks::check_exit(VCPKG_LINE_INFO, + has_match, + "Could not deduce nuget id and version from filename: %s", + archive.u8string()); + + const std::string nugetid = match[1]; + const std::string version = match[2]; + + const auto code_and_output = System::cmd_execute_and_capture_output(Strings::format( + R"("%s" install %s -Version %s -OutputDirectory "%s" -Source "%s" -nocache -DirectDownload -NonInteractive -ForceEnglishOutput -PackageSaveMode nuspec)", + nuget_exe.u8string(), + nugetid, + version, + to_path_partial.u8string(), + paths.downloads.u8string())); + + Checks::check_exit(VCPKG_LINE_INFO, + code_and_output.exit_code == 0, + "Failed to extract '%s' with message:\n%s", + archive.u8string(), + code_and_output.output); + recursion_limiter_sevenzip_old = false; + } + else + { + static bool recursion_limiter_sevenzip = false; + Checks::check_exit(VCPKG_LINE_INFO, !recursion_limiter_sevenzip); + recursion_limiter_sevenzip = true; + const auto seven_zip = get_tool_path(paths, Tools::SEVEN_ZIP); + const auto code_and_output = System::cmd_execute_and_capture_output(Strings::format( + R"("%s" x "%s" -o"%s" -y)", seven_zip.u8string(), archive.u8string(), to_path_partial.u8string())); + Checks::check_exit(VCPKG_LINE_INFO, + code_and_output.exit_code == 0, + "7zip failed while extracting '%s' with message:\n%s", + archive.u8string(), + code_and_output.output); + recursion_limiter_sevenzip = false; + } +#else if (ext == ".gz" && ext.extension() != ".tar") { const auto code = System::cmd_execute( @@ -224,16 +313,23 @@ namespace vcpkg::Commands::Fetch { Checks::exit_with_message(VCPKG_LINE_INFO, "Unexpected archive extension: %s", ext.u8string()); } +#endif - fs.rename(to_path_partial, to_path); + fs.rename(to_path_partial, to_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Failed to do post-extract rename-in-place.\nfs.rename(%s, %s, %s)", + to_path_partial.u8string(), + to_path.u8string(), + ec.message()); } - static void verify_hash(const VcpkgPaths& paths, + static void verify_hash(const Files::Filesystem& fs, const std::string& url, const fs::path& path, const std::string& sha512) { - const std::string actual_hash = Hash::get_file_hash(paths, path, "SHA512"); + const std::string actual_hash = Hash::get_file_hash(fs, path, "SHA512"); Checks::check_exit(VCPKG_LINE_INFO, sha512 == actual_hash, "File does not have the expected hash:\n" @@ -247,24 +343,119 @@ namespace vcpkg::Commands::Fetch actual_hash); } - static void download_file(const VcpkgPaths& paths, +#if defined(_WIN32) + static void winhttp_download_file(Files::Filesystem& fs, + CStringView target_file_path, + CStringView hostname, + CStringView url_path) + { + // Make sure the directories are present, otherwise fopen_s fails + const auto dir = fs::path(target_file_path.c_str()).parent_path(); + std::error_code ec; + fs.create_directories(dir, ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directories %s", dir.u8string()); + + FILE* f = nullptr; + const errno_t err = fopen_s(&f, target_file_path.c_str(), "wb"); + Checks::check_exit(VCPKG_LINE_INFO, + !err, + "Could not download https://%s%s. Failed to open file %s. Error code was %s", + hostname, + url_path, + target_file_path, + std::to_string(err)); + + auto hSession = WinHttpOpen( + L"vcpkg/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); + Checks::check_exit(VCPKG_LINE_INFO, hSession, "WinHttpOpen() failed: %d", GetLastError()); + + // Use Windows 10 defaults on Windows 7 + DWORD secure_protocols(WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 | + WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2); + WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, &secure_protocols, sizeof(secure_protocols)); + + // Specify an HTTP server. + auto hConnect = WinHttpConnect(hSession, Strings::to_utf16(hostname).c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0); + Checks::check_exit(VCPKG_LINE_INFO, hConnect, "WinHttpConnect() failed: %d", GetLastError()); + + // Create an HTTP request handle. + auto hRequest = WinHttpOpenRequest(hConnect, + L"GET", + Strings::to_utf16(url_path).c_str(), + nullptr, + WINHTTP_NO_REFERER, + WINHTTP_DEFAULT_ACCEPT_TYPES, + WINHTTP_FLAG_SECURE); + Checks::check_exit(VCPKG_LINE_INFO, hRequest, "WinHttpOpenRequest() failed: %d", GetLastError()); + + // Send a request. + auto bResults = + WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); + Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpSendRequest() failed: %d", GetLastError()); + + // End the request. + bResults = WinHttpReceiveResponse(hRequest, NULL); + Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpReceiveResponse() failed: %d", GetLastError()); + + std::vector buf; + + size_t total_downloaded_size = 0; + DWORD dwSize = 0; + do + { + DWORD downloaded_size = 0; + bResults = WinHttpQueryDataAvailable(hRequest, &dwSize); + Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpQueryDataAvailable() failed: %d", GetLastError()); + + if (buf.size() < dwSize) buf.resize(dwSize * 2); + + bResults = WinHttpReadData(hRequest, (LPVOID)buf.data(), dwSize, &downloaded_size); + Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpReadData() failed: %d", GetLastError()); + fwrite(buf.data(), 1, downloaded_size, f); + + total_downloaded_size += downloaded_size; + } while (dwSize > 0); + + WinHttpCloseHandle(hSession); + WinHttpCloseHandle(hConnect); + WinHttpCloseHandle(hRequest); + fflush(f); + fclose(f); + } +#endif + + static void download_file(Files::Filesystem& fs, const std::string& url, const fs::path& download_path, const std::string& sha512) { - Files::Filesystem& fs = paths.get_filesystem(); const std::string download_path_part = download_path.u8string() + ".part"; std::error_code ec; + fs.remove(download_path, ec); fs.remove(download_path_part, ec); +#if defined(_WIN32) + auto url_no_proto = url.substr(8); // drop https:// + auto path_begin = Util::find(url_no_proto, '/'); + std::string hostname(url_no_proto.begin(), path_begin); + std::string path(path_begin, url_no_proto.end()); + + winhttp_download_file(fs, download_path_part.c_str(), hostname, path); +#else const auto code = System::cmd_execute( Strings::format(R"(curl -L '%s' --create-dirs --output '%s')", url, download_path_part)); Checks::check_exit(VCPKG_LINE_INFO, code == 0, "Could not download %s", url); +#endif - verify_hash(paths, url, download_path_part, sha512); - fs.rename(download_path_part, download_path); + verify_hash(fs, url, download_path_part, sha512); + fs.rename(download_path_part, download_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Failed to do post-download rename-in-place.\nfs.rename(%s, %s, %s)", + download_path_part, + download_path.u8string(), + ec.message()); } -#endif static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) { const std::array& version = tool_data.version; @@ -280,50 +471,37 @@ namespace vcpkg::Commands::Fetch version_as_string, tool_name, version_as_string); -#if defined(_WIN32) - const fs::path script = paths.scripts / "fetchtool.ps1"; - const std::string title = Strings::format( - "Fetching %s version %s (No sufficient installed version was found)", tool_name, version_as_string); - const System::PowershellParameter tool_param("tool", tool_name); - const std::string output = System::powershell_execute_and_capture_output(title, script, {tool_param}); - - const std::vector tool_path = keep_data_lines(output); - Checks::check_exit(VCPKG_LINE_INFO, tool_path.size() == 1, "Expected tool path, but got %s", output); - - const fs::path actual_downloaded_path = Strings::trim(std::string{tool_path.at(0)}); - const fs::path& expected_downloaded_path = tool_data.exe_path; - std::error_code ec; - const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - eq && !ec, - "Expected tool downloaded path to be %s, but was %s", - expected_downloaded_path.u8string(), - actual_downloaded_path.u8string()); - return actual_downloaded_path; -#else - const auto& fs = paths.get_filesystem(); + auto& fs = paths.get_filesystem(); if (!fs.exists(tool_data.download_path)) { System::println("Downloading %s...", tool_name); - download_file(paths, tool_data.url, tool_data.download_path, tool_data.sha512); + download_file(fs, tool_data.url, tool_data.download_path, tool_data.sha512); System::println("Downloading %s... done.", tool_name); } else { - verify_hash(paths, tool_data.url, tool_data.download_path, tool_data.sha512); + verify_hash(fs, tool_data.url, tool_data.download_path, tool_data.sha512); } - System::println("Extracting %s...", tool_name); - extract_archive(paths, tool_data.download_path, tool_data.tool_dir_path); - System::println("Extracting %s... done.", tool_name); + if (tool_data.is_archive) + { + System::println("Extracting %s...", tool_name); + extract_archive(paths, tool_data.download_path, tool_data.tool_dir_path); + System::println("Extracting %s... done.", tool_name); + } + else + { + std::error_code ec; + fs.create_directories(tool_data.exe_path.parent_path(), ec); + fs.rename(tool_data.download_path, tool_data.exe_path, ec); + } Checks::check_exit(VCPKG_LINE_INFO, fs.exists(tool_data.exe_path), - "Expected %s to exist after extracting", - tool_data.exe_path); + "Expected %s to exist after fetching", + tool_data.exe_path.u8string()); return tool_data.exe_path; -#endif } static fs::path get_cmake_path(const VcpkgPaths& paths) @@ -345,8 +523,8 @@ namespace vcpkg::Commands::Fetch const auto& program_files_32_bit = System::get_program_files_32_bit(); if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); + const Optional path = find_if_has_equal_or_greater_version( + paths.get_filesystem(), candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -378,7 +556,8 @@ namespace vcpkg::Commands::Fetch const std::vector from_path = Files::find_from_PATH("ninja"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - auto path = find_if_has_equal_or_greater_version(candidate_paths, "--version", TOOL_DATA.version); + auto path = find_if_has_equal_or_greater_version( + paths.get_filesystem(), candidate_paths, "--version", TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -396,7 +575,8 @@ namespace vcpkg::Commands::Fetch const std::vector from_path = Files::find_from_PATH("nuget"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - auto path = find_if_has_equal_or_greater_version(candidate_paths, "", TOOL_DATA.version); + auto path = + find_if_has_equal_or_greater_version(paths.get_filesystem(), candidate_paths, "", TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -422,8 +602,8 @@ namespace vcpkg::Commands::Fetch const auto& program_files_32_bit = System::get_program_files_32_bit(); if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); + const Optional path = find_if_has_equal_or_greater_version( + paths.get_filesystem(), candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -448,8 +628,8 @@ namespace vcpkg::Commands::Fetch // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" / // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); + const Optional path = find_if_has_equal_or_greater_version( + paths.get_filesystem(), candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.version); if (const auto p = path.get()) { return *p; @@ -460,48 +640,114 @@ namespace vcpkg::Commands::Fetch struct VisualStudioInstance { + enum class ReleaseType + { + STABLE, + PRERELEASE, + LEGACY + }; + + static bool prefered_first_comparator(const VisualStudioInstance& left, const VisualStudioInstance& right) + { + const auto get_preference_weight = [](const ReleaseType& type) -> int { + switch (type) + { + case ReleaseType::STABLE: return 3; + case ReleaseType::PRERELEASE: return 2; + case ReleaseType::LEGACY: return 1; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + }; + + if (left.release_type != right.release_type) + { + return get_preference_weight(left.release_type) > get_preference_weight(right.release_type); + } + + return left.version > right.version; + } + + VisualStudioInstance(fs::path&& root_path, std::string&& version, const ReleaseType& release_type) + : root_path(std::move(root_path)), version(std::move(version)), release_type(release_type) + { + } + fs::path root_path; std::string version; - std::string release_type; - std::string preference_weight; // Mostly unused, just for verification that order is as intended + ReleaseType release_type; std::string major_version() const { return version.substr(0, 2); } }; static std::vector get_visual_studio_instances(const VcpkgPaths& paths) { - const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; - const std::string output = - System::powershell_execute_and_capture_output("Detecting Visual Studio instances", script); + const auto& fs = paths.get_filesystem(); + + const auto& program_files_32_bit = System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO); + const fs::path vswhere_exe = program_files_32_bit / "Microsoft Visual Studio" / "Installer" / "vswhere.exe"; + Checks::check_exit( + VCPKG_LINE_INFO, fs.exists(vswhere_exe), "Could not locate vswhere at %s", vswhere_exe.u8string()); + + const auto code_and_output = System::cmd_execute_and_capture_output( + Strings::format(R"("%s" -prerelease -legacy -products * -format xml)", vswhere_exe.u8string())); - const std::vector instances_as_strings = keep_data_lines(output); Checks::check_exit(VCPKG_LINE_INFO, - !instances_as_strings.empty(), - "Could not detect any Visual Studio instances.\n" - "Powershell script:\n" - " %s\n" - "returned:\n" - "%s", - script.generic_string(), - output); + code_and_output.exit_code == 0, + "Running vswhere.exe failed with message:\n%s", + code_and_output.output); + + const auto& xml_as_string = code_and_output.output; + + const auto instance_entries = find_all_enclosed(xml_as_string, "", ""); std::vector instances; - for (const std::string& instance_as_string : instances_as_strings) + for (const VcpkgStringRange& instance : instance_entries) { - const std::vector split = Strings::split(instance_as_string, "::"); - Checks::check_exit(VCPKG_LINE_INFO, - split.size() == 4, - "Invalid Visual Studio instance format.\n" - "Expected: PreferenceWeight::ReleaseType::Version::PathToVisualStudio\n" - "Actual : %s\n", - instance_as_string); - instances.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); + auto maybe_is_prerelease = find_at_most_one_enclosed(instance, "", ""); + + VisualStudioInstance::ReleaseType release_type = VisualStudioInstance::ReleaseType::LEGACY; + if (auto p = maybe_is_prerelease.get()) + { + auto s = p->to_string(); + if (s == "0") + release_type = VisualStudioInstance::ReleaseType::STABLE; + else if (s == "1") + release_type = VisualStudioInstance::ReleaseType::PRERELEASE; + else + Checks::unreachable(VCPKG_LINE_INFO); + } + + instances.emplace_back( + find_exactly_one_enclosed(instance, "", "").to_string(), + find_exactly_one_enclosed(instance, "", "").to_string(), + release_type); } + const auto append_if_has_cl = [&](fs::path&& path_root) { + const auto cl_exe = path_root / "VC" / "bin" / "cl.exe"; + const auto vcvarsall_bat = path_root / "VC" / "vcvarsall.bat"; + + if (fs.exists(cl_exe) && fs.exists(vcvarsall_bat)) + instances.emplace_back(std::move(path_root), "14.0", VisualStudioInstance::ReleaseType::LEGACY); + }; + + auto maybe_vs140comntools = System::get_environment_variable("vs140comntools"); + if (const auto path_as_string = maybe_vs140comntools.get()) + { + // We want lexically_normal(), but it is not available + // Correct root path might be 2 or 3 levels up, depending on if the path has trailing backslash. Try both. + auto common7_tools = fs::path{*path_as_string}; + append_if_has_cl(fs::path{*path_as_string}.parent_path().parent_path()); + append_if_has_cl(fs::path{*path_as_string}.parent_path().parent_path().parent_path()); + } + + append_if_has_cl(program_files_32_bit / "Microsoft Visual Studio 14.0"); + return instances; } - std::vector find_toolset_instances(const VcpkgPaths& paths) +#if defined(_WIN32) + std::vector find_toolset_instances_prefered_first(const VcpkgPaths& paths) { using CPU = System::CPUArchitecture; @@ -513,12 +759,14 @@ namespace vcpkg::Commands::Fetch std::vector found_toolsets; std::vector excluded_toolsets; - const std::vector vs_instances = get_visual_studio_instances(paths); - const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) { - return vs_instance.major_version() == "14"; - }) != vs_instances.cend(); + const SortedVector sorted{get_visual_studio_instances(paths), + VisualStudioInstance::prefered_first_comparator}; - for (const VisualStudioInstance& vs_instance : vs_instances) + const bool v140_is_available = Util::find_if(sorted, [&](const VisualStudioInstance& vs_instance) { + return vs_instance.major_version() == "14"; + }) != sorted.end(); + + for (const VisualStudioInstance& vs_instance : sorted) { const std::string major_version = vs_instance.major_version(); if (major_version == "15") @@ -672,6 +920,7 @@ namespace vcpkg::Commands::Fetch return found_toolsets; } +#endif fs::path get_tool_path(const VcpkgPaths& paths, const std::string& tool) { diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index 1f709f87bd..d7d653ca3a 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -154,10 +154,9 @@ namespace vcpkg::Commands::Hash }; } - std::string get_file_hash(const VcpkgPaths& paths, const fs::path& path, const std::string& hash_type) + std::string get_file_hash(const Files::Filesystem& fs, const fs::path& path, const std::string& hash_type) { - Checks::check_exit( - VCPKG_LINE_INFO, paths.get_filesystem().exists(path), "File %s does not exist", path.u8string()); + Checks::check_exit(VCPKG_LINE_INFO, fs.exists(path), "File %s does not exist", path.u8string()); return BCryptHasher{hash_type}.hash_file(path); } @@ -239,7 +238,7 @@ namespace vcpkg::Commands::Hash const fs::path file_to_hash = args.command_arguments[0]; const std::string algorithm = args.command_arguments.size() == 2 ? args.command_arguments[1] : "SHA512"; - const std::string hash = get_file_hash(paths, file_to_hash, algorithm); + const std::string hash = get_file_hash(paths.get_filesystem(), file_to_hash, algorithm); System::println(hash); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 1522520184..b13140de2f 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -227,8 +227,6 @@ namespace vcpkg::Export {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"}, {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, {fs::path{"scripts"} / "getWindowsSDK.ps1"}, - {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"}, - {fs::path{"scripts"} / "getProgramFiles32bit.ps1"}, {fs::path{"scripts"} / "VcpkgPowershellUtils.ps1"}, }; diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 0903c2d764..caf09f5261 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -39,6 +39,7 @@ namespace vcpkg paths.triplets = paths.root / "triplets"; paths.scripts = paths.root / "scripts"; + paths.tools = paths.downloads / "tools"; paths.buildsystems = paths.scripts / "buildsystems"; paths.buildsystems_msbuild_targets = paths.buildsystems / "msbuild" / "vcpkg.targets"; @@ -113,9 +114,11 @@ namespace vcpkg return external_toolset; } - // Invariant: toolsets are non-empty and sorted with newest at back() +#if !defined(_WIN32) + Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot build windows triplets from non-windows."); +#else const std::vector& vs_toolsets = - this->toolsets.get_lazy([this]() { return Commands::Fetch::find_toolset_instances(*this); }); + this->toolsets.get_lazy([this]() { return Commands::Fetch::find_toolset_instances_prefered_first(*this); }); std::vector candidates = Util::element_pointers(vs_toolsets); const auto tsv = prebuildinfo.platform_toolset.get(); @@ -159,6 +162,8 @@ namespace vcpkg Checks::check_exit(VCPKG_LINE_INFO, !candidates.empty(), "No suitable Visual Studio instances were found"); return *candidates.front(); + +#endif } Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } diff --git a/toolsrc/vcpkg.sln b/toolsrc/vcpkg.sln index eae73a7609..792d39906e 100644 --- a/toolsrc/vcpkg.sln +++ b/toolsrc/vcpkg.sln @@ -15,11 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{F589 ProjectSection(SolutionItems) = preProject ..\scripts\bootstrap.ps1 = ..\scripts\bootstrap.ps1 ..\scripts\fetchDependency.ps1 = ..\scripts\fetchDependency.ps1 - ..\scripts\findAnyMSBuildWithCppPlatformToolset.ps1 = ..\scripts\findAnyMSBuildWithCppPlatformToolset.ps1 - ..\scripts\findVisualStudioInstallationInstances.ps1 = ..\scripts\findVisualStudioInstallationInstances.ps1 + ..\scripts\getVisualStudioInstances.ps1 = ..\scripts\getVisualStudioInstances.ps1 ..\scripts\get_triplet_environment.cmake = ..\scripts\get_triplet_environment.cmake - ..\scripts\getProgramFiles32bit.ps1 = ..\scripts\getProgramFiles32bit.ps1 - ..\scripts\getProgramFilesPlatformBitness.ps1 = ..\scripts\getProgramFilesPlatformBitness.ps1 ..\scripts\getWindowsSDK.ps1 = ..\scripts\getWindowsSDK.ps1 ..\scripts\internalCI.ps1 = ..\scripts\internalCI.ps1 ..\scripts\ports.cmake = ..\scripts\ports.cmake