Fix bootstrap wrapper scripts to tolerate deployment within readonly VCPKG_ROOT. (#939)

This commit is contained in:
Billy O'Neal 2023-03-01 13:44:54 -08:00 коммит произвёл GitHub
Родитель b2d59cbbb7
Коммит 538539c4e3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 102 добавлений и 268 удалений

Просмотреть файл

@ -156,7 +156,7 @@ jobs:
inputs:
pwsh: true
filePath: vcpkg-init/mint-standalone-bundle.ps1
arguments: '-DestinationTarball "$(Build.BinariesDirectory)\vcpkg-standalone-bundle.tar.gz" -TempDir standalone-temp -SignedFilesRoot "$(Build.BinariesDirectory)" -Deployment OneLiner'
arguments: '-DestinationTarball "$(Build.BinariesDirectory)\vcpkg-standalone-bundle.tar.gz" -TempDir standalone-temp -SignedFilesRoot "$(Build.BinariesDirectory)" -Deployment OneLiner -VcpkgBaseVersion "$(VCPKG_INITIAL_BASE_VERSION)"'
- script: npm pack
displayName: Create vcpkg-artifacts Pack
workingDirectory: $(Build.BinariesDirectory)/ce
@ -366,7 +366,7 @@ jobs:
inputs:
pwsh: true
filePath: vcpkg-init/mint-standalone-bundle.ps1
arguments: '-DestinationDir "$(Build.ArtifactStagingDirectory)/vs-insertion/staging" -TempDir standalone-temp -SignedFilesRoot "$(Build.ArtifactStagingDirectory)\staging" -Deployment "VisualStudio"'
arguments: '-DestinationDir "$(Build.ArtifactStagingDirectory)/vs-insertion/staging" -TempDir standalone-temp -SignedFilesRoot "$(Build.ArtifactStagingDirectory)\staging" -Deployment "VisualStudio" -VcpkgBaseVersion "$(VCPKG_BASE_VERSION)"'
- task: CmdLine@2
displayName: 'Arrange Drop'
inputs:

Просмотреть файл

@ -137,7 +137,7 @@ namespace vcpkg
download_manager.download_file(fs, ce_uri, {}, ce_tarball, nullopt, null_sink);
extract_ce_tarball(paths, ce_tarball, node_path, base_path);
#endif // ^^^ always get latest
#endif // ^^^ !VCPKG_CE_SHA
#endif // ^^^ might need to download
auto temp_directory = fs.create_or_get_temp_directory(VCPKG_LINE_INFO);

Просмотреть файл

@ -9,16 +9,16 @@ Param(
$versionUnlockedUri = "https://github.com/microsoft/vcpkg-tool/releases/latest/download/"
$versionLockedUri = "https://github.com/microsoft/vcpkg-tool/releases/download/$VcpkgBaseVersion/"
$pwshInstaller = Get-Content "$PSScriptRoot\vcpkg-init.ps1" -Raw -Encoding ascii
$pwshInstaller = Get-Content "$PSScriptRoot\vcpkg-init.ps1" -Raw -Encoding Ascii
$pwshInstaller = $pwshInstaller.Replace($versionUnlockedUri, $versionLockedUri)
$pwshLatestLine = "`$SCRIPT:VCPKG_INIT_VERSION = 'latest'"
$pwshLockedLine = "`$SCRIPT:VCPKG_INIT_VERSION = '$VcpkgBaseVersion'"
$pwshInstaller = $pwshInstaller.Replace($pwshLatestLine, $pwshLockedLine)
Set-Content -Path "$Destination\vcpkg-init.ps1" -Value $pwshInstaller -NoNewline -Encoding ascii
Set-Content -Path "$Destination\vcpkg-init.ps1" -Value $pwshInstaller -NoNewline -Encoding Ascii
$shInstaller = Get-Content "$PSScriptRoot\vcpkg-init" -Raw -Encoding ascii
$shInstaller = Get-Content "$PSScriptRoot\vcpkg-init" -Raw -Encoding Ascii
$shInstaller = $shInstaller.Replace($versionUnlockedUri, $versionLockedUri)
$shLatestLine = "VCPKG_BASE_VERSION='latest'"
$shLockedLine = "VCPKG_BASE_VERSION='$VcpkgBaseVersion'"
$shInstaller = $shInstaller.Replace($shLatestLine, $shLockedLine)
Set-Content -Path "$Destination\vcpkg-init" -Value $shInstaller -NoNewline -Encoding ascii
Set-Content -Path "$Destination\vcpkg-init" -Value $shInstaller -NoNewline -Encoding Ascii

Просмотреть файл

@ -6,12 +6,17 @@ Param(
[string]$DestinationDir,
[Parameter(Mandatory = $True)]
[string]$TempDir,
[Parameter()]
[Parameter(Mandatory = $True)]
[string]$Deployment,
[Parameter(Mandatory = $True)]
[string]$SignedFilesRoot
[string]$SignedFilesRoot,
[Parameter(Mandatory = $true)]
[string]$VcpkgBaseVersion
)
$sha = Get-Content "$PSScriptRoot/vcpkg-scripts-sha.txt" -Raw
$sha = $sha.Trim()
if ($Deployment -eq 'VisualStudio') {
$BundleConfig = @{
'readonly' = $True;
@ -29,9 +34,6 @@ if ($Deployment -eq 'VisualStudio') {
}
}
$sha = Get-Content "$PSScriptRoot/vcpkg-scripts-sha.txt" -Raw
$sha = $sha.Trim()
$scripts_dependencies = @(
'build_info.cmake',
'buildsystems',
@ -82,6 +84,8 @@ try {
Pop-Location
}
Set-Content -Path "out/vcpkg-version.txt" -Value $VcpkgBaseVersion -NoNewLine -Encoding Ascii
Copy-Item -Path "$PSScriptRoot/vcpkg-cmd.cmd" -Destination 'out/vcpkg-cmd.cmd'
Copy-Item -Path "$SignedFilesRoot/vcpkg-init" -Destination 'out/vcpkg-init'
Copy-Item -Path "$SignedFilesRoot/vcpkg-init.ps1" -Destination 'out/vcpkg-init.ps1'
Copy-Item -Path "$SignedFilesRoot/vcpkg-init.cmd" -Destination 'out/vcpkg-init.cmd'

17
vcpkg-init/vcpkg-cmd.cmd Normal file
Просмотреть файл

@ -0,0 +1,17 @@
@echo off
:: Generate 30 bits of randomness, to avoid clashing with concurrent executions.
SET /A Z_VCPKG_POSTSCRIPT=%RANDOM% * 32768 + %RANDOM%
:: Set a temporary postscript path
SET Z_VCPKG_POSTSCRIPT=%TEMP%\VCPKG_tmp_%Z_VCPKG_POSTSCRIPT%.cmd
:: Actually run vcpkg and save its exit code
"%~dp0\vcpkg.exe" %*
SET Z_VCPKG_ERRORLEVEL=%ERRORLEVEL%
:: If vcpkg wanted to make any environment changes, make them
IF EXIST "%Z_VCPKG_POSTSCRIPT%" (
CALL "%Z_VCPKG_POSTSCRIPT%"
DEL "%Z_VCPKG_POSTSCRIPT%"
)
:: Cleanup
SET Z_VCPKG_POSTSCRIPT=
EXIT /B %Z_VCPKG_ERRORLEVEL%

Просмотреть файл

@ -28,22 +28,13 @@ if [ $sourced -eq 0 ]; then
exit
fi
Z_VCPKG_init() {
# find important cmdline args
Z_VCPKG_ARGS=()
for each in "$@"; do case $each in
--remove-vcpkg) Z_VCPKG_REMOVE=TRUE;;
*) Z_VCPKG_ARGS+=("$each");;
esac ;done
}
Z_VCPKG_bootstrap() {
VCPKG_BASE_VERSION='latest'
if [ $VCPKG_BASE_VERSION != 'latest' ] \
&& [ -f "${VCPKG_ROOT}/vcpkg" ] \
&& [ -f "${VCPKG_ROOT}/vcpkg-one-liner-version.txt" ] \
&& [ "$(cat "${VCPKG_ROOT}/vcpkg-one-liner-version.txt")" = $VCPKG_BASE_VERSION ]; then
&& [ -f "${VCPKG_ROOT}/vcpkg-version.txt" ] \
&& [ "$(cat "${VCPKG_ROOT}/vcpkg-version.txt")" = $VCPKG_BASE_VERSION ]; then
return 0;
fi
@ -64,14 +55,11 @@ Z_VCPKG_bootstrap() {
chmod +x "${VCPKG_ROOT}/vcpkg"
"${VCPKG_ROOT}/vcpkg" bootstrap-standalone
echo $VCPKG_BASE_VERSION > "${VCPKG_ROOT}/vcpkg-one-liner-version.txt"
return 0;
}
Z_VCPKG_cleanup() {
# clear things that we're not going to need for the long term
unset Z_VCPKG_REMOVE
unset Z_VCPKG_ARGS
if [ -f "${Z_VCPKG_POSTSCRIPT}" ]; then
command rm "${Z_VCPKG_POSTSCRIPT}"
fi
@ -79,21 +67,6 @@ Z_VCPKG_cleanup() {
unset -f Z_VCPKG_bootstrap > /dev/null 2>&1
}
Z_VCPKG_remove() {
Z_VCPKG_cleanup
if [ -d "$VCPKG_ROOT" ]; then
rm -rf "$VCPKG_ROOT"
fi
unset -f Z_VCPKG_init > /dev/null 2>&1
unset -f Z_VCPKG_cleanup > /dev/null 2>&1
unset -f Z_VCPKG_remove > /dev/null 2>&1
unset -f vcpkg > /dev/null 2>&1
}
Z_VCPKG_init "$@"
shift $#
if [ -n "$VCPKG_ROOT" ]; then
export VCPKG_ROOT=$VCPKG_ROOT
else
@ -102,12 +75,6 @@ fi;
mkdir -p "$VCPKG_ROOT"
if [ ! -z "$Z_VCPKG_REMOVE" ]; then
Z_VCPKG_remove
return
fi
Z_VCPKG_bootstrap
if [ $? -eq 1 ]; then
Z_VCPKG_cleanup
@ -116,20 +83,13 @@ fi
# So, we're the real script then.
vcpkg() {
Z_VCPKG_init "$@"
if [ ! -z "$Z_VCPKG_REMOVE" ]; then
Z_VCPKG_remove
return;
fi
# set the response file
# Generate 32 bits of randomness, to avoid clashing with concurrent executions.
export Z_VCPKG_POSTSCRIPT="${VCPKG_ROOT}/VCPKG_tmp_$(dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -f1 -d" ").sh"
export Z_VCPKG_POSTSCRIPT="$(mktemp).sh"
# call vcpkg
# it picks up the Z_VCPKG_POSTSCRIPT environment variable to know where to dump the postscript
"${VCPKG_ROOT}/vcpkg" ${Z_VCPKG_ARGS[@]}
"${VCPKG_ROOT}/vcpkg" $@
# Call the post-invocation script if it is present, then delete it.
# This allows the invocation to potentially modify the caller's environment (e.g. PATH)
@ -143,8 +103,8 @@ vcpkg() {
}
# did they dotsource and have args go ahead and run it then!
if [ -n "$Z_VCPKG_ARGS" ]; then
vcpkg "${Z_VCPKG_ARGS[@]}"
if [ "$#" -gt "0" ]; then
vcpkg $@
fi
Z_VCPKG_cleanup

Просмотреть файл

@ -8,112 +8,50 @@ if #ftw NEQ '' goto :init
# wrapper script for vcpkg
# this is intended to be dot-sourced and then you can use the vcpkg() function
# unpack arguments if they came from CMD
$hash=@{};
get-item env:argz* |% { $hash[$_.name] = $_.value }
if ($hash.count -gt 0) {
$args=for ($i=0; $i -lt $hash.count;$i++) { $hash["ARGZ[$i]"] }
}
# force the array to be an arraylist since we like to mutate it.
$args=[System.Collections.ArrayList][System.Array]$args
# GLOBALS
$VCPKG_START_TIME=Get-Date
# Workaround for $IsWindows not existing in Windows PowerShell
if (-not (Test-Path variable:IsWindows)) {
if (-Not (Test-Path variable:IsWindows)) {
$IsWindows = $true
}
function z-vcpkg-resolve([string]$name) {
$name = Resolve-Path $name -ErrorAction 0 -ErrorVariable _err
if (-not($name)) { return $_err[0].TargetObject }
$Error.clear()
return $name
}
$SCRIPT:DEBUG=( $args.indexOf('--debug') -gt -1 )
function z-vcpkg-debug() {
$t = [int32]((get-date).Subtract(($VCPKG_START_TIME)).ticks/10000)
if($SCRIPT:DEBUG) {
write-host -fore green "[$t msec] " -nonewline
write-host -fore gray $args
}
write-output "[$t msec] $args" >> $VCPKG_ROOT/log.txt
}
function download($url, $path) {
$wc = New-Object net.webclient
if( test-path -ea 0 $path ) {
# check to see if the size is a match before downloading
$s = $wc.OpenRead($url)
$len = $wc.ResponseHeaders['Content-Length']
$s.Dispose()
if( (get-item $path).Length -eq $len ){
$wc.Dispose();
z-vcpkg-debug "skipping download of '$url' - '$path' is ok."
return $path;
}
}
z-vcpkg-debug "Downloading '$url' -> '$path'"
Write-Host "Downloading '$url' -> '$path'"
$wc.DownloadFile($url, $path);
$wc.Dispose();
if( (get-item $path).Length -ne $wc.ResponseHeaders['Content-Length'] ) {
throw "Download of '$url' failed. Check your internet connection."
}
if (-not $IsWindows) {
if (-Not $IsWindows) {
chmod +x $path
}
z-vcpkg-debug "Completed Download of $url"
return $path
}
# set the home path.
if( $ENV:VCPKG_ROOT ) {
$SCRIPT:VCPKG_ROOT=(z-vcpkg-resolve $ENV:VCPKG_ROOT)
$ENV:VCPKG_ROOT=$VCPKG_ROOT
} else {
$SCRIPT:VCPKG_ROOT=(z-vcpkg-resolve "$HOME/.vcpkg")
$ENV:VCPKG_ROOT=$VCPKG_ROOT
# Determine VCPKG_ROOT
if (Test-Path "$PSScriptRoot/.vcpkg-root") {
$env:VCPKG_ROOT = "$PSScriptRoot"
} elseif (-Not (Test-Path env:VCPKG_ROOT)) {
$env:VCPKG_ROOT = "$HOME/.vcpkg"
}
$VCPKG = "${VCPKG_ROOT}/vcpkg"
$VCPKG = Join-Path $env:VCPKG_ROOT vcpkg
if ($IsWindows) {
$VCPKG += '.exe'
}
$SCRIPT:VCPKG_SCRIPT = "${VCPKG_ROOT}/vcpkg-init.ps1"
$SCRIPT:VCPKG_VERSION_MARKER = "${VCPKG_ROOT}/vcpkg-one-liner-version.txt"
$SCRIPT:VCPKG_VERSION_MARKER = Join-Path $env:VCPKG_ROOT vcpkg-version.txt
$SCRIPT:VCPKG_INIT_VERSION = 'latest'
$remove = $args.IndexOf('--remove-vcpkg') -gt -1
if( $remove ) {
write-host "Removing vcpkg"
remove-item -recurse -force -ea 0 "$VCPKG_ROOT"
$error.clear();
exit
}
function bootstrap-vcpkg {
[bool]$do_bootstrap = -not (test-path $VCPKG_SCRIPT) -or ($VCPKG_INIT_VERSION -eq 'latest')
if(-not $do_bootstrap -and (test-path $VCPKG_VERSION_MARKER)) {
$previous_version = Get-Content -Path $VCPKG_VERSION_MARKER -Raw
if ($previous_version.Trim() -ne $VCPKG_INIT_VERSION) {
$do_bootstrap = $true
}
if (-Not ($VCPKG_INIT_VERSION -eq 'latest') `
-And (Test-Path $VCPKG_VERSION_MARKER) `
-And ((Get-Content -Path $VCPKG_VERSION_MARKER -Raw).Trim() -eq $VCPKG_INIT_VERSION)) {
return $True
}
if( -not $do_bootstrap ) {
return $true
}
write-host "Installing vcpkg to $VCPKG_ROOT"
if (-not (Test-Path $VCPKG_ROOT)) {
mkdir $VCPKG_ROOT
}
Write-Host "Installing vcpkg to $env:VCPKG_ROOT"
New-Item -ItemType Directory -Force $env:VCPKG_ROOT | Out-Null
if ($IsWindows) {
download https://github.com/microsoft/vcpkg-tool/releases/latest/download/vcpkg.exe $VCPKG
@ -126,70 +64,38 @@ function bootstrap-vcpkg {
}
& $VCPKG bootstrap-standalone
$PATH = $ENV:PATH
$ENV:PATH="$VCPKG_ROOT;$PATH"
Set-Content -Path $VCPKG_VERSION_MARKER -Value "$VCPKG_INIT_VERSION`n" -Force -NoNewline
z-vcpkg-debug "Bootstrapped vcpkg: ${VCPKG_ROOT}"
if( -not ( test-path $VCPKG_SCRIPT )) {
Write-Error "ERROR! Bootstrapping vcpkg failed."
return $false
}
return $true
if(-Not $?) {
Write-Error "Bootstrap failed."
return $False
}
if( -not (bootstrap-vcpkg )) {
write-error "Unable to install vcpkg."
throw "Installation Unsuccessful."
Write-Host "Bootstrapped vcpkg: $env:VCPKG_ROOT"
return $True
}
# export vcpkg to the current shell.
$shh = New-Module -name vcpkg -ArgumentList @($VCPKG,$VCPKG_ROOT) -ScriptBlock {
param($VCPKG,$VCPKG_ROOT)
function z-vcpkg-resolve([string]$name) {
$name = Resolve-Path $name -ErrorAction 0 -ErrorVariable _err
if (-not($name)) { return $_err[0].TargetObject }
$Error.clear()
return $name
if(-Not (bootstrap-vcpkg)) {
throw "Unable to install vcpkg."
}
# Export vcpkg to the current shell.
New-Module -name vcpkg -ArgumentList @($VCPKG) -ScriptBlock {
param($VCPKG)
function vcpkg() {
if( ($args.indexOf('--remove-vcpkg') -gt -1)) {
# we really want to do call the ps1 script to do this.
if( test-path "${VCPKG_ROOT}/vcpkg.ps1" ) {
& "${VCPKG_ROOT}/vcpkg.ps1" @args
}
return
}
if( -not (test-path $VCPKG )) {
write-error "vcpkg is not installed."
write-host -nonewline "You can reinstall vcpkg by running "
write-host -fore green "iex (iwr -useb https://aka.ms/vcpkg-init.ps1)"
return
}
# setup the postscript file
# Generate 31 bits of randomness, to avoid clashing with concurrent executions.
$env:Z_VCPKG_POSTSCRIPT = z-vcpkg-resolve "${VCPKG_ROOT}/VCPKG_tmp_$(Get-Random -SetSeed $PID).ps1"
$env:Z_VCPKG_POSTSCRIPT = Join-Path ([System.IO.Path]::GetTempPath()) "VCPKG_tmp_$(Get-Random -SetSeed $PID).ps1"
& $VCPKG @args
# dot-source the postscript file to modify the environment
if ($env:Z_VCPKG_POSTSCRIPT -and (Test-Path $env:Z_VCPKG_POSTSCRIPT)) {
# write-host (get-content -raw $env:Z_VCPKG_POSTSCRIPT)
$postscr = get-content -raw $env:Z_VCPKG_POSTSCRIPT
if (Test-Path $env:Z_VCPKG_POSTSCRIPT) {
$postscr = Get-Content -Raw $env:Z_VCPKG_POSTSCRIPT
if( $postscr ) {
iex $postscr
}
Remove-Item -Force -ea 0 $env:Z_VCPKG_POSTSCRIPT,env:Z_VCPKG_POSTSCRIPT
}
}
}
} | Out-Null
if ($args.Count -ne 0) {
return vcpkg @args
@ -197,91 +103,38 @@ if ($args.Count -ne 0) {
return
<#
:set
set ARGZ[%i%]=%1&set /a i+=1 & goto :eof
:unset
set %1=& goto :eof
:init
if exist $null erase $null
:: do anything we need to before calling into powershell
if exist $null erase $null
:: If the first line of this script created a file named $null, delete it
IF EXIST $null DEL $null
:: Figure out where VCPKG_ROOT is
IF EXIST "%~dp0\.vcpkg-root" SET VCPKG_ROOT=%~dp0
IF "%VCPKG_ROOT:~-1%"=="\" SET VCPKG_ROOT=%VCPKG_ROOT:~0,-1%
IF "%VCPKG_ROOT%"=="" SET VCPKG_ROOT=%USERPROFILE%\.vcpkg
:: we're running vcpkg from the home folder
set Z_VCPKG_CMD=%VCPKG_ROOT%\vcpkg-init.cmd
set Z_VCPKG_EXE=%VCPKG_ROOT%\vcpkg.exe
:: if we're being asked to remove the install, call bootstrap
if "%1" EQU "--remove-vcpkg" (
set REMOVE_VCPKG=TRUE
doskey vcpkg=
goto BOOTSTRAP
)
:: do we even have it installed?
if NOT exist "%Z_VCPKG_CMD%" goto BOOTSTRAP
:: if this is the actual installed vcpkg, let's get to the invocation
if "%~dfp0" == "%Z_VCPKG_CMD%" goto INVOKE
:: this is not the 'right' vcpkg cmd, let's forward this on to that one.
call "%Z_VCPKG_CMD%" %*
set VCPKG_EXITCODE=%ERRORLEVEL%
goto :eof
:INVOKE
:: Generate 30 bits of randomness, to avoid clashing with concurrent executions.
SET /A Z_VCPKG_POSTSCRIPT=%RANDOM% * 32768 + %RANDOM%
SET Z_VCPKG_POSTSCRIPT=%VCPKG_ROOT%\VCPKG_tmp_%Z_VCPKG_POSTSCRIPT%.cmd
:: call the program
"%Z_VCPKG_EXE%" %*
set VCPKG_EXITCODE=%ERRORLEVEL%
doskey vcpkg="%Z_VCPKG_CMD%" $*
:POSTSCRIPT
:: Call the post-invocation script if it is present, then delete it.
:: This allows the invocation to potentially modify the caller's environment (e.g. PATH).
IF NOT EXIST "%Z_VCPKG_POSTSCRIPT%" GOTO :fin
CALL "%Z_VCPKG_POSTSCRIPT%"
DEL "%Z_VCPKG_POSTSCRIPT%"
goto :fin
:BOOTSTRAP
:: add the cmdline args to the environment so powershell can use them
set /a i=0 & for %%a in (%*) do call :set %%a
set Z_POWERSHELL_EXE=
for %%i in (pwsh.exe powershell.exe) do (
if EXIST "%%~$PATH:i" set Z_POWERSHELL_EXE=%%~$PATH:i & goto :gotpwsh
)
:gotpwsh
"%Z_POWERSHELL_EXE%" -noprofile -executionpolicy unrestricted -command "iex (get-content %~dfp0 -raw)#" && set REMOVE_VCPKG=
set VCPKG_EXITCODE=%ERRORLEVEL%
:: clear out the arguments
@for /f "delims==" %%_ in ('set ^| findstr -i argz') do call :unset %%_
:: if we're being asked to remove it,we're done.
if "%REMOVE_VCPKG%" EQU "TRUE" (
goto :fin
)
:CREATEALIAS
doskey vcpkg="%VCPKG_ROOT%\vcpkg-init.cmd" $*
:fin
:: Call powershell which may or may not invoke bootstrap if there's a version mismatch
SET Z_POWERSHELL_EXE=
SET Z_VCPKG_POSTSCRIPT=
SET Z_VCPKG_CMD=
set Z_VCPKG_EXE=
FOR %%i IN (pwsh.exe powershell.exe) DO (
IF EXIST "%%~$PATH:i" SET Z_POWERSHELL_EXE=%%~$PATH:i & GOTO :gotpwsh
)
EXIT /B %VCPKG_EXITCODE%
goto :eof
:gotpwsh
"%Z_POWERSHELL_EXE%" -NoProfile -ExecutionPolicy Unrestricted -Command "iex (get-content \"%~dfp0\" -raw)#"
IF ERRORLEVEL 1 (
:: leak VCPKG_ROOT
SET Z_POWERSHELL_EXE=
EXIT /B 1
)
SET Z_POWERSHELL_EXE=
:: Install the doskey
DOSKEY vcpkg="%VCPKG_ROOT%\vcpkg-cmd.cmd" $*
:: If there were any arguments, also invoke vcpkg with them
IF "%1"=="" GOTO fin
CALL "%VCPKG_ROOT%\vcpkg-cmd.cmd" %*
:fin
EXIT /B
#>