diff --git a/azure-pipelines/e2e_ports/integrate-install/NoProps.vcxproj b/azure-pipelines/e2e_ports/integrate-install/NoProps.vcxproj
index 5b75d09615..6f85444235 100644
--- a/azure-pipelines/e2e_ports/integrate-install/NoProps.vcxproj
+++ b/azure-pipelines/e2e_ports/integrate-install/NoProps.vcxproj
@@ -141,5 +141,5 @@
-
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/Project1.vcxproj b/azure-pipelines/e2e_ports/integrate-install/Project1.vcxproj
index a8896fe29d..342099061f 100644
--- a/azure-pipelines/e2e_ports/integrate-install/Project1.vcxproj
+++ b/azure-pipelines/e2e_ports/integrate-install/Project1.vcxproj
@@ -52,7 +52,7 @@
Unicode
-
+
@@ -142,5 +142,5 @@
-
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet.vcxproj b/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet.vcxproj
index 883fc8ec1a..2197c98dd8 100644
--- a/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet.vcxproj
+++ b/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet.vcxproj
@@ -52,7 +52,7 @@
Unicode
-
+
@@ -147,5 +147,5 @@
-
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet2.vcxproj b/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet2.vcxproj
index d3352e195b..0224be227f 100644
--- a/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet2.vcxproj
+++ b/azure-pipelines/e2e_ports/integrate-install/VcpkgTriplet2.vcxproj
@@ -53,7 +53,7 @@
Unicode
-
+
@@ -145,5 +145,5 @@
-
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic.vcxproj b/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic.vcxproj
index 28c4fc7158..7558f1650e 100644
--- a/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic.vcxproj
+++ b/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic.vcxproj
@@ -52,7 +52,7 @@
Unicode
-
+
@@ -147,5 +147,5 @@
-
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic2.vcxproj b/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic2.vcxproj
index 98beaee4b1..a70a307351 100644
--- a/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic2.vcxproj
+++ b/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStatic2.vcxproj
@@ -53,7 +53,7 @@
Unicode
-
+
@@ -145,5 +145,5 @@
-
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStaticManifestHost.vcxproj b/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStaticManifestHost.vcxproj
new file mode 100644
index 0000000000..a80f878ec5
--- /dev/null
+++ b/azure-pipelines/e2e_ports/integrate-install/VcpkgUseStaticManifestHost.vcxproj
@@ -0,0 +1,154 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {5AFB7AF5-D8FC-4A86-B0D2-3BBD039ED03A}
+ VcpkgUseStaticManifestHost
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+ true
+ x64-windows-static
+ true
+ $(TestingVcpkgInstalledDir)
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/integrate-install/vcpkg.json b/azure-pipelines/e2e_ports/integrate-install/vcpkg.json
new file mode 100644
index 0000000000..54275ccd51
--- /dev/null
+++ b/azure-pipelines/e2e_ports/integrate-install/vcpkg.json
@@ -0,0 +1,11 @@
+{
+ "name": "integrate-install-test",
+ "version-string": "0",
+ "dependencies": [
+ {
+ "name": "zlib",
+ "host": true
+ },
+ "zlib"
+ ]
+}
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/overlays/tool-control/CONTROL b/azure-pipelines/e2e_ports/overlays/tool-control/CONTROL
new file mode 100644
index 0000000000..58052ece7b
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/tool-control/CONTROL
@@ -0,0 +1,4 @@
+Source: tool-control
+Version: 1
+Description: test tool port
+Build-Depends: tool-liba
diff --git a/azure-pipelines/e2e_ports/overlays/tool-control/portfile.cmake b/azure-pipelines/e2e_ports/overlays/tool-control/portfile.cmake
new file mode 100644
index 0000000000..065116c276
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/tool-control/portfile.cmake
@@ -0,0 +1 @@
+set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
diff --git a/azure-pipelines/e2e_ports/overlays/tool-liba/portfile.cmake b/azure-pipelines/e2e_ports/overlays/tool-liba/portfile.cmake
new file mode 100644
index 0000000000..065116c276
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/tool-liba/portfile.cmake
@@ -0,0 +1 @@
+set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
diff --git a/azure-pipelines/e2e_ports/overlays/tool-liba/vcpkg.json b/azure-pipelines/e2e_ports/overlays/tool-liba/vcpkg.json
new file mode 100644
index 0000000000..038eec9302
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/tool-liba/vcpkg.json
@@ -0,0 +1,4 @@
+{
+ "name": "tool-liba",
+ "version-string": "1"
+}
diff --git a/azure-pipelines/e2e_ports/overlays/tool-libb/portfile.cmake b/azure-pipelines/e2e_ports/overlays/tool-libb/portfile.cmake
new file mode 100644
index 0000000000..54e886c6c2
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/tool-libb/portfile.cmake
@@ -0,0 +1,21 @@
+set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
+
+if(NOT DEFINED _HOST_TRIPLET)
+ message(FATAL_ERROR "tool-libb requires _HOST_TRIPLET to be defined")
+endif()
+
+get_filename_component(base_install_dir "${CURRENT_INSTALLED_DIR}" DIRECTORY)
+
+# This is needed to cut the requirement for an atomic change across both Microsoft/vcpkg and Microsoft/vcpkg-tool
+if(DEFINED CURRENT_HOST_INSTALLED_DIR AND NOT CURRENT_HOST_INSTALLED_DIR STREQUAL "${base_install_dir}/${_HOST_TRIPLET}")
+ message(FATAL_ERROR "tool-libb requires CURRENT_HOST_INSTALLED_DIR to be defined to \"${base_install_dir}/${_HOST_TRIPLET}\"")
+endif()
+
+set(CURRENT_HOST_INSTALLED_DIR "${base_install_dir}/${_HOST_TRIPLET}")
+
+if(NOT EXISTS "${CURRENT_HOST_INSTALLED_DIR}/share/tool-manifest")
+ message(FATAL_ERROR "tool-libb requires tool-manifest on the host (${CURRENT_HOST_INSTALLED_DIR}/share/tool-manifest)")
+endif()
+if(NOT EXISTS "${CURRENT_HOST_INSTALLED_DIR}/share/tool-control")
+ message(FATAL_ERROR "tool-libb requires tool-control on the host (${CURRENT_HOST_INSTALLED_DIR}/share/tool-control)")
+endif()
diff --git a/azure-pipelines/e2e_ports/overlays/tool-libb/vcpkg.json b/azure-pipelines/e2e_ports/overlays/tool-libb/vcpkg.json
new file mode 100644
index 0000000000..6212bf8e2e
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/tool-libb/vcpkg.json
@@ -0,0 +1,14 @@
+{
+ "name": "tool-libb",
+ "version-string": "1",
+ "dependencies": [
+ {
+ "name": "tool-manifest",
+ "host": true
+ },
+ {
+ "name": "tool-control",
+ "host": true
+ }
+ ]
+}
\ No newline at end of file
diff --git a/azure-pipelines/e2e_ports/overlays/tool-manifest/portfile.cmake b/azure-pipelines/e2e_ports/overlays/tool-manifest/portfile.cmake
new file mode 100644
index 0000000000..065116c276
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/tool-manifest/portfile.cmake
@@ -0,0 +1 @@
+set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
diff --git a/azure-pipelines/e2e_ports/overlays/tool-manifest/vcpkg.json b/azure-pipelines/e2e_ports/overlays/tool-manifest/vcpkg.json
new file mode 100644
index 0000000000..74f81ede0a
--- /dev/null
+++ b/azure-pipelines/e2e_ports/overlays/tool-manifest/vcpkg.json
@@ -0,0 +1,7 @@
+{
+ "name": "tool-manifest",
+ "version-string": "1.0.0",
+ "dependencies": [
+ "tool-liba"
+ ]
+}
diff --git a/azure-pipelines/e2e_ports/triplets/x64-linux-e2e.cmake b/azure-pipelines/e2e_ports/triplets/x64-linux-e2e.cmake
new file mode 100644
index 0000000000..5196184638
--- /dev/null
+++ b/azure-pipelines/e2e_ports/triplets/x64-linux-e2e.cmake
@@ -0,0 +1,5 @@
+set(VCPKG_TARGET_ARCHITECTURE x64)
+set(VCPKG_CRT_LINKAGE dynamic)
+set(VCPKG_LIBRARY_LINKAGE static)
+
+set(VCPKG_CMAKE_SYSTEM_NAME Linux)
diff --git a/azure-pipelines/e2e_ports/triplets/x64-osx-e2e.cmake b/azure-pipelines/e2e_ports/triplets/x64-osx-e2e.cmake
new file mode 100644
index 0000000000..8cd8c90b4a
--- /dev/null
+++ b/azure-pipelines/e2e_ports/triplets/x64-osx-e2e.cmake
@@ -0,0 +1,6 @@
+set(VCPKG_TARGET_ARCHITECTURE x64)
+set(VCPKG_CRT_LINKAGE dynamic)
+set(VCPKG_LIBRARY_LINKAGE static)
+
+set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
+set(VCPKG_OSX_ARCHITECTURES x86_64)
diff --git a/azure-pipelines/e2e_ports/triplets/x64-windows-e2e.cmake b/azure-pipelines/e2e_ports/triplets/x64-windows-e2e.cmake
new file mode 100644
index 0000000000..d0be7297f0
--- /dev/null
+++ b/azure-pipelines/e2e_ports/triplets/x64-windows-e2e.cmake
@@ -0,0 +1,4 @@
+set(VCPKG_TARGET_ARCHITECTURE x64)
+set(VCPKG_CRT_LINKAGE dynamic)
+set(VCPKG_LIBRARY_LINKAGE dynamic)
+
diff --git a/azure-pipelines/end-to-end-tests-dir/integrate-install.ps1 b/azure-pipelines/end-to-end-tests-dir/integrate-install.ps1
index 38362ba8cb..f02a5ec6d5 100644
--- a/azure-pipelines/end-to-end-tests-dir/integrate-install.ps1
+++ b/azure-pipelines/end-to-end-tests-dir/integrate-install.ps1
@@ -1,28 +1,43 @@
if (-not $IsLinux -and -not $IsMacOS) {
. $PSScriptRoot/../end-to-end-tests-prelude.ps1
+ $iiroot = "$PSScriptRoot/../e2e_ports/integrate-install"
+
+ $env:VCPKG_BINARY_SOURCES="clear;default,read"
+ $env:VCPKG_KEEP_ENV_VARS="VCPKG_KEEP_ENV_VARS;VCPKG_BINARY_SOURCES;VCPKG_FORCE_SYSTEM_BINARIES;VCPKG_DOWNLOADS;VCPKG_DEFAULT_BINARY_CACHE"
# Test msbuild props and targets
- $Script:CurrentTest = "zlib:x86-windows-static msbuild scripts\testing\integrate-install\..."
+ $Script:CurrentTest = "zlib:x86-windows msbuild $iiroot\..."
Write-Host $Script:CurrentTest
- ./vcpkg $commonArgs install zlib:x86-windows-static --x-binarysource=clear
+ ./vcpkg $commonArgs install zlib:x86-windows
Throw-IfFailed
- foreach ($project in @("VcpkgTriplet", "VcpkgTriplet2", "VcpkgUseStatic", "VcpkgUseStatic2")) {
- $Script:CurrentTest = "msbuild scripts\testing\integrate-install\$project.vcxproj"
- ./vcpkg $commonArgs env "msbuild scripts\testing\integrate-install\$project.vcxproj /p:VcpkgRoot=$TestingRoot /p:IntDir=$TestingRoot\int\ /p:OutDir=$TestingRoot\out\ "
+ foreach ($project in @("Project1", "NoProps")) {
+ $Script:CurrentTest = "msbuild $iiroot\$project.vcxproj"
+ Write-Host $Script:CurrentTest
+ ./vcpkg $commonArgs env "msbuild $iiroot\$project.vcxproj /p:VCPKG_ROOT=$VcpkgRoot /p:VcpkgRoot=$TestingRoot /p:IntDir=$TestingRoot\int\ /p:OutDir=$TestingRoot\out\ "
Throw-IfFailed
Remove-Item -Recurse -Force $TestingRoot\int
Remove-Item -Recurse -Force $TestingRoot\out
}
- $Script:CurrentTest = "zlib:x86-windows msbuild scripts\testing\integrate-install\..."
+
+ $Script:CurrentTest = "zlib:x86-windows-static msbuild $iiroot\..."
Write-Host $Script:CurrentTest
- ./vcpkg $commonArgs install zlib:x86-windows --x-binarysource=clear
+ ./vcpkg $commonArgs install zlib:x86-windows-static
Throw-IfFailed
- foreach ($project in @("Project1", "NoProps")) {
- $Script:CurrentTest = "msbuild scripts\testing\integrate-install\$project.vcxproj"
- Write-Host $Script:CurrentTest
- ./vcpkg $commonArgs env "msbuild scripts\testing\integrate-install\$project.vcxproj /p:VcpkgRoot=$TestingRoot /p:IntDir=$TestingRoot\int\ /p:OutDir=$TestingRoot\out\ "
+ foreach ($project in @("VcpkgTriplet", "VcpkgTriplet2", "VcpkgUseStatic", "VcpkgUseStatic2")) {
+ $Script:CurrentTest = "msbuild $iiroot\$project.vcxproj"
+ ./vcpkg $commonArgs env "msbuild $iiroot\$project.vcxproj /p:VCPKG_ROOT=$VcpkgRoot /p:VcpkgRoot=$TestingRoot /p:IntDir=$TestingRoot\int\ /p:OutDir=$TestingRoot\out\ "
Throw-IfFailed
Remove-Item -Recurse -Force $TestingRoot\int
Remove-Item -Recurse -Force $TestingRoot\out
}
+
+ # This test is currently disabled because it requires adding the ability to override the vcpkg executable into the msbuild props/targets.
+ # Require-FileNotExists $installRoot/x64-windows-static/include/zlib.h
+ # Require-FileNotExists $installRoot/x64-windows/include/zlib.h
+ # Require-FileExists $installRoot/x86-windows/include/zlib.h
+ # $Script:CurrentTest = "msbuild $iiroot\VcpkgUseStaticManifestHost.vcxproj"
+ # ./vcpkg $commonArgs env "msbuild $iiroot\VcpkgUseStaticManifestHost.vcxproj /p:VCPKG_ROOT=$VcpkgRoot `"/p:_VcpkgExecutable=$VcpkgExe`" /p:VcpkgRoot=$TestingRoot /p:IntDir=$TestingRoot\int\ /p:OutDir=$TestingRoot\out\ /p:TestingVcpkgInstalledDir=$installRoot"
+ # Throw-IfFailed
+ # Require-FileExists $installRoot/x64-windows-static/include/zlib.h
+ # Require-FileNotExists $installRoot/x86-windows/include/zlib.h
}
diff --git a/azure-pipelines/end-to-end-tests-dir/tool-ports.ps1 b/azure-pipelines/end-to-end-tests-dir/tool-ports.ps1
new file mode 100644
index 0000000000..4436ae6dd3
--- /dev/null
+++ b/azure-pipelines/end-to-end-tests-dir/tool-ports.ps1
@@ -0,0 +1,84 @@
+. $PSScriptRoot/../end-to-end-tests-prelude.ps1
+
+$commonArgs += @("--x-binarysource=clear")
+
+$hostTriplet = "$Triplet"
+$env:VCPKG_DEFAULT_HOST_TRIPLET = "$hostTriplet"
+if (!$IsLinux -and !$IsMacOS)
+{
+ $targetTriplet = "x64-windows-e2e"
+}
+elseif ($IsMacOS)
+{
+ $targetTriplet = "x64-osx-e2e"
+}
+else
+{
+ $targetTriplet = "x64-linux-e2e"
+}
+
+$env:VCPKG_FEATURE_FLAGS="-compilertracking"
+
+# Test native installation
+Run-Vcpkg ($commonArgs + @("install", "tool-libb"))
+Throw-IfFailed
+@("tool-control", "tool-manifest", "tool-liba", "tool-libb") | % {
+ Require-FileNotExists $installRoot/$targetTriplet/share/$_
+ Require-FileExists $installRoot/$hostTriplet/share/$_
+}
+
+Refresh-TestRoot
+
+# Test cross installation
+Run-Vcpkg ($commonArgs + @("install", "tool-libb:$targetTriplet"))
+Throw-IfFailed
+@("tool-control", "tool-manifest", "tool-liba") | % {
+ Require-FileNotExists $installRoot/$targetTriplet/share/$_
+ Require-FileExists $installRoot/$hostTriplet/share/$_
+}
+@("tool-libb") | % {
+ Require-FileExists $installRoot/$targetTriplet/share/$_
+ Require-FileNotExists $installRoot/$hostTriplet/share/$_
+}
+
+# Test removal of packages in cross installation
+Run-Vcpkg ($commonArgs + @("remove", "tool-manifest", "--recurse"))
+Throw-IfFailed
+@("tool-control", "tool-liba") | % {
+ Require-FileNotExists $installRoot/$targetTriplet/share/$_
+ Require-FileExists $installRoot/$hostTriplet/share/$_
+}
+@("tool-libb", "tool-manifest") | % {
+ Require-FileNotExists $installRoot/$targetTriplet/share/$_
+ Require-FileNotExists $installRoot/$hostTriplet/share/$_
+}
+
+Refresh-TestRoot
+
+# Test VCPKG_DEFAULT_HOST_TRIPLET
+$env:VCPKG_DEFAULT_HOST_TRIPLET = $targetTriplet
+Run-Vcpkg ($commonArgs + @("install", "tool-libb:$hostTriplet"))
+Throw-IfFailed
+@("tool-control", "tool-manifest", "tool-liba") | % {
+ Require-FileExists $installRoot/$targetTriplet/share/$_
+ Require-FileNotExists $installRoot/$hostTriplet/share/$_
+}
+@("tool-libb") | % {
+ Require-FileNotExists $installRoot/$targetTriplet/share/$_
+ Require-FileExists $installRoot/$hostTriplet/share/$_
+}
+
+Refresh-TestRoot
+
+Remove-Item env:VCPKG_DEFAULT_HOST_TRIPLET
+# Test --host-triplet
+Run-Vcpkg ($commonArgs + @("install", "tool-libb:$hostTriplet", "--host-triplet=$targetTriplet"))
+Throw-IfFailed
+@("tool-control", "tool-manifest", "tool-liba") | % {
+ Require-FileExists $installRoot/$targetTriplet/share/$_
+ Require-FileNotExists $installRoot/$hostTriplet/share/$_
+}
+@("tool-libb") | % {
+ Require-FileNotExists $installRoot/$targetTriplet/share/$_
+ Require-FileExists $installRoot/$hostTriplet/share/$_
+}
diff --git a/azure-pipelines/end-to-end-tests-prelude.ps1 b/azure-pipelines/end-to-end-tests-prelude.ps1
index 497f4fc941..7d51787fd3 100644
--- a/azure-pipelines/end-to-end-tests-prelude.ps1
+++ b/azure-pipelines/end-to-end-tests-prelude.ps1
@@ -12,19 +12,11 @@ $commonArgs = @(
"--x-buildtrees-root=$buildtreesRoot",
"--x-install-root=$installRoot",
"--x-packages-root=$packagesRoot",
- "--overlay-ports=$PSScriptRoot/e2e_ports/overlays"
+ "--overlay-ports=$PSScriptRoot/e2e_ports/overlays",
+ "--overlay-triplets=$PSScriptRoot/e2e_ports/triplets"
)
$Script:CurrentTest = 'unassigned'
-if ($IsWindows)
-{
- $VcpkgExe = Get-Item './vcpkg.exe'
-}
-else
-{
- $VcpkgExe = Get-Item './vcpkg'
-}
-
function Refresh-TestRoot {
Remove-Item -Recurse -Force $TestingRoot -ErrorAction SilentlyContinue
mkdir $TestingRoot | Out-Null
@@ -72,7 +64,7 @@ function Run-Vcpkg {
[Parameter(ValueFromRemainingArguments)]
[string[]]$TestArgs
)
- $Script:CurrentTest = "vcpkg $($testArgs -join ' ')"
+ $Script:CurrentTest = "$VcpkgExe $($testArgs -join ' ')"
Write-Host $Script:CurrentTest
& $VcpkgExe @testArgs
}
diff --git a/azure-pipelines/end-to-end-tests.ps1 b/azure-pipelines/end-to-end-tests.ps1
index d25bc67ff1..f8fa756674 100644
--- a/azure-pipelines/end-to-end-tests.ps1
+++ b/azure-pipelines/end-to-end-tests.ps1
@@ -29,7 +29,9 @@ Param(
[string]$VcpkgRoot,
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
- [string]$Filter
+ [string]$Filter,
+ [Parameter(Mandatory = $false)]
+ [string]$VcpkgExe
)
$ErrorActionPreference = "Stop"
@@ -40,7 +42,18 @@ if (-Not (Test-Path $WorkingRoot)) {
$WorkingRoot = (Get-Item $WorkingRoot).FullName
$VcpkgRoot = (Get-Item $VcpkgRoot).FullName
-$env:VCPKG_ROOT = $VcpkgRoot
+
+if ([string]::IsNullOrEmpty($VcpkgExe))
+{
+ if ($IsWindows)
+ {
+ $VcpkgExe = Get-Item './vcpkg.exe'
+ }
+ else
+ {
+ $VcpkgExe = Get-Item './vcpkg'
+ }
+}
$AllTests = Get-ChildItem $PSScriptRoot/end-to-end-tests-dir/*.ps1
if ($Filter -ne $Null) {
@@ -49,9 +62,58 @@ if ($Filter -ne $Null) {
$n = 1
$m = $AllTests.Count
-$AllTests | % {
- Write-Host "[end-to-end-tests.ps1] [$n/$m] Running suite $_"
- & $_
+$envvars_clear = @(
+ "VCPKG_DEFAULT_HOST_TRIPLET",
+ "VCPKG_DEFAULT_TRIPLET",
+ "VCPKG_BINARY_SOURCES",
+ "VCPKG_OVERLAY_PORTS",
+ "VCPKG_OVERLAY_TRIPLETS",
+ "VCPKG_KEEP_ENV_VARS",
+ "VCPKG_ROOT",
+ "VCPKG_FEATURE_FLAGS",
+ "VCPKG_DISABLE_METRICS"
+)
+$envvars = $envvars_clear + @("VCPKG_DOWNLOADS")
+
+foreach ($Test in $AllTests)
+{
+ Write-Host "[end-to-end-tests.ps1] [$n/$m] Running suite $Test"
+
+ $envbackup = @{}
+ foreach ($var in $envvars)
+ {
+ $envbackup[$var] = [System.Environment]::GetEnvironmentVariable($var)
+ }
+
+ try
+ {
+ foreach ($var in $envvars_clear)
+ {
+ if (Test-Path "Env:\$var")
+ {
+ Remove-Item "Env:\$var"
+ }
+ }
+ $env:VCPKG_ROOT = $VcpkgRoot
+ & $Test
+ }
+ finally
+ {
+ foreach ($var in $envvars)
+ {
+ if ($envbackup[$var] -eq $null)
+ {
+ if (Test-Path "Env:\$var")
+ {
+ Remove-Item "Env:\$var"
+ }
+ }
+ else
+ {
+ Set-Item "Env:\$var" "$envbackup[$var]"
+ }
+ }
+ }
$n += 1
}
diff --git a/include/vcpkg/binaryparagraph.h b/include/vcpkg/binaryparagraph.h
index a807797f88..7bc4682a8a 100644
--- a/include/vcpkg/binaryparagraph.h
+++ b/include/vcpkg/binaryparagraph.h
@@ -39,9 +39,9 @@ namespace vcpkg
std::vector maintainers;
std::string feature;
std::vector default_features;
- std::vector dependencies;
+ std::vector dependencies;
std::string abi;
- Type type = {Type::UNKNOWN};
+ Type type = {Type::PORT};
};
bool operator==(const BinaryParagraph&, const BinaryParagraph&);
diff --git a/include/vcpkg/build.h b/include/vcpkg/build.h
index ed27244359..afe89ce311 100644
--- a/include/vcpkg/build.h
+++ b/include/vcpkg/build.h
@@ -59,6 +59,7 @@ namespace vcpkg::Build
{
int perform_ex(const VcpkgCmdArguments& args,
const FullPackageSpec& full_spec,
+ Triplet host_triplet,
const SourceControlFileLocation& scfl,
const PortFileProvider::PathsPortFileProvider& provider,
IBinaryProvider& binaryprovider,
@@ -66,14 +67,21 @@ namespace vcpkg::Build
const VcpkgPaths& paths);
void perform_and_exit_ex(const VcpkgCmdArguments& args,
const FullPackageSpec& full_spec,
+ Triplet host_triplet,
const SourceControlFileLocation& scfl,
const PortFileProvider::PathsPortFileProvider& provider,
IBinaryProvider& binaryprovider,
const IBuildLogsRecorder& build_logs_recorder,
const VcpkgPaths& paths);
- int perform(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
+ int perform(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet);
}
enum class UseHeadVersion
@@ -384,6 +392,7 @@ namespace vcpkg::Build
{
virtual void perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const override;
+ Triplet default_triplet,
+ Triplet host_triplet) const override;
};
}
diff --git a/include/vcpkg/commands.buildexternal.h b/include/vcpkg/commands.buildexternal.h
index b4e1aa669b..4187fa3876 100644
--- a/include/vcpkg/commands.buildexternal.h
+++ b/include/vcpkg/commands.buildexternal.h
@@ -4,12 +4,16 @@
namespace vcpkg::Commands::BuildExternal
{
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet);
struct BuildExternalCommand : TripletCommand
{
virtual void perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const override;
+ Triplet default_triplet,
+ Triplet host_triplet) const override;
};
}
diff --git a/include/vcpkg/commands.ci.h b/include/vcpkg/commands.ci.h
index 4657741c92..8061e14354 100644
--- a/include/vcpkg/commands.ci.h
+++ b/include/vcpkg/commands.ci.h
@@ -5,12 +5,16 @@
namespace vcpkg::Commands::CI
{
extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet);
struct CICommand : TripletCommand
{
virtual void perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const override;
+ Triplet default_triplet,
+ Triplet host_triplet) const override;
};
}
diff --git a/include/vcpkg/commands.dependinfo.h b/include/vcpkg/commands.dependinfo.h
index 81301b6d9c..ef5d8a1080 100644
--- a/include/vcpkg/commands.dependinfo.h
+++ b/include/vcpkg/commands.dependinfo.h
@@ -5,12 +5,16 @@
namespace vcpkg::Commands::DependInfo
{
extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet);
struct DependInfoCommand : TripletCommand
{
virtual void perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const override;
+ Triplet default_triplet,
+ Triplet host_triplet) const override;
};
}
diff --git a/include/vcpkg/commands.env.h b/include/vcpkg/commands.env.h
index 5ba58d081d..d7087e7e7f 100644
--- a/include/vcpkg/commands.env.h
+++ b/include/vcpkg/commands.env.h
@@ -5,12 +5,16 @@
namespace vcpkg::Commands::Env
{
extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet);
struct EnvCommand : TripletCommand
{
virtual void perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const override;
+ Triplet default_triplet,
+ Triplet host_triplet) const override;
};
}
diff --git a/include/vcpkg/commands.interface.h b/include/vcpkg/commands.interface.h
index c8bc14ca96..e9f6da0479 100644
--- a/include/vcpkg/commands.interface.h
+++ b/include/vcpkg/commands.interface.h
@@ -31,7 +31,8 @@ namespace vcpkg::Commands
{
virtual void perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const = 0;
+ Triplet default_triplet,
+ Triplet host_triplet) const = 0;
virtual ~TripletCommand() = default;
};
}
diff --git a/include/vcpkg/commands.setinstalled.h b/include/vcpkg/commands.setinstalled.h
index c5723669bd..efeb864c0a 100644
--- a/include/vcpkg/commands.setinstalled.h
+++ b/include/vcpkg/commands.setinstalled.h
@@ -15,12 +15,16 @@ namespace vcpkg::Commands::SetInstalled
Dependencies::ActionPlan action_plan,
DryRun dry_run,
const Optional& pkgsconfig_path);
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet);
struct SetInstalledCommand : TripletCommand
{
virtual void perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const override;
+ Triplet default_triplet,
+ Triplet host_triplet) const override;
};
}
diff --git a/include/vcpkg/commands.upgrade.h b/include/vcpkg/commands.upgrade.h
index 340a70c97c..8f724a0808 100644
--- a/include/vcpkg/commands.upgrade.h
+++ b/include/vcpkg/commands.upgrade.h
@@ -5,12 +5,16 @@
namespace vcpkg::Commands::Upgrade
{
extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet);
struct UpgradeCommand : TripletCommand
{
virtual void perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const override;
+ Triplet default_triplet,
+ Triplet host_triplet) const override;
};
}
diff --git a/include/vcpkg/dependencies.h b/include/vcpkg/dependencies.h
index 1b1a7748b6..8a30b3fd1b 100644
--- a/include/vcpkg/dependencies.h
+++ b/include/vcpkg/dependencies.h
@@ -56,6 +56,7 @@ namespace vcpkg::Dependencies
InstallPlanAction(const PackageSpec& spec,
const SourceControlFileLocation& scfl,
const RequestType& request_type,
+ Triplet host_triplet,
std::map>&& dependencies);
std::string displayname() const;
@@ -76,6 +77,7 @@ namespace vcpkg::Dependencies
std::map> feature_dependencies;
std::vector package_dependencies;
std::vector feature_list;
+ Triplet host_triplet;
Optional abi_info;
};
@@ -142,7 +144,11 @@ namespace vcpkg::Dependencies
struct CreateInstallPlanOptions
{
+ CreateInstallPlanOptions(Graphs::Randomizer* r, Triplet t) : randomizer(r), host_triplet(t) { }
+ CreateInstallPlanOptions(Triplet t) : host_triplet(t) { }
+
Graphs::Randomizer* randomizer = nullptr;
+ Triplet host_triplet;
};
std::vector create_remove_plan(const std::vector& specs,
@@ -159,30 +165,31 @@ namespace vcpkg::Dependencies
const CMakeVars::CMakeVarProvider& var_provider,
const std::vector& specs,
const StatusParagraphs& status_db,
- const CreateInstallPlanOptions& options = {});
+ const CreateInstallPlanOptions& options = {Triplet{}});
ActionPlan create_upgrade_plan(const PortFileProvider::PortFileProvider& provider,
const CMakeVars::CMakeVarProvider& var_provider,
const std::vector& specs,
const StatusParagraphs& status_db,
- const CreateInstallPlanOptions& options = {});
+ const CreateInstallPlanOptions& options = {Triplet{}});
// `features` should have "default" instead of missing "core". This is only exposed for testing purposes.
std::vector resolve_deps_as_top_level(const SourceControlFile& scf,
Triplet triplet,
+ Triplet host_triplet,
std::vector features,
CMakeVars::CMakeVarProvider& var_provider);
- /// Contains the ports of the current environment.
- /// Feature specifications to resolve dependencies for.
- /// Status of installed packages in the current environment.
ExpectedS create_versioned_install_plan(const PortFileProvider::IVersionedPortfileProvider& vprovider,
const PortFileProvider::IBaselineProvider& bprovider,
const PortFileProvider::IOverlayProvider& oprovider,
const CMakeVars::CMakeVarProvider& var_provider,
const std::vector& deps,
const std::vector& overrides,
- const PackageSpec& toplevel);
+ const PackageSpec& toplevel,
+ Triplet host_triplet);
- void print_plan(const ActionPlan& action_plan, const bool is_recursive = true, const fs::path& vcpkg_root_dir = {});
+ void print_plan(const ActionPlan& action_plan,
+ const bool is_recursive = true,
+ const fs::path& builtin_ports_dir = {});
}
diff --git a/include/vcpkg/export.h b/include/vcpkg/export.h
index 0dd5b1aacd..f440fee0c0 100644
--- a/include/vcpkg/export.h
+++ b/include/vcpkg/export.h
@@ -14,6 +14,7 @@ namespace vcpkg::Export
{
virtual void perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const override;
+ Triplet default_triplet,
+ Triplet host_triplet) const override;
};
}
diff --git a/include/vcpkg/install.h b/include/vcpkg/install.h
index 8187735c5f..103a0b30a9 100644
--- a/include/vcpkg/install.h
+++ b/include/vcpkg/install.h
@@ -105,12 +105,16 @@ namespace vcpkg::Install
extern const CommandStructure COMMAND_STRUCTURE;
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet);
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet);
struct InstallCommand : Commands::TripletCommand
{
virtual void perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const override;
+ Triplet default_triplet,
+ Triplet host_triplet) const override;
};
}
diff --git a/include/vcpkg/packagespec.h b/include/vcpkg/packagespec.h
index 43be57e68c..44b1fbab36 100644
--- a/include/vcpkg/packagespec.h
+++ b/include/vcpkg/packagespec.h
@@ -149,10 +149,20 @@ namespace vcpkg
struct Dependency
{
+ // Remove when support for MSVC v140 is dropped.
+ Dependency(std::string n = {},
+ std::vector f = {},
+ PlatformExpression::Expr expr = {},
+ DependencyConstraint dc = {},
+ bool h = false)
+ : name(std::move(n)), features(std::move(f)), platform(std::move(expr)), constraint(std::move(dc)), host(h)
+ {
+ }
std::string name;
std::vector features;
PlatformExpression::Expr platform;
DependencyConstraint constraint;
+ bool host = false;
Json::Object extra_info;
diff --git a/include/vcpkg/remove.h b/include/vcpkg/remove.h
index faba3e3686..74e56aaba5 100644
--- a/include/vcpkg/remove.h
+++ b/include/vcpkg/remove.h
@@ -29,6 +29,7 @@ namespace vcpkg::Remove
{
virtual void perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const override;
+ Triplet default_triplet,
+ Triplet host_triplet) const override;
};
}
diff --git a/include/vcpkg/sourceparagraph.h b/include/vcpkg/sourceparagraph.h
index 52ce539808..a88252f83f 100644
--- a/include/vcpkg/sourceparagraph.h
+++ b/include/vcpkg/sourceparagraph.h
@@ -19,6 +19,7 @@ namespace vcpkg
{
std::vector filter_dependencies(const std::vector& deps,
Triplet t,
+ Triplet host,
const std::unordered_map& cmake_vars);
struct Type
@@ -71,7 +72,7 @@ namespace vcpkg
std::string license; // SPDX license expression
Optional builtin_baseline;
- Type type;
+ Type type = {Type::PORT};
PlatformExpression::Expr supports_expression;
Json::Object extra_info;
diff --git a/include/vcpkg/triplet.h b/include/vcpkg/triplet.h
index 40f6d6f236..21da0d5dad 100644
--- a/include/vcpkg/triplet.h
+++ b/include/vcpkg/triplet.h
@@ -38,6 +38,7 @@ namespace vcpkg
inline bool operator!=(Triplet left, Triplet right) { return !(left == right); }
Triplet default_triplet(const VcpkgCmdArguments& args);
+ Triplet default_host_triplet(const VcpkgCmdArguments& args);
}
namespace std
diff --git a/include/vcpkg/vcpkgcmdarguments.h b/include/vcpkg/vcpkgcmdarguments.h
index 14208e926b..5c8cba1a6f 100644
--- a/include/vcpkg/vcpkgcmdarguments.h
+++ b/include/vcpkg/vcpkgcmdarguments.h
@@ -143,6 +143,9 @@ namespace vcpkg
constexpr static StringLiteral TRIPLET_ENV = "VCPKG_DEFAULT_TRIPLET";
constexpr static StringLiteral TRIPLET_ARG = "triplet";
std::unique_ptr triplet;
+ constexpr static StringLiteral HOST_TRIPLET_ENV = "VCPKG_DEFAULT_HOST_TRIPLET";
+ constexpr static StringLiteral HOST_TRIPLET_ARG = "host-triplet";
+ std::unique_ptr host_triplet;
constexpr static StringLiteral OVERLAY_PORTS_ENV = "VCPKG_OVERLAY_PORTS";
constexpr static StringLiteral OVERLAY_PORTS_ARG = "overlay-ports";
std::vector overlay_ports;
diff --git a/src/vcpkg-test/binarycaching.cpp b/src/vcpkg-test/binarycaching.cpp
index 8a1a28d237..d4352d07e9 100644
--- a/src/vcpkg-test/binarycaching.cpp
+++ b/src/vcpkg-test/binarycaching.cpp
@@ -87,6 +87,7 @@ Build-Depends: bzip
Dependencies::InstallPlanAction ipa(PackageSpec{"zlib2", Test::X64_WINDOWS},
scfl,
Dependencies::RequestType::USER_REQUESTED,
+ Test::ARM_UWP,
{{"a", {}}, {"b", {}}});
ipa.abi_info = Build::AbiInfo{};
diff --git a/src/vcpkg-test/dependencies.cpp b/src/vcpkg-test/dependencies.cpp
index 696a3ee142..1861d7cecb 100644
--- a/src/vcpkg-test/dependencies.cpp
+++ b/src/vcpkg-test/dependencies.cpp
@@ -215,7 +215,23 @@ static ExpectedS create_versioned_install_plan(
const PackageSpec& toplevel)
{
return Dependencies::create_versioned_install_plan(
- provider, bprovider, s_empty_mock_overlay, var_provider, deps, overrides, toplevel);
+ provider, bprovider, s_empty_mock_overlay, var_provider, deps, overrides, toplevel, Test::ARM_UWP);
+}
+
+namespace vcpkg::Dependencies
+{
+ static ExpectedS create_versioned_install_plan(
+ const PortFileProvider::IVersionedPortfileProvider& provider,
+ const PortFileProvider::IBaselineProvider& bprovider,
+ const PortFileProvider::IOverlayProvider& oprovider,
+ const CMakeVars::CMakeVarProvider& var_provider,
+ const std::vector& deps,
+ const std::vector& overrides,
+ const PackageSpec& toplevel)
+ {
+ return vcpkg::Dependencies::create_versioned_install_plan(
+ provider, bprovider, oprovider, var_provider, deps, overrides, toplevel, Test::ARM_UWP);
+ }
}
TEST_CASE ("basic version install single", "[versionplan]")
@@ -1646,6 +1662,89 @@ TEST_CASE ("version install self features", "[versionplan]")
check_name_and_version(install_plan.install_actions[0], "a", {"1", 0}, {"x", "y"});
}
+static auto create_versioned_install_plan(MockVersionedPortfileProvider& vp,
+ MockBaselineProvider& bp,
+ std::vector deps)
+{
+ MockCMakeVarProvider var_provider;
+
+ return create_versioned_install_plan(vp, bp, var_provider, deps, {}, toplevel_spec());
+}
+
+TEST_CASE ("version install host tool", "[versionplan]")
+{
+ MockBaselineProvider bp;
+ bp.v["a"] = {"1", 0};
+ bp.v["b"] = {"1", 0};
+ bp.v["c"] = {"1", 0};
+ bp.v["d"] = {"1", 0};
+
+ MockVersionedPortfileProvider vp;
+ vp.emplace("a", {"1", 0});
+ auto& b_scf = vp.emplace("b", {"1", 0}).source_control_file;
+ b_scf->core_paragraph->dependencies.push_back(Dependency{"a", {}, {}, {}, true});
+ auto& c_scf = vp.emplace("c", {"1", 0}).source_control_file;
+ c_scf->core_paragraph->dependencies.push_back(Dependency{"a"});
+ auto& d_scf = vp.emplace("d", {"1", 0}).source_control_file;
+ d_scf->core_paragraph->dependencies.push_back(Dependency{"d", {}, {}, {}, true});
+
+ SECTION ("normal toplevel")
+ {
+ Dependency dep_c{"c"};
+
+ auto install_plan = unwrap(create_versioned_install_plan(vp, bp, {dep_c}));
+
+ REQUIRE(install_plan.size() == 2);
+ check_name_and_version(install_plan.install_actions[0], "a", {"1", 0});
+ REQUIRE(install_plan.install_actions[0].spec.triplet() == Test::X86_WINDOWS);
+ check_name_and_version(install_plan.install_actions[1], "c", {"1", 0});
+ REQUIRE(install_plan.install_actions[1].spec.triplet() == Test::X86_WINDOWS);
+ }
+ SECTION ("toplevel")
+ {
+ Dependency dep_a{"a"};
+ dep_a.host = true;
+
+ auto install_plan = unwrap(create_versioned_install_plan(vp, bp, {dep_a}));
+
+ REQUIRE(install_plan.size() == 1);
+ check_name_and_version(install_plan.install_actions[0], "a", {"1", 0});
+ REQUIRE(install_plan.install_actions[0].spec.triplet() == Test::ARM_UWP);
+ }
+ SECTION ("transitive 1")
+ {
+ auto install_plan = unwrap(create_versioned_install_plan(vp, bp, {{"b"}}));
+
+ REQUIRE(install_plan.size() == 2);
+ check_name_and_version(install_plan.install_actions[0], "a", {"1", 0});
+ REQUIRE(install_plan.install_actions[0].spec.triplet() == Test::ARM_UWP);
+ check_name_and_version(install_plan.install_actions[1], "b", {"1", 0});
+ REQUIRE(install_plan.install_actions[1].spec.triplet() == Test::X86_WINDOWS);
+ }
+ SECTION ("transitive 2")
+ {
+ Dependency dep_c{"c"};
+ dep_c.host = true;
+
+ auto install_plan = unwrap(create_versioned_install_plan(vp, bp, {dep_c}));
+
+ REQUIRE(install_plan.size() == 2);
+ check_name_and_version(install_plan.install_actions[0], "a", {"1", 0});
+ REQUIRE(install_plan.install_actions[0].spec.triplet() == Test::ARM_UWP);
+ check_name_and_version(install_plan.install_actions[1], "c", {"1", 0});
+ REQUIRE(install_plan.install_actions[1].spec.triplet() == Test::ARM_UWP);
+ }
+ SECTION ("self-reference")
+ {
+ auto install_plan = unwrap(create_versioned_install_plan(vp, bp, {{"d"}}));
+
+ REQUIRE(install_plan.size() == 2);
+ check_name_and_version(install_plan.install_actions[0], "d", {"1", 0});
+ REQUIRE(install_plan.install_actions[0].spec.triplet() == Test::ARM_UWP);
+ check_name_and_version(install_plan.install_actions[1], "d", {"1", 0});
+ REQUIRE(install_plan.install_actions[1].spec.triplet() == Test::X86_WINDOWS);
+ }
+}
TEST_CASE ("version overlay ports", "[versionplan]")
{
MockBaselineProvider bp;
diff --git a/src/vcpkg-test/manifests.cpp b/src/vcpkg-test/manifests.cpp
index bbbe0c96c5..8eee3f4959 100644
--- a/src/vcpkg-test/manifests.cpp
+++ b/src/vcpkg-test/manifests.cpp
@@ -609,6 +609,37 @@ TEST_CASE ("SourceParagraph manifest construct qualified dependencies", "[manife
REQUIRE(pgh.core_paragraph->dependencies[1].platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"}}));
}
+TEST_CASE ("SourceParagraph manifest construct host dependencies", "[manifests]")
+{
+ std::string raw = R"json({
+ "name": "zlib",
+ "version-string": "1.2.8",
+ "dependencies": [
+ {
+ "name": "liba",
+ "host": true
+ },
+ "libb"
+ ]
+}
+)json";
+ auto m_pgh = test_parse_manifest(raw);
+ REQUIRE(m_pgh.has_value());
+ auto& pgh = **m_pgh.get();
+
+ REQUIRE(pgh.core_paragraph->name == "zlib");
+ REQUIRE(pgh.core_paragraph->version == "1.2.8");
+ REQUIRE(pgh.core_paragraph->maintainers.empty());
+ REQUIRE(pgh.core_paragraph->description.empty());
+ REQUIRE(pgh.core_paragraph->dependencies.size() == 2);
+ REQUIRE(pgh.core_paragraph->dependencies[0].name == "liba");
+ REQUIRE(pgh.core_paragraph->dependencies[0].host);
+ REQUIRE(pgh.core_paragraph->dependencies[1].name == "libb");
+ REQUIRE(!pgh.core_paragraph->dependencies[1].host);
+
+ REQUIRE(Json::stringify(serialize_manifest(pgh), Json::JsonStyle::with_spaces(4)) == raw);
+}
+
TEST_CASE ("SourceParagraph manifest default features", "[manifests]")
{
auto m_pgh = test_parse_manifest(R"json({
diff --git a/src/vcpkg-test/paragraph.cpp b/src/vcpkg-test/paragraph.cpp
index cb3f8e6207..b44aaf50ab 100644
--- a/src/vcpkg-test/paragraph.cpp
+++ b/src/vcpkg-test/paragraph.cpp
@@ -242,7 +242,7 @@ TEST_CASE ("BinaryParagraph construct maximum", "[paragraph]")
REQUIRE(pgh.description.size() == 1);
REQUIRE(pgh.description[0] == "d");
REQUIRE(pgh.dependencies.size() == 1);
- REQUIRE(pgh.dependencies[0] == "bd");
+ REQUIRE(pgh.dependencies[0].name() == "bd");
}
TEST_CASE ("BinaryParagraph three dependencies", "[paragraph]")
@@ -256,9 +256,28 @@ TEST_CASE ("BinaryParagraph three dependencies", "[paragraph]")
});
REQUIRE(pgh.dependencies.size() == 3);
- REQUIRE(pgh.dependencies[0] == "a");
- REQUIRE(pgh.dependencies[1] == "b");
- REQUIRE(pgh.dependencies[2] == "c");
+ REQUIRE(pgh.dependencies[0].name() == "a");
+ REQUIRE(pgh.dependencies[1].name() == "b");
+ REQUIRE(pgh.dependencies[2].name() == "c");
+}
+
+TEST_CASE ("BinaryParagraph dependencies with triplets", "[paragraph]")
+{
+ auto pgh = test_make_binary_paragraph({
+ {"Package", "zlib"},
+ {"Version", "1.2.8"},
+ {"Architecture", "x86-windows"},
+ {"Multi-Arch", "same"},
+ {"Depends", "a:x64-windows, b, c:arm-uwp"},
+ });
+
+ REQUIRE(pgh.dependencies.size() == 3);
+ REQUIRE(pgh.dependencies[0].name() == "a");
+ REQUIRE(pgh.dependencies[0].triplet() == vcpkg::Test::X64_WINDOWS);
+ REQUIRE(pgh.dependencies[1].name() == "b");
+ REQUIRE(pgh.dependencies[1].triplet() == vcpkg::Test::X86_WINDOWS);
+ REQUIRE(pgh.dependencies[2].name() == "c");
+ REQUIRE(pgh.dependencies[2].triplet() == vcpkg::Test::ARM_UWP);
}
TEST_CASE ("BinaryParagraph abi", "[paragraph]")
@@ -484,18 +503,36 @@ TEST_CASE ("BinaryParagraph serialize max", "[paragraph]")
TEST_CASE ("BinaryParagraph serialize multiple deps", "[paragraph]")
{
- auto pgh = test_make_binary_paragraph({
- {"Package", "zlib"},
- {"Version", "1.2.8"},
- {"Architecture", "x86-windows"},
- {"Multi-Arch", "same"},
- {"Depends", "a, b, c"},
- });
- std::string ss = Strings::serialize(pgh);
- auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss, "").value_or_exit(VCPKG_LINE_INFO);
-
- REQUIRE(pghs.size() == 1);
- REQUIRE(pghs[0]["Depends"].first == "a, b, c");
+ SECTION ("target only")
+ {
+ auto pgh = test_make_binary_paragraph({
+ {"Package", "zlib"},
+ {"Version", "1.2.8"},
+ {"Architecture", "x86-windows"},
+ {"Multi-Arch", "same"},
+ {"Depends", "a, b, c"},
+ });
+ std::string ss = Strings::serialize(pgh);
+ auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss, "").value_or_exit(VCPKG_LINE_INFO);
+
+ REQUIRE(pghs.size() == 1);
+ REQUIRE(pghs[0]["Depends"].first == "a, b, c");
+ }
+ SECTION ("host deps")
+ {
+ auto pgh = test_make_binary_paragraph({
+ {"Package", "zlib"},
+ {"Version", "1.2.8"},
+ {"Architecture", "x86-windows"},
+ {"Multi-Arch", "same"},
+ {"Depends", "a:x64-windows, b, c:arm-uwp"},
+ });
+ std::string ss = Strings::serialize(pgh);
+ auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss, "").value_or_exit(VCPKG_LINE_INFO);
+
+ REQUIRE(pghs.size() == 1);
+ REQUIRE(pghs[0]["Depends"].first == "a:x64-windows, b, c:arm-uwp");
+ }
}
TEST_CASE ("BinaryParagraph serialize abi", "[paragraph]")
diff --git a/src/vcpkg-test/plan.cpp b/src/vcpkg-test/plan.cpp
index 363a2d9b46..74cdce868f 100644
--- a/src/vcpkg-test/plan.cpp
+++ b/src/vcpkg-test/plan.cpp
@@ -1066,6 +1066,159 @@ TEST_CASE ("features depend core remove scheme 2", "[plan]")
REQUIRE(remove_plan.at(0).spec.name() == "curl");
}
+TEST_CASE ("self-referencing scheme", "[plan]")
+{
+ PackageSpecMap spec_map;
+ auto spec_a = spec_map.emplace("a", "a");
+ auto spec_b = spec_map.emplace("b", "b, b (x64)");
+
+ PortFileProvider::MapPortFileProvider map_port(spec_map.map);
+ MockCMakeVarProvider var_provider;
+
+ SECTION ("basic")
+ {
+ auto install_plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {FullPackageSpec{spec_a, {}}}, {}, {{}, Test::X64_WINDOWS});
+
+ REQUIRE(install_plan.size() == 1);
+ REQUIRE(install_plan.install_actions.at(0).spec == spec_a);
+ }
+ SECTION ("qualified")
+ {
+ auto install_plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {FullPackageSpec{spec_b, {}}}, {}, {{}, Test::X64_WINDOWS});
+
+ REQUIRE(install_plan.size() == 1);
+ REQUIRE(install_plan.install_actions.at(0).spec == spec_b);
+ }
+}
+
+TEST_CASE ("basic tool port scheme", "[plan]")
+{
+ std::vector> status_paragraphs;
+
+ PackageSpecMap spec_map;
+ auto spec_a = spec_map.emplace("a", "b");
+ auto spec_b = spec_map.emplace("b", "c");
+ auto spec_c = spec_map.emplace("c");
+
+ spec_map.map.at("a").source_control_file->core_paragraph->dependencies[0].host = true;
+
+ PortFileProvider::MapPortFileProvider map_port(spec_map.map);
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan = Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {FullPackageSpec{spec_a, {}}},
+ StatusParagraphs(std::move(status_paragraphs)),
+ {{}, Test::X64_WINDOWS});
+
+ REQUIRE(install_plan.size() == 3);
+ REQUIRE(install_plan.install_actions.at(0).spec.name() == "c");
+ REQUIRE(install_plan.install_actions.at(0).spec.triplet() == Test::X64_WINDOWS);
+ REQUIRE(install_plan.install_actions.at(1).spec.name() == "b");
+ REQUIRE(install_plan.install_actions.at(1).spec.triplet() == Test::X64_WINDOWS);
+ REQUIRE(install_plan.install_actions.at(2).spec.name() == "a");
+}
+
+TEST_CASE ("basic existing tool port scheme", "[plan]")
+{
+ std::vector> pghs;
+ pghs.push_back(make_status_pgh("b", "", "", "x64-windows"));
+ StatusParagraphs status_db(std::move(pghs));
+ MockCMakeVarProvider var_provider;
+
+ SECTION ("a+b")
+ {
+ PackageSpecMap spec_map;
+ auto spec_a = spec_map.emplace("a", "b");
+ auto spec_b = spec_map.emplace("b");
+
+ spec_map.map.at("a").source_control_file->core_paragraph->dependencies[0].host = true;
+
+ PortFileProvider::MapPortFileProvider map_port(spec_map.map);
+
+ auto install_plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {FullPackageSpec{spec_a, {}}}, status_db, {{}, Test::X64_WINDOWS});
+
+ REQUIRE(install_plan.size() == 1);
+ REQUIRE(install_plan.install_actions.at(0).spec == spec_a);
+ }
+
+ SECTION ("a recurse")
+ {
+ PackageSpecMap spec_map;
+ auto spec_a = spec_map.emplace("a", "a");
+
+ spec_map.map.at("a").source_control_file->core_paragraph->dependencies[0].host = true;
+
+ PortFileProvider::MapPortFileProvider map_port(spec_map.map);
+
+ auto install_plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {FullPackageSpec{spec_a, {}}}, status_db, {{}, Test::X64_WINDOWS});
+
+ REQUIRE(install_plan.size() == 2);
+ REQUIRE(install_plan.install_actions.at(0).spec.name() == "a");
+ REQUIRE(install_plan.install_actions.at(0).spec.triplet() == Test::X64_WINDOWS);
+ REQUIRE(install_plan.install_actions.at(1).spec == spec_a);
+
+ install_plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {FullPackageSpec{spec_a, {}}}, status_db, {{}, Test::X86_WINDOWS});
+
+ REQUIRE(install_plan.size() == 1);
+ REQUIRE(install_plan.install_actions.at(0).spec == spec_a);
+ }
+
+ SECTION ("a+b (arm)")
+ {
+ PackageSpecMap spec_map;
+ auto spec_a = spec_map.emplace("a", "b");
+ auto spec_b = spec_map.emplace("b");
+
+ spec_map.map.at("a").source_control_file->core_paragraph->dependencies[0].host = true;
+
+ PortFileProvider::MapPortFileProvider map_port(spec_map.map);
+
+ auto install_plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {FullPackageSpec{spec_a, {}}}, status_db, {{}, Test::ARM_UWP});
+
+ REQUIRE(install_plan.size() == 2);
+ REQUIRE(install_plan.install_actions.at(0).spec.name() == "b");
+ REQUIRE(install_plan.install_actions.at(0).spec.triplet() == Test::ARM_UWP);
+ REQUIRE(install_plan.install_actions.at(1).spec == spec_a);
+ }
+
+ SECTION ("a+b+c")
+ {
+ PackageSpecMap spec_map;
+ auto spec_a = spec_map.emplace("a", "b");
+ auto spec_b = spec_map.emplace("b", "c");
+ auto spec_c = spec_map.emplace("c");
+
+ spec_map.map.at("a").source_control_file->core_paragraph->dependencies[0].host = true;
+
+ PortFileProvider::MapPortFileProvider map_port(spec_map.map);
+
+ auto install_plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {FullPackageSpec{spec_a, {}}}, status_db, {{}, Test::X64_WINDOWS});
+
+ REQUIRE(install_plan.size() == 1);
+ REQUIRE(install_plan.install_actions.at(0).spec == spec_a);
+ }
+}
+
+TEST_CASE ("remove tool port scheme", "[plan]")
+{
+ std::vector> pghs;
+ pghs.push_back(make_status_pgh("a"));
+ StatusParagraphs status_db(std::move(pghs));
+
+ auto remove_plan = Dependencies::create_remove_plan({{"a", Test::X86_WINDOWS}}, status_db);
+
+ REQUIRE(remove_plan.size() == 1);
+ REQUIRE(remove_plan.at(0).spec.name() == "a");
+}
+
TEST_CASE ("basic upgrade scheme", "[plan]")
{
std::vector> pghs;
diff --git a/src/vcpkg-test/versionplan.cpp b/src/vcpkg-test/versionplan.cpp
index 2f82d21b43..0d004ab632 100644
--- a/src/vcpkg-test/versionplan.cpp
+++ b/src/vcpkg-test/versionplan.cpp
@@ -34,12 +34,12 @@ TEST_CASE ("filter depends", "[dependencies]")
auto deps_ = parse_dependencies_list("liba (!uwp), libb, libc (uwp)");
REQUIRE(deps_);
auto& deps = *deps_.get();
- auto v = filter_dependencies(deps, Test::X64_WINDOWS, x64_win_cmake_vars);
+ auto v = filter_dependencies(deps, Test::X64_WINDOWS, Test::X86_WINDOWS, x64_win_cmake_vars);
REQUIRE(v.size() == 2);
REQUIRE(v.at(0).package_spec.name() == "liba");
REQUIRE(v.at(1).package_spec.name() == "libb");
- auto v2 = filter_dependencies(deps, Test::ARM_UWP, arm_uwp_cmake_vars);
+ auto v2 = filter_dependencies(deps, Test::ARM_UWP, Test::X86_WINDOWS, arm_uwp_cmake_vars);
REQUIRE(v.size() == 2);
REQUIRE(v2.at(0).package_spec.name() == "libb");
REQUIRE(v2.at(1).package_spec.name() == "libc");
@@ -95,6 +95,8 @@ TEST_CASE ("resolve_deps_as_top_level", "[dependencies]")
FullPackageSpec spec_b{spec_map.emplace("b", "", {{"b1", ""}}), {}};
FullPackageSpec spec_c{spec_map.emplace("c", "b", {{"c1", "b[b1]"}, {"c2", "c[c1], a"}}, {"c1"}), {"core"}};
FullPackageSpec spec_d{spec_map.emplace("d", "c[core]"), {}};
+ FullPackageSpec spec_e{spec_map.emplace("e", "c[core]"), {}};
+ spec_map.map.at("e").source_control_file->core_paragraph->dependencies[0].host = true;
PortFileProvider::MapPortFileProvider map_port{spec_map.map};
MockCMakeVarProvider var_provider;
@@ -102,20 +104,20 @@ TEST_CASE ("resolve_deps_as_top_level", "[dependencies]")
var_provider.dep_info_vars[{"a", t_linux}].emplace("VCPKG_CMAKE_SYSTEM_NAME", "Linux");
{
auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("a").source_control_file, Test::X86_WINDOWS, {}, var_provider);
+ *spec_map.map.at("a").source_control_file, Test::X86_WINDOWS, Test::ARM_UWP, {}, var_provider);
REQUIRE(deps.size() == 1);
REQUIRE(deps.at(0) == spec_b);
}
{
auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("a").source_control_file, t_linux, {}, var_provider);
+ *spec_map.map.at("a").source_control_file, t_linux, Test::ARM_UWP, {}, var_provider);
REQUIRE(deps.size() == 1);
REQUIRE(deps.at(0) == FullPackageSpec({"b", t_linux}, {"b1"}));
}
{
// without defaults
auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("c").source_control_file, Test::X86_WINDOWS, {}, var_provider);
+ *spec_map.map.at("c").source_control_file, Test::X86_WINDOWS, Test::ARM_UWP, {}, var_provider);
REQUIRE(deps.size() == 1);
REQUIRE(deps.at(0) == spec_b);
}
@@ -123,21 +125,21 @@ TEST_CASE ("resolve_deps_as_top_level", "[dependencies]")
{
// with defaults of c (c1)
auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("c").source_control_file, Test::X86_WINDOWS, {"default"}, var_provider);
+ *spec_map.map.at("c").source_control_file, Test::X86_WINDOWS, Test::ARM_UWP, {"default"}, var_provider);
REQUIRE(deps.size() == 1);
REQUIRE(deps.at(0) == spec_b_with_b1);
}
{
// with c1
auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("c").source_control_file, Test::X86_WINDOWS, {"c1"}, var_provider);
+ *spec_map.map.at("c").source_control_file, Test::X86_WINDOWS, Test::ARM_UWP, {"c1"}, var_provider);
REQUIRE(deps.size() == 1);
REQUIRE(deps.at(0) == spec_b_with_b1);
}
{
// with c2 implying c1
auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("c").source_control_file, Test::X86_WINDOWS, {"c2"}, var_provider);
+ *spec_map.map.at("c").source_control_file, Test::X86_WINDOWS, Test::ARM_UWP, {"c2"}, var_provider);
REQUIRE(deps.size() == 2);
REQUIRE(deps.at(0) == spec_a);
REQUIRE(deps.at(1) == spec_b_with_b1);
@@ -145,8 +147,17 @@ TEST_CASE ("resolve_deps_as_top_level", "[dependencies]")
{
// d -> c[core]
auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
- *spec_map.map.at("d").source_control_file, Test::X86_WINDOWS, {}, var_provider);
+ *spec_map.map.at("d").source_control_file, Test::X86_WINDOWS, Test::ARM_UWP, {}, var_provider);
REQUIRE(deps.size() == 1);
REQUIRE(deps.at(0) == spec_c);
}
+ SECTION ("host dep")
+ {
+ // e -> c[core]:$host
+ auto deps = vcpkg::Dependencies::resolve_deps_as_top_level(
+ *spec_map.map.at("e").source_control_file, Test::X86_WINDOWS, Test::ARM_UWP, {}, var_provider);
+ REQUIRE(deps.size() == 1);
+ REQUIRE(deps.at(0).package_spec.name() == "c");
+ REQUIRE(deps.at(0).package_spec.triplet() == Test::ARM_UWP);
+ }
}
diff --git a/src/vcpkg.cpp b/src/vcpkg.cpp
index f25a0c3b60..3e4dd000b0 100644
--- a/src/vcpkg.cpp
+++ b/src/vcpkg.cpp
@@ -87,10 +87,12 @@ static void inner(vcpkg::Files::Filesystem& fs, const VcpkgCmdArguments& args)
Triplet default_triplet = vcpkg::default_triplet(args);
Input::check_triplet(default_triplet, paths);
+ Triplet host_triplet = vcpkg::default_host_triplet(args);
+ Input::check_triplet(host_triplet, paths);
if (const auto command_function = find_command(Commands::get_available_triplet_commands()))
{
- return command_function->function->perform_and_exit(args, paths, default_triplet);
+ return command_function->function->perform_and_exit(args, paths, default_triplet, host_triplet);
}
return invalid_command(args.command);
diff --git a/src/vcpkg/binaryparagraph.cpp b/src/vcpkg/binaryparagraph.cpp
index d30fd47516..b22d9faca8 100644
--- a/src/vcpkg/binaryparagraph.cpp
+++ b/src/vcpkg/binaryparagraph.cpp
@@ -71,11 +71,16 @@ namespace vcpkg
std::string multi_arch;
parser.required_field(Fields::MULTI_ARCH, multi_arch);
+ Triplet my_triplet = this->spec.triplet();
this->dependencies = Util::fmap(
parse_qualified_specifier_list(parser.optional_field(Fields::DEPENDS)).value_or_exit(VCPKG_LINE_INFO),
- [](const ParsedQualifiedSpecifier& dep) {
+ [my_triplet](const ParsedQualifiedSpecifier& dep) {
// for compatibility with previous vcpkg versions, we discard all irrelevant information
- return dep.name;
+ return PackageSpec{
+ dep.name,
+ dep.triplet.map([](auto&& s) { return Triplet::from_canonical_name(std::string(s)); })
+ .value_or(my_triplet),
+ };
});
if (!this->is_feature())
{
@@ -113,7 +118,7 @@ namespace vcpkg
, abi(abi_tag)
, type(spgh.type)
{
- this->dependencies = Util::fmap(deps, [](const FeatureSpec& spec) { return spec.spec().name(); });
+ this->dependencies = Util::fmap(deps, [](const FeatureSpec& spec) { return spec.spec(); });
canonicalize();
}
@@ -132,7 +137,7 @@ namespace vcpkg
, abi()
, type(spgh.type)
{
- this->dependencies = Util::fmap(deps, [](const FeatureSpec& spec) { return spec.spec().name(); });
+ this->dependencies = Util::fmap(deps, [](const FeatureSpec& spec) { return spec.spec(); });
canonicalize();
}
@@ -223,6 +228,20 @@ namespace vcpkg
serialize_array(name, array, out_str, "\n ");
}
+ static std::string serialize_deps_list(View deps, Triplet target)
+ {
+ return Strings::join(", ", deps, [target](const PackageSpec& pspec) {
+ if (pspec.triplet() == target)
+ {
+ return pspec.name();
+ }
+ else
+ {
+ return pspec.to_string();
+ }
+ });
+ }
+
void serialize(const BinaryParagraph& pgh, std::string& out_str)
{
const size_t initial_end = out_str.size();
@@ -242,7 +261,7 @@ namespace vcpkg
if (!pgh.dependencies.empty())
{
- serialize_array(Fields::DEPENDS, pgh.dependencies, out_str);
+ serialize_string(Fields::DEPENDS, serialize_deps_list(pgh.dependencies, pgh.spec.triplet()), out_str);
}
serialize_string(Fields::ARCHITECTURE, pgh.spec.triplet().to_string(), out_str);
diff --git a/src/vcpkg/build.cpp b/src/vcpkg/build.cpp
index b38062f0c9..0b5ae8420d 100644
--- a/src/vcpkg/build.cpp
+++ b/src/vcpkg/build.cpp
@@ -59,14 +59,16 @@ namespace vcpkg::Build
void Command::perform_and_exit_ex(const VcpkgCmdArguments& args,
const FullPackageSpec& full_spec,
+ Triplet host_triplet,
const SourceControlFileLocation& scfl,
const PathsPortFileProvider& provider,
IBinaryProvider& binaryprovider,
const IBuildLogsRecorder& build_logs_recorder,
const VcpkgPaths& paths)
{
- Checks::exit_with_code(VCPKG_LINE_INFO,
- perform_ex(args, full_spec, scfl, provider, binaryprovider, build_logs_recorder, paths));
+ Checks::exit_with_code(
+ VCPKG_LINE_INFO,
+ perform_ex(args, full_spec, host_triplet, scfl, provider, binaryprovider, build_logs_recorder, paths));
}
const CommandStructure COMMAND_STRUCTURE = {
@@ -77,13 +79,17 @@ namespace vcpkg::Build
nullptr,
};
- void Command::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
+ void Command::perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet)
{
- Checks::exit_with_code(VCPKG_LINE_INFO, perform(args, paths, default_triplet));
+ Checks::exit_with_code(VCPKG_LINE_INFO, perform(args, paths, default_triplet, host_triplet));
}
int Command::perform_ex(const VcpkgCmdArguments& args,
const FullPackageSpec& full_spec,
+ Triplet host_triplet,
const SourceControlFileLocation& scfl,
const PathsPortFileProvider& provider,
IBinaryProvider& binaryprovider,
@@ -97,7 +103,7 @@ namespace vcpkg::Build
StatusParagraphs status_db = database_load_check(paths);
auto action_plan = Dependencies::create_feature_install_plan(
- provider, var_provider, std::vector{full_spec}, status_db);
+ provider, var_provider, std::vector{full_spec}, status_db, {host_triplet});
var_provider.load_tag_vars(action_plan, provider);
@@ -165,7 +171,10 @@ namespace vcpkg::Build
return 0;
}
- int Command::perform(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
+ int Command::perform(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet)
{
// Build only takes a single package and all dependencies must already be installed
const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
@@ -187,6 +196,7 @@ namespace vcpkg::Build
return perform_ex(args,
spec,
+ host_triplet,
*scfl,
provider,
args.binary_caching_enabled() ? *binaryprovider : null_binary_provider(),
@@ -196,9 +206,10 @@ namespace vcpkg::Build
void BuildCommand::perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const
+ Triplet default_triplet,
+ Triplet host_triplet) const
{
- Build::Command::perform_and_exit(args, paths, default_triplet);
+ Build::Command::perform_and_exit(args, paths, default_triplet, host_triplet);
}
}
@@ -573,6 +584,8 @@ namespace vcpkg::Build
{"CURRENT_PORT_DIR", paths.scripts / "detect_compiler"},
{"CURRENT_BUILDTREES_DIR", buildpath},
{"CURRENT_PACKAGES_DIR", paths.packages / ("detect_compiler_" + triplet.canonical_name())},
+ // The detect_compiler "port" doesn't depend on the host triplet, so always natively compile
+ {"_HOST_TRIPLET", triplet.canonical_name()},
};
get_generic_cmake_build_args(paths, triplet, abi_info.toolset.value_or_exit(VCPKG_LINE_INFO), cmake_args);
@@ -645,8 +658,7 @@ namespace vcpkg::Build
static std::vector get_cmake_build_args(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- const Dependencies::InstallPlanAction& action,
- Triplet triplet)
+ const Dependencies::InstallPlanAction& action)
{
#if !defined(_WIN32)
// TODO: remove when vcpkg.exe is in charge for acquiring tools. Change introduced in vcpkg v0.0.107.
@@ -665,6 +677,7 @@ namespace vcpkg::Build
std::vector variables{
{"ALL_FEATURES", all_features},
{"CURRENT_PORT_DIR", scfl.source_location},
+ {"_HOST_TRIPLET", action.host_triplet.canonical_name()},
{"FEATURES", Strings::join(";", action.feature_list)},
{"PORT", scf.core_paragraph->name},
{"VCPKG_USE_HEAD_VERSION", Util::Enum::to_bool(action.build_options.use_head_version) ? "1" : "0"},
@@ -685,7 +698,7 @@ namespace vcpkg::Build
get_generic_cmake_build_args(
paths,
- triplet,
+ action.spec.triplet(),
action.abi_info.value_or_exit(VCPKG_LINE_INFO).toolset.value_or_exit(VCPKG_LINE_INFO),
variables);
@@ -803,8 +816,7 @@ namespace vcpkg::Build
const auto timer = Chrono::ElapsedTimer::create_started();
- auto command =
- vcpkg::make_cmake_cmd(paths, paths.ports_cmake, get_cmake_build_args(args, paths, action, triplet));
+ auto command = vcpkg::make_cmake_cmd(paths, paths.ports_cmake, get_cmake_build_args(args, paths, action));
const auto& env = paths.get_action_env(action.abi_info.value_or_exit(VCPKG_LINE_INFO));
diff --git a/src/vcpkg/buildenvironment.cpp b/src/vcpkg/buildenvironment.cpp
index bc116f4f3c..c86aa93d21 100644
--- a/src/vcpkg/buildenvironment.cpp
+++ b/src/vcpkg/buildenvironment.cpp
@@ -1,5 +1,6 @@
#include
#include
+#include
#include
namespace vcpkg
diff --git a/src/vcpkg/commands.buildexternal.cpp b/src/vcpkg/commands.buildexternal.cpp
index 65b1ec8230..dbaf41e426 100644
--- a/src/vcpkg/commands.buildexternal.cpp
+++ b/src/vcpkg/commands.buildexternal.cpp
@@ -17,7 +17,10 @@ namespace vcpkg::Commands::BuildExternal
nullptr,
};
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet)
{
const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
@@ -38,6 +41,7 @@ namespace vcpkg::Commands::BuildExternal
Build::Command::perform_and_exit_ex(args,
spec,
+ host_triplet,
maybe_scfl.value_or_exit(VCPKG_LINE_INFO),
provider,
args.binary_caching_enabled() ? *binaryprovider : null_binary_provider(),
@@ -47,8 +51,9 @@ namespace vcpkg::Commands::BuildExternal
void BuildExternalCommand::perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const
+ Triplet default_triplet,
+ Triplet host_triplet) const
{
- BuildExternal::perform_and_exit(args, paths, default_triplet);
+ BuildExternal::perform_and_exit(args, paths, default_triplet, host_triplet);
}
}
diff --git a/src/vcpkg/commands.ci.cpp b/src/vcpkg/commands.ci.cpp
index 26ae058add..0424ff7a27 100644
--- a/src/vcpkg/commands.ci.cpp
+++ b/src/vcpkg/commands.ci.cpp
@@ -2,6 +2,7 @@
#include
#include
#include
+#include
#include
#include
@@ -65,7 +66,8 @@ namespace
{
for (const fs::path& p : children)
{
- filesystem.copy_file(p, target_path / p.filename(), fs::copy_options::none, VCPKG_LINE_INFO);
+ filesystem.copy_file(
+ p, target_path / p.filename(), fs::copy_options::overwrite_existing, VCPKG_LINE_INFO);
}
}
}
@@ -292,7 +294,8 @@ namespace vcpkg::Commands::CI
const PortFileProvider::PortFileProvider& provider,
const CMakeVars::CMakeVarProvider& var_provider,
const std::vector& specs,
- IBinaryProvider& binaryprovider)
+ IBinaryProvider& binaryprovider,
+ const Dependencies::CreateInstallPlanOptions& serialize_options)
{
auto ret = std::make_unique();
@@ -312,7 +315,8 @@ namespace vcpkg::Commands::CI
}
var_provider.load_dep_info_vars(packages_with_qualified_deps);
- auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, {}, {});
+ auto action_plan =
+ Dependencies::create_feature_install_plan(provider, var_provider, specs, {}, serialize_options);
std::vector install_specs;
for (auto&& install_action : action_plan.install_actions)
@@ -419,7 +423,10 @@ namespace vcpkg::Commands::CI
return ret;
}
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet)
{
std::unique_ptr binaryproviderStorage;
if (args.binary_caching_enabled())
@@ -496,7 +503,7 @@ namespace vcpkg::Commands::CI
return FullPackageSpec{spec, std::move(default_features)};
});
- Dependencies::CreateInstallPlanOptions serialize_options;
+ Dependencies::CreateInstallPlanOptions serialize_options(host_triplet);
struct RandomizerInstance : Graphs::Randomizer
{
@@ -515,8 +522,13 @@ namespace vcpkg::Commands::CI
serialize_options.randomizer = &randomizer_instance;
}
- auto split_specs = find_unknown_ports_for_ci(
- paths, exclusions_set, provider, var_provider, all_default_full_specs, binaryprovider);
+ auto split_specs = find_unknown_ports_for_ci(paths,
+ exclusions_set,
+ provider,
+ var_provider,
+ all_default_full_specs,
+ binaryprovider,
+ serialize_options);
auto& action_plan = split_specs->plan;
@@ -599,8 +611,9 @@ namespace vcpkg::Commands::CI
void CICommand::perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const
+ Triplet default_triplet,
+ Triplet host_triplet) const
{
- CI::perform_and_exit(args, paths, default_triplet);
+ CI::perform_and_exit(args, paths, default_triplet, host_triplet);
}
}
diff --git a/src/vcpkg/commands.dependinfo.cpp b/src/vcpkg/commands.dependinfo.cpp
index bfd719df08..bade947902 100644
--- a/src/vcpkg/commands.dependinfo.cpp
+++ b/src/vcpkg/commands.dependinfo.cpp
@@ -237,7 +237,10 @@ namespace vcpkg::Commands::DependInfo
nullptr,
};
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet)
{
const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
const int max_depth = get_max_depth(options);
@@ -261,7 +264,8 @@ namespace vcpkg::Commands::DependInfo
// By passing an empty status_db, we should get a plan containing all dependencies.
// All actions in the plan should be install actions, as there's no installed packages to remove.
StatusParagraphs status_db;
- auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, status_db);
+ auto action_plan =
+ Dependencies::create_feature_install_plan(provider, var_provider, specs, status_db, {host_triplet});
Checks::check_exit(
VCPKG_LINE_INFO, action_plan.remove_actions.empty(), "Only install actions should exist in the plan");
std::vector install_actions =
@@ -332,8 +336,9 @@ namespace vcpkg::Commands::DependInfo
void DependInfoCommand::perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const
+ Triplet default_triplet,
+ Triplet host_triplet) const
{
- DependInfo::perform_and_exit(args, paths, default_triplet);
+ DependInfo::perform_and_exit(args, paths, default_triplet, host_triplet);
}
}
diff --git a/src/vcpkg/commands.env.cpp b/src/vcpkg/commands.env.cpp
index f129f02626..cc92bcea13 100644
--- a/src/vcpkg/commands.env.cpp
+++ b/src/vcpkg/commands.env.cpp
@@ -33,7 +33,10 @@ namespace vcpkg::Commands::Env
};
// This command should probably optionally take a port
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet triplet)
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet triplet,
+ Triplet /*host_triplet*/)
{
const auto& fs = paths.get_filesystem();
@@ -115,8 +118,9 @@ namespace vcpkg::Commands::Env
void EnvCommand::perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const
+ Triplet default_triplet,
+ Triplet host_triplet) const
{
- Env::perform_and_exit(args, paths, default_triplet);
+ Env::perform_and_exit(args, paths, default_triplet, host_triplet);
}
}
diff --git a/src/vcpkg/commands.setinstalled.cpp b/src/vcpkg/commands.setinstalled.cpp
index 28eee6992a..5b24d52a06 100644
--- a/src/vcpkg/commands.setinstalled.cpp
+++ b/src/vcpkg/commands.setinstalled.cpp
@@ -117,7 +117,10 @@ namespace vcpkg::Commands::SetInstalled
Checks::exit_success(VCPKG_LINE_INFO);
}
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet)
{
// input sanitization
const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
@@ -150,7 +153,7 @@ namespace vcpkg::Commands::SetInstalled
// We have a set of user-requested specs.
// We need to know all the specs which are required to fulfill dependencies for those specs.
// Therefore, we see what we would install into an empty installed tree, so we can use the existing code.
- auto action_plan = Dependencies::create_feature_install_plan(provider, *cmake_vars, specs, {});
+ auto action_plan = Dependencies::create_feature_install_plan(provider, *cmake_vars, specs, {}, {host_triplet});
for (auto&& action : action_plan.install_actions)
{
@@ -169,8 +172,9 @@ namespace vcpkg::Commands::SetInstalled
void SetInstalledCommand::perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const
+ Triplet default_triplet,
+ Triplet host_triplet) const
{
- SetInstalled::perform_and_exit(args, paths, default_triplet);
+ SetInstalled::perform_and_exit(args, paths, default_triplet, host_triplet);
}
}
diff --git a/src/vcpkg/commands.upgrade.cpp b/src/vcpkg/commands.upgrade.cpp
index 2d25be4550..535f1f5057 100644
--- a/src/vcpkg/commands.upgrade.cpp
+++ b/src/vcpkg/commands.upgrade.cpp
@@ -36,7 +36,10 @@ namespace vcpkg::Commands::Upgrade
nullptr,
};
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet)
{
const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
@@ -78,7 +81,8 @@ namespace vcpkg::Commands::Upgrade
provider,
var_provider,
Util::fmap(outdated_packages, [](const Update::OutdatedPackage& package) { return package.spec; }),
- status_db);
+ status_db,
+ {host_triplet});
}
else
{
@@ -158,7 +162,8 @@ namespace vcpkg::Commands::Upgrade
if (to_upgrade.empty()) Checks::exit_success(VCPKG_LINE_INFO);
- action_plan = Dependencies::create_upgrade_plan(provider, var_provider, to_upgrade, status_db);
+ action_plan =
+ Dependencies::create_upgrade_plan(provider, var_provider, to_upgrade, status_db, {host_triplet});
}
Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty());
@@ -203,8 +208,9 @@ namespace vcpkg::Commands::Upgrade
void UpgradeCommand::perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const
+ Triplet default_triplet,
+ Triplet host_triplet) const
{
- Upgrade::perform_and_exit(args, paths, default_triplet);
+ Upgrade::perform_and_exit(args, paths, default_triplet, host_triplet);
}
}
diff --git a/src/vcpkg/dependencies.cpp b/src/vcpkg/dependencies.cpp
index f52b4b7095..3d33816ca5 100644
--- a/src/vcpkg/dependencies.cpp
+++ b/src/vcpkg/dependencies.cpp
@@ -16,6 +16,8 @@ using namespace vcpkg;
namespace vcpkg::Dependencies
{
+ struct ClusterGraph;
+
namespace
{
struct ClusterInstalled
@@ -82,7 +84,8 @@ namespace vcpkg::Dependencies
// Precondition: must have called "mark_for_reinstall()" or "create_install_info()" on this cluster
void add_feature(const std::string& feature,
const CMakeVars::CMakeVarProvider& var_provider,
- std::vector& out_new_dependencies)
+ std::vector& out_new_dependencies,
+ Triplet host_triplet)
{
ClusterInstallInfo& info = m_install_info.value_or_exit(VCPKG_LINE_INFO);
if (feature == "default")
@@ -110,7 +113,7 @@ namespace vcpkg::Dependencies
if (auto vars = maybe_vars.get())
{
// Qualified dependency resolution is available
- auto fullspec_list = filter_dependencies(*qualified_deps, m_spec.triplet(), *vars);
+ auto fullspec_list = filter_dependencies(*qualified_deps, m_spec.triplet(), host_triplet, *vars);
for (auto&& fspec : fullspec_list)
{
@@ -127,8 +130,9 @@ namespace vcpkg::Dependencies
{
if (dep.platform.is_empty())
{
+ auto t = dep.host ? host_triplet : m_spec.triplet();
Util::Vectors::append(&dep_list,
- FullPackageSpec({dep.name, m_spec.triplet()}, dep.features)
+ FullPackageSpec({dep.name, t}, dep.features)
.to_feature_specs({"default"}, {"default"}));
}
else
@@ -137,11 +141,17 @@ namespace vcpkg::Dependencies
}
}
Util::sort_unique_erase(dep_list);
- if (!requires_qualified_resolution)
+ if (requires_qualified_resolution)
+ {
+ auto my_spec = this->m_spec;
+ Util::erase_remove_if(dep_list, [my_spec](FeatureSpec& f) { return f.spec() == my_spec; });
+ }
+ else
{
info.build_edges.emplace(feature, dep_list);
}
}
+
Util::Vectors::append(&out_new_dependencies, dep_list);
}
@@ -223,14 +233,15 @@ namespace vcpkg::Dependencies
{
PackageGraph(const PortFileProvider::PortFileProvider& provider,
const CMakeVars::CMakeVarProvider& var_provider,
- const StatusParagraphs& status_db);
+ const StatusParagraphs& status_db,
+ Triplet host_triplet);
~PackageGraph();
void install(Span specs);
void upgrade(Span specs);
void mark_user_requested(const PackageSpec& spec);
- ActionPlan serialize(const CreateInstallPlanOptions& options = {}) const;
+ ActionPlan serialize(Graphs::Randomizer* randomizer) const;
void mark_for_reinstall(const PackageSpec& spec, std::vector& out_reinstall_requirements);
const CMakeVars::CMakeVarProvider& m_var_provider;
@@ -243,9 +254,10 @@ namespace vcpkg::Dependencies
///
/// Directional graph representing a collection of packages with their features connected by their dependencies.
///
- struct ClusterGraph : Util::MoveOnlyBase
+ struct ClusterGraph : Util::ResourceBase
{
- explicit ClusterGraph(const PortFileProvider::PortFileProvider& port_provider) : m_port_provider(port_provider)
+ explicit ClusterGraph(const PortFileProvider::PortFileProvider& port_provider, Triplet host_triplet)
+ : m_port_provider(port_provider), m_host_triplet(host_triplet)
{
}
@@ -261,45 +273,48 @@ namespace vcpkg::Dependencies
{
const SourceControlFileLocation* scfl = m_port_provider.get_control_file(spec.name()).get();
- Checks::check_maybe_upgrade(
- VCPKG_LINE_INFO, scfl, "Error: Cannot find definition for package `%s`.", spec.name());
+ Checks::check_exit(VCPKG_LINE_INFO,
+ scfl,
+ "Error: Cannot find definition for package `%s` while getting `%s`.",
+ spec.name(),
+ spec);
- return m_graph
- .emplace(std::piecewise_construct, std::forward_as_tuple(spec), std::forward_as_tuple(spec, *scfl))
- .first->second;
+ it = m_graph
+ .emplace(
+ std::piecewise_construct, std::forward_as_tuple(spec), std::forward_as_tuple(spec, *scfl))
+ .first;
}
return it->second;
}
- Cluster& get(const InstalledPackageView& ipv)
+ Cluster& insert(const InstalledPackageView& ipv)
{
- auto it = m_graph.find(ipv.spec());
-
- if (it == m_graph.end())
- {
- ExpectedS maybe_scfl =
- m_port_provider.get_control_file(ipv.spec().name());
+ ExpectedS maybe_scfl =
+ m_port_provider.get_control_file(ipv.spec().name());
- return m_graph
- .emplace(std::piecewise_construct,
- std::forward_as_tuple(ipv.spec()),
- std::forward_as_tuple(ipv, std::move(maybe_scfl)))
- .first->second;
- }
-
- if (!it->second.m_installed)
+ if (maybe_scfl.has_value())
{
- it->second.m_installed = {ipv};
+ Checks::check_exit(VCPKG_LINE_INFO,
+ maybe_scfl.get()->source_control_file->core_paragraph->type.type ==
+ ipv.core->package.type.type,
+ "Error: the port type of '%s' differs between the installed and available "
+ "portfile.\nPlease manually remove '%s' and re-run this command.",
+ ipv.spec().name(),
+ ipv.spec());
}
- return it->second;
+ return m_graph
+ .emplace(std::piecewise_construct,
+ std::forward_as_tuple(ipv.spec()),
+ std::forward_as_tuple(ipv, std::move(maybe_scfl)))
+ .first->second;
}
const Cluster& find_or_exit(const PackageSpec& spec, LineInfo linfo) const
{
auto it = m_graph.find(spec);
- Checks::check_maybe_upgrade(linfo, it != m_graph.end(), "Failed to locate spec in graph");
+ Checks::check_exit(linfo, it != m_graph.end(), "Failed to locate spec in graph: %s", spec);
return it->second;
}
@@ -309,6 +324,9 @@ namespace vcpkg::Dependencies
private:
std::map m_graph;
const PortFileProvider::PortFileProvider& m_port_provider;
+
+ public:
+ const Triplet m_host_triplet;
};
static std::string to_output_string(RequestType request_type,
@@ -370,6 +388,7 @@ namespace vcpkg::Dependencies
InstallPlanAction::InstallPlanAction(const PackageSpec& spec,
const SourceControlFileLocation& scfl,
const RequestType& request_type,
+ Triplet host_triplet,
std::map>&& dependencies)
: spec(spec)
, source_control_file_location(scfl)
@@ -377,6 +396,7 @@ namespace vcpkg::Dependencies
, request_type(request_type)
, build_options{}
, feature_dependencies(std::move(dependencies))
+ , host_triplet(host_triplet)
{
for (const auto& kv : feature_dependencies)
{
@@ -626,11 +646,12 @@ namespace vcpkg::Dependencies
// `features` should have "default" instead of missing "core"
std::vector resolve_deps_as_top_level(const SourceControlFile& scf,
Triplet triplet,
+ Triplet host_triplet,
std::vector features,
CMakeVars::CMakeVarProvider& var_provider)
{
PackageSpec spec{scf.core_paragraph->name, triplet};
- std::map> specs_to_features;
+ std::map> specs_to_features;
Optional ctx_storage = var_provider.get_dep_info_vars(spec);
auto ctx = [&]() -> const PlatformExpression::Context& {
@@ -650,7 +671,10 @@ namespace vcpkg::Dependencies
if (dep.name == spec.name())
Util::Vectors::append(&features, dep.features);
else
- Util::Vectors::append(&specs_to_features[dep.name], dep.features);
+ {
+ auto t = dep.host ? host_triplet : triplet;
+ Util::Vectors::append(&specs_to_features[{dep.name, t}], dep.features);
+ }
}
}
};
@@ -682,8 +706,8 @@ namespace vcpkg::Dependencies
if (it != scf.feature_paragraphs.end()) handle_deps(it->get()->dependencies);
}
}
- return Util::fmap(specs_to_features, [triplet](std::pair>& p) {
- return FullPackageSpec({p.first, triplet}, Util::sort_unique_erase(std::move(p.second)));
+ return Util::fmap(specs_to_features, [](std::pair>& p) {
+ return FullPackageSpec(p.first, Util::sort_unique_erase(std::move(p.second)));
});
}
@@ -693,7 +717,7 @@ namespace vcpkg::Dependencies
const StatusParagraphs& status_db,
const CreateInstallPlanOptions& options)
{
- PackageGraph pgraph(port_provider, var_provider, status_db);
+ PackageGraph pgraph(port_provider, var_provider, status_db, options.host_triplet);
std::vector feature_specs;
for (const FullPackageSpec& spec : specs)
@@ -725,7 +749,7 @@ namespace vcpkg::Dependencies
}
pgraph.install(feature_specs);
- auto res = pgraph.serialize(options);
+ auto res = pgraph.serialize(options.randomizer);
return res;
}
@@ -775,6 +799,7 @@ namespace vcpkg::Dependencies
// Get the cluster for the PackageSpec of the FeatureSpec we are adding to the install graph
Cluster& clust = m_graph->get(spec.spec());
+ spec = FeatureSpec{clust.m_spec, spec.feature()};
// If this spec hasn't already had its qualified dependencies resolved
if (!m_var_provider.get_dep_info_vars(spec.spec()).has_value())
@@ -812,14 +837,14 @@ namespace vcpkg::Dependencies
if (clust.m_install_info.has_value())
{
- clust.add_feature(spec.feature(), m_var_provider, next_dependencies);
+ clust.add_feature(spec.feature(), m_var_provider, next_dependencies, m_graph->m_host_triplet);
}
else
{
if (!clust.m_installed.has_value())
{
clust.create_install_info(next_dependencies);
- clust.add_feature(spec.feature(), m_var_provider, next_dependencies);
+ clust.add_feature(spec.feature(), m_var_provider, next_dependencies, m_graph->m_host_triplet);
}
else
{
@@ -840,7 +865,8 @@ namespace vcpkg::Dependencies
// which hasn't already been installed to this cluster. In this case, we need to reinstall
// the port if the feature isn't already present.
mark_for_reinstall(spec.spec(), next_dependencies);
- clust.add_feature(spec.feature(), m_var_provider, next_dependencies);
+ clust.add_feature(
+ spec.feature(), m_var_provider, next_dependencies, m_graph->m_host_triplet);
}
}
}
@@ -885,14 +911,14 @@ namespace vcpkg::Dependencies
const StatusParagraphs& status_db,
const CreateInstallPlanOptions& options)
{
- PackageGraph pgraph(port_provider, var_provider, status_db);
+ PackageGraph pgraph(port_provider, var_provider, status_db, options.host_triplet);
pgraph.upgrade(specs);
- return pgraph.serialize(options);
+ return pgraph.serialize(options.randomizer);
}
- ActionPlan PackageGraph::serialize(const CreateInstallPlanOptions& options) const
+ ActionPlan PackageGraph::serialize(Graphs::Randomizer* randomizer) const
{
struct BaseEdgeProvider : Graphs::AdjacencyProvider
{
@@ -952,8 +978,8 @@ namespace vcpkg::Dependencies
installed_vertices.push_back(kv.first);
}
}
- auto remove_toposort = Graphs::topological_sort(removed_vertices, removeedgeprovider, options.randomizer);
- auto insert_toposort = Graphs::topological_sort(installed_vertices, installedgeprovider, options.randomizer);
+ auto remove_toposort = Graphs::topological_sort(removed_vertices, removeedgeprovider, randomizer);
+ auto insert_toposort = Graphs::topological_sort(installed_vertices, installedgeprovider, randomizer);
ActionPlan plan;
@@ -995,6 +1021,7 @@ namespace vcpkg::Dependencies
plan.install_actions.emplace_back(p_cluster->m_spec,
p_cluster->get_scfl_or_exit(),
p_cluster->request_type,
+ m_graph->m_host_triplet,
std::move(computed_edges));
}
else if (p_cluster->request_type == RequestType::USER_REQUESTED && p_cluster->m_installed.has_value())
@@ -1008,15 +1035,17 @@ namespace vcpkg::Dependencies
}
static std::unique_ptr create_feature_install_graph(
- const PortFileProvider::PortFileProvider& port_provider, const StatusParagraphs& status_db)
+ const PortFileProvider::PortFileProvider& port_provider,
+ const StatusParagraphs& status_db,
+ Triplet host_triplet)
{
- std::unique_ptr graph = std::make_unique(port_provider);
+ std::unique_ptr graph = std::make_unique(port_provider, host_triplet);
auto installed_ports = get_installed_ports(status_db);
for (auto&& ipv : installed_ports)
{
- graph->get(ipv);
+ graph->insert(ipv);
}
// Populate the graph with "remove edges", which are the reverse of the Build-Depends edges.
@@ -1041,8 +1070,9 @@ namespace vcpkg::Dependencies
PackageGraph::PackageGraph(const PortFileProvider::PortFileProvider& port_provider,
const CMakeVars::CMakeVarProvider& var_provider,
- const StatusParagraphs& status_db)
- : m_var_provider(var_provider), m_graph(create_feature_install_graph(port_provider, status_db))
+ const StatusParagraphs& status_db,
+ Triplet host_triplet)
+ : m_var_provider(var_provider), m_graph(create_feature_install_graph(port_provider, status_db, host_triplet))
{
}
@@ -1178,11 +1208,13 @@ namespace vcpkg::Dependencies
VersionedPackageGraph(const IVersionedPortfileProvider& ver_provider,
const IBaselineProvider& base_provider,
const PortFileProvider::IOverlayProvider& oprovider,
- const CMakeVars::CMakeVarProvider& var_provider)
+ const CMakeVars::CMakeVarProvider& var_provider,
+ Triplet host_triplet)
: m_ver_provider(ver_provider)
, m_base_provider(base_provider)
, m_o_provider(oprovider)
, m_var_provider(var_provider)
+ , m_host_triplet(host_triplet)
{
}
@@ -1197,6 +1229,7 @@ namespace vcpkg::Dependencies
const IBaselineProvider& m_base_provider;
const PortFileProvider::IOverlayProvider& m_o_provider;
const CMakeVars::CMakeVarProvider& m_var_provider;
+ const Triplet m_host_triplet;
struct DepSpec
{
@@ -1417,7 +1450,7 @@ namespace vcpkg::Dependencies
for (auto&& dep : *deps.get())
{
- PackageSpec dep_spec(dep.name, ref.first.triplet());
+ PackageSpec dep_spec(dep.name, dep.host ? m_host_triplet : ref.first.triplet());
if (!dep.platform.is_empty())
{
@@ -1435,7 +1468,6 @@ namespace vcpkg::Dependencies
}
auto& dep_node = emplace_package(dep_spec);
- // Todo: cycle detection
add_constraint(dep_node, dep, ref.first.name());
p.first->second.emplace_back(dep_spec, "core");
@@ -1624,9 +1656,11 @@ namespace vcpkg::Dependencies
void VersionedPackageGraph::add_roots(View deps, const PackageSpec& toplevel)
{
- auto specs = Util::fmap(deps, [&toplevel](const Dependency& d) {
- return PackageSpec{d.name, toplevel.triplet()};
- });
+ auto dep_to_spec = [&toplevel, this](const Dependency& d) {
+ return PackageSpec{d.name, d.host ? m_host_triplet : toplevel.triplet()};
+ };
+ auto specs = Util::fmap(deps, dep_to_spec);
+
specs.push_back(toplevel);
Util::sort_unique_erase(specs);
m_var_provider.load_dep_info_vars(specs);
@@ -1635,7 +1669,6 @@ namespace vcpkg::Dependencies
for (auto&& dep : deps)
{
- PackageSpec spec(dep.name, toplevel.triplet());
if (!dep.platform.evaluate(vars)) continue;
active_deps.push_back(&dep);
@@ -1644,7 +1677,7 @@ namespace vcpkg::Dependencies
// Note: x[core], x[y] will still eventually depend on defaults due to the second x[y]
if (Util::find(dep.features, "core") != dep.features.end())
{
- auto& node = emplace_package(spec);
+ auto& node = emplace_package(dep_to_spec(dep));
node.second.default_features = false;
}
}
@@ -1652,7 +1685,7 @@ namespace vcpkg::Dependencies
for (auto pdep : active_deps)
{
const auto& dep = *pdep;
- PackageSpec spec(dep.name, toplevel.triplet());
+ auto spec = dep_to_spec(dep);
auto& node = emplace_package(spec);
@@ -1795,7 +1828,8 @@ namespace vcpkg::Dependencies
// -> Add stack frame
auto maybe_vars = m_var_provider.get_dep_info_vars(spec);
- InstallPlanAction ipa(spec, *p_vnode->scfl, RequestType::USER_REQUESTED, std::move(p_vnode->deps));
+ InstallPlanAction ipa(
+ spec, *p_vnode->scfl, RequestType::USER_REQUESTED, m_host_triplet, std::move(p_vnode->deps));
std::vector deps;
for (auto&& f : ipa.feature_list)
{
@@ -1804,7 +1838,8 @@ namespace vcpkg::Dependencies
{
for (auto&& dep : *maybe_deps)
{
- if (dep.name == spec.name()) continue;
+ PackageSpec dep_spec(dep.name, dep.host ? m_host_triplet : spec.triplet());
+ if (dep_spec == spec) continue;
if (!dep.platform.is_empty() &&
!dep.platform.evaluate(maybe_vars.value_or_exit(VCPKG_LINE_INFO)))
@@ -1815,7 +1850,7 @@ namespace vcpkg::Dependencies
if (auto cons = maybe_cons.get())
{
- deps.emplace_back(DepSpec{{dep.name, spec.triplet()}, std::move(*cons)});
+ deps.emplace_back(DepSpec{std::move(dep_spec), std::move(*cons)});
}
else
{
@@ -1890,9 +1925,10 @@ namespace vcpkg::Dependencies
const CMakeVars::CMakeVarProvider& var_provider,
const std::vector& deps,
const std::vector& overrides,
- const PackageSpec& toplevel)
+ const PackageSpec& toplevel,
+ Triplet host_triplet)
{
- VersionedPackageGraph vpg(provider, bprovider, oprovider, var_provider);
+ VersionedPackageGraph vpg(provider, bprovider, oprovider, var_provider, host_triplet);
for (auto&& o : overrides)
vpg.add_override(o.name, {o.version, o.port_version});
vpg.add_roots(deps, toplevel);
diff --git a/src/vcpkg/export.chocolatey.cpp b/src/vcpkg/export.chocolatey.cpp
index 875982ed67..ba535526d5 100644
--- a/src/vcpkg/export.chocolatey.cpp
+++ b/src/vcpkg/export.chocolatey.cpp
@@ -14,20 +14,19 @@ namespace vcpkg::Export::Chocolatey
using Install::InstallDir;
static std::string create_nuspec_dependencies(const BinaryParagraph& binary_paragraph,
- const std::map& packages_version)
+ const std::map& packages_version)
{
static constexpr auto CONTENT_TEMPLATE = R"()";
std::string nuspec_dependencies;
- for (const std::string& depend : binary_paragraph.dependencies)
+ for (const auto& depend : binary_paragraph.dependencies)
{
auto found = packages_version.find(depend);
if (found == packages_version.end())
{
Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot find desired dependency version.");
}
-
- std::string nuspec_dependency = Strings::replace_all(CONTENT_TEMPLATE, "@PACKAGE_ID@", depend);
+ std::string nuspec_dependency = Strings::replace_all(CONTENT_TEMPLATE, "@PACKAGE_ID@", depend.name());
Strings::inplace_replace_all(nuspec_dependency, "@PACKAGE_VERSION@", found->second);
nuspec_dependencies += nuspec_dependency;
}
@@ -36,7 +35,7 @@ namespace vcpkg::Export::Chocolatey
static std::string create_nuspec_file_contents(const std::string& exported_root_dir,
const BinaryParagraph& binary_paragraph,
- const std::map& packages_version,
+ const std::map& packages_version,
const Options& chocolatey_options)
{
static constexpr auto CONTENT_TEMPLATE = R"(
@@ -58,7 +57,7 @@ namespace vcpkg::Export::Chocolatey
)";
- auto package_version = packages_version.find(binary_paragraph.spec.name());
+ auto package_version = packages_version.find(binary_paragraph.spec);
if (package_version == packages_version.end())
{
Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot find desired package version.");
@@ -168,7 +167,7 @@ if (Test-Path $installedDir)
fs.create_directory(exported_dir_path, ec);
// execute the plan
- std::map packages_version;
+ std::map packages_version;
for (const ExportPlanAction& action : export_plan)
{
if (action.plan_type != ExportPlanType::ALREADY_BUILT)
@@ -183,7 +182,7 @@ if (Test-Path $installedDir)
Strings::inplace_replace_all(norm_version, '-', '.');
Strings::inplace_replace_all(norm_version, '_', '.');
norm_version += chocolatey_options.maybe_version_suffix.value_or("");
- packages_version.insert(std::make_pair(binary_paragraph.spec.name(), norm_version));
+ packages_version.emplace(binary_paragraph.spec, norm_version);
}
for (const ExportPlanAction& action : export_plan)
diff --git a/src/vcpkg/export.cpp b/src/vcpkg/export.cpp
index 1f202a9d54..fd882cb47e 100644
--- a/src/vcpkg/export.cpp
+++ b/src/vcpkg/export.cpp
@@ -700,7 +700,8 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console
void ExportCommand::perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const
+ Triplet default_triplet,
+ Triplet /*host_triplet*/) const
{
Export::perform_and_exit(args, paths, default_triplet);
}
diff --git a/src/vcpkg/export.ifw.cpp b/src/vcpkg/export.ifw.cpp
index 74b06f5244..3093569794 100644
--- a/src/vcpkg/export.ifw.cpp
+++ b/src/vcpkg/export.ifw.cpp
@@ -94,7 +94,7 @@ namespace vcpkg::Export::IFW
fs::generic_u8string(package_xml_file_path));
auto deps = Strings::join(
- ",", binary_paragraph.dependencies, [](const std::string& dep) { return "packages." + dep + ":"; });
+ ",", binary_paragraph.dependencies, [](const auto& dep) { return "packages." + dep.name() + ":"; });
if (!deps.empty()) deps = "\n " + deps + "";
diff --git a/src/vcpkg/install.cpp b/src/vcpkg/install.cpp
index 5c62af4ede..2213e992f0 100644
--- a/src/vcpkg/install.cpp
+++ b/src/vcpkg/install.cpp
@@ -758,7 +758,10 @@ namespace vcpkg::Install
/// Run "install" command.
///
///
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
+ void perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet host_triplet)
{
// input sanitization
const ParsedArguments options =
@@ -903,7 +906,8 @@ namespace vcpkg::Install
var_provider,
dependencies,
manifest_scf.core_paragraph->overrides,
- {manifest_scf.core_paragraph->name, default_triplet})
+ {manifest_scf.core_paragraph->name, default_triplet},
+ host_triplet)
.value_or_exit(VCPKG_LINE_INFO);
for (InstallPlanAction& action : install_plan.install_actions)
@@ -938,7 +942,8 @@ namespace vcpkg::Install
StatusParagraphs status_db = database_load_check(paths);
// Note: action_plan will hold raw pointers to SourceControlFileLocations from this map
- auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, status_db);
+ auto action_plan =
+ Dependencies::create_feature_install_plan(provider, var_provider, specs, status_db, {host_triplet});
for (auto&& action : action_plan.install_actions)
{
@@ -1065,9 +1070,10 @@ namespace vcpkg::Install
void InstallCommand::perform_and_exit(const VcpkgCmdArguments& args,
const VcpkgPaths& paths,
- Triplet default_triplet) const
+ Triplet default_triplet,
+ Triplet host_triplet) const
{
- Install::perform_and_exit(args, paths, default_triplet);
+ Install::perform_and_exit(args, paths, default_triplet, host_triplet);
}
SpecSummary::SpecSummary(const PackageSpec& spec, const Dependencies::InstallPlanAction* action)
diff --git a/src/vcpkg/remove.cpp b/src/vcpkg/remove.cpp
index e29ae16c8f..b82f6cabd0 100644
--- a/src/vcpkg/remove.cpp
+++ b/src/vcpkg/remove.cpp
@@ -214,9 +214,7 @@ namespace vcpkg::Remove
&valid_arguments,
};
- void RemoveCommand::perform_and_exit(const VcpkgCmdArguments& args,
- const VcpkgPaths& paths,
- Triplet default_triplet) const
+ static void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
{
if (paths.manifest_mode_enabled())
{
@@ -334,4 +332,12 @@ namespace vcpkg::Remove
Checks::exit_success(VCPKG_LINE_INFO);
}
+
+ void RemoveCommand::perform_and_exit(const VcpkgCmdArguments& args,
+ const VcpkgPaths& paths,
+ Triplet default_triplet,
+ Triplet /*host_triplet*/) const
+ {
+ Remove::perform_and_exit(args, paths, default_triplet);
+ }
}
diff --git a/src/vcpkg/sourceparagraph.cpp b/src/vcpkg/sourceparagraph.cpp
index 52f72da943..b63f524182 100644
--- a/src/vcpkg/sourceparagraph.cpp
+++ b/src/vcpkg/sourceparagraph.cpp
@@ -427,6 +427,7 @@ namespace vcpkg
virtual StringView type_name() const override { return "a dependency"; }
constexpr static StringLiteral NAME = "name";
+ constexpr static StringLiteral HOST = "host";
constexpr static StringLiteral FEATURES = "features";
constexpr static StringLiteral DEFAULT_FEATURES = "default-features";
constexpr static StringLiteral PLATFORM = "platform";
@@ -436,6 +437,7 @@ namespace vcpkg
{
static const StringView t[] = {
NAME,
+ HOST,
FEATURES,
DEFAULT_FEATURES,
PLATFORM,
@@ -481,6 +483,7 @@ namespace vcpkg
{
dep.features.push_back("core");
}
+ r.optional_object_field(obj, HOST, dep.host, Json::BooleanDeserializer::instance);
r.optional_object_field(obj, PLATFORM, dep.platform, PlatformExprDeserializer::instance);
@@ -917,7 +920,6 @@ namespace vcpkg
control_file->core_paragraph = std::make_unique();
auto& spgh = control_file->core_paragraph;
- spgh->type = Type{Type::PORT};
for (const auto& el : obj)
{
@@ -1188,7 +1190,8 @@ namespace vcpkg
}
std::vector filter_dependencies(const std::vector& deps,
- Triplet t,
+ Triplet target,
+ Triplet host,
const std::unordered_map& cmake_vars)
{
std::vector ret;
@@ -1196,6 +1199,7 @@ namespace vcpkg
{
if (dep.platform.evaluate(cmake_vars))
{
+ Triplet t = dep.host ? host : target;
ret.emplace_back(FullPackageSpec({dep.name, t}, dep.features));
}
}
@@ -1205,7 +1209,7 @@ namespace vcpkg
static bool is_dependency_trivial(const Dependency& dep)
{
return dep.features.empty() && dep.platform.is_empty() && dep.extra_info.is_empty() &&
- dep.constraint.type == Versions::Constraint::Type::None;
+ dep.constraint.type == Versions::Constraint::Type::None && !dep.host;
}
static Json::Object serialize_manifest_impl(const SourceControlFile& scf, bool debug)
@@ -1265,6 +1269,7 @@ namespace vcpkg
}
dep_obj.insert(DependencyDeserializer::NAME, Json::Value::string(dep.name));
+ if (dep.host) dep_obj.insert(DependencyDeserializer::HOST, Json::Value::boolean(true));
auto features_copy = dep.features;
auto core_it = std::find(features_copy.begin(), features_copy.end(), "core");
@@ -1375,11 +1380,6 @@ namespace vcpkg
}
}
- if (debug)
- {
- obj.insert("TYPE", Json::Value::string(Type::to_string(scf.core_paragraph->type)));
- }
-
return obj;
}
diff --git a/src/vcpkg/statusparagraph.cpp b/src/vcpkg/statusparagraph.cpp
index ff3700d4b6..cc2d693337 100644
--- a/src/vcpkg/statusparagraph.cpp
+++ b/src/vcpkg/statusparagraph.cpp
@@ -88,7 +88,7 @@ namespace vcpkg
std::map> InstalledPackageView::feature_dependencies() const
{
- auto extract_deps = [&](const std::string& name) { return FeatureSpec{{name, spec().triplet()}, "core"}; };
+ auto extract_deps = [&](const PackageSpec& spec) { return FeatureSpec{spec, "core"}; };
std::map> deps;
@@ -104,7 +104,7 @@ namespace vcpkg
{
// accumulate all features in installed dependencies
// Todo: make this unneeded by collapsing all package dependencies into the core package
- std::vector deps;
+ std::vector deps;
for (auto&& feature : features)
for (auto&& dep : feature->package.dependencies)
deps.push_back(dep);
@@ -113,9 +113,10 @@ namespace vcpkg
for (auto&& dep : core->package.dependencies)
deps.push_back(dep);
- Util::erase_remove_if(deps, [&](const std::string& pspec) { return pspec == spec().name(); });
+ auto this_spec = this->spec();
+ Util::erase_remove_if(deps, [this_spec](const PackageSpec& pspec) { return pspec == this_spec; });
Util::sort_unique_erase(deps);
- return PackageSpec::to_package_specs(deps, spec().triplet());
+ return deps;
}
}
diff --git a/src/vcpkg/triplet.cpp b/src/vcpkg/triplet.cpp
index 9943ec9a8e..24a1f813af 100644
--- a/src/vcpkg/triplet.cpp
+++ b/src/vcpkg/triplet.cpp
@@ -73,38 +73,61 @@ namespace vcpkg
return nullopt;
}
- Triplet default_triplet(const VcpkgCmdArguments& args)
+ static Triplet system_triplet()
{
- if (args.triplet != nullptr)
+#if defined(_WIN32)
+ auto host_proc = System::get_host_processor();
+ switch (host_proc)
{
- return Triplet::from_canonical_name(std::string(*args.triplet));
+ case System::CPUArchitecture::X86: return Triplet::from_canonical_name("x86-windows");
+ case System::CPUArchitecture::X64: return Triplet::from_canonical_name("x64-windows");
+ case System::CPUArchitecture::ARM: return Triplet::from_canonical_name("arm-windows");
+ case System::CPUArchitecture::ARM64: return Triplet::from_canonical_name("arm64-windows");
+ default: return Triplet::from_canonical_name("x86-windows");
}
- else
- {
-#if defined(_WIN32)
- return Triplet::from_canonical_name("x86-windows");
#elif defined(__APPLE__)
- return Triplet::from_canonical_name("x64-osx");
+ return Triplet::from_canonical_name("x64-osx");
#elif defined(__FreeBSD__)
- return Triplet::from_canonical_name("x64-freebsd");
+ return Triplet::from_canonical_name("x64-freebsd");
#elif defined(__OpenBSD__)
- return Triplet::from_canonical_name("x64-openbsd");
+ return Triplet::from_canonical_name("x64-openbsd");
#elif defined(__GLIBC__)
#if defined(__aarch64__)
- return Triplet::from_canonical_name("arm64-linux");
+ return Triplet::from_canonical_name("arm64-linux");
#elif defined(__arm__)
- return Triplet::from_canonical_name("arm-linux");
+ return Triplet::from_canonical_name("arm-linux");
#elif defined(__s390x__)
- return Triplet::from_canonical_name("s390x-linux");
+ return Triplet::from_canonical_name("s390x-linux");
#elif (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) && \
defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
- return Triplet::from_canonical_name("ppc64le-linux");
+ return Triplet::from_canonical_name("ppc64le-linux");
#else
- return Triplet::from_canonical_name("x64-linux");
+ return Triplet::from_canonical_name("x64-linux");
#endif
#else
- return Triplet::from_canonical_name("x64-linux-musl");
+ return Triplet::from_canonical_name("x64-linux-musl");
#endif
+ }
+
+ Triplet default_triplet(const VcpkgCmdArguments& args)
+ {
+ if (args.triplet != nullptr)
+ {
+ return Triplet::from_canonical_name(std::string(*args.triplet));
+ }
+#if defined(_WIN32)
+ return Triplet::from_canonical_name("x86-windows");
+#else
+ return system_triplet();
+#endif
+ }
+
+ Triplet default_host_triplet(const VcpkgCmdArguments& args)
+ {
+ if (args.host_triplet != nullptr)
+ {
+ return Triplet::from_canonical_name(std::string(*args.host_triplet));
}
+ return system_triplet();
}
}
diff --git a/src/vcpkg/vcpkgcmdarguments.cpp b/src/vcpkg/vcpkgcmdarguments.cpp
index 6ac05e5380..b704f1ab4f 100644
--- a/src/vcpkg/vcpkgcmdarguments.cpp
+++ b/src/vcpkg/vcpkgcmdarguments.cpp
@@ -270,6 +270,7 @@ namespace vcpkg
cojoined_values[] = {
{VCPKG_ROOT_DIR_ARG, &VcpkgCmdArguments::vcpkg_root_dir},
{TRIPLET_ARG, &VcpkgCmdArguments::triplet},
+ {HOST_TRIPLET_ARG, &VcpkgCmdArguments::host_triplet},
{MANIFEST_ROOT_DIR_ARG, &VcpkgCmdArguments::manifest_root_dir},
{BUILDTREES_ROOT_DIR_ARG, &VcpkgCmdArguments::buildtrees_root_dir},
{DOWNLOADS_ROOT_DIR_ARG, &VcpkgCmdArguments::downloads_root_dir},
@@ -613,6 +614,9 @@ namespace vcpkg
table.format(opt(TRIPLET_ARG, "=", ""), "Specify the target architecture triplet. See 'vcpkg help triplet'");
table.format("", "(default: " + format_environment_variable("VCPKG_DEFAULT_TRIPLET") + ')');
+ table.format(opt(HOST_TRIPLET_ARG, "=", ""),
+ "Specify the host architecture triplet. See 'vcpkg help triplet'");
+ table.format("", "(default: " + format_environment_variable("VCPKG_DEFAULT_HOST_TRIPLET") + ')');
table.format(opt(OVERLAY_PORTS_ARG, "=", ""), "Specify directories to be used when searching for ports");
table.format("", "(also: " + format_environment_variable("VCPKG_OVERLAY_PORTS") + ')');
table.format(opt(OVERLAY_TRIPLETS_ARG, "=", ""), "Specify directories containing triplets files");
@@ -658,6 +662,7 @@ namespace vcpkg
}
from_env(TRIPLET_ENV, triplet);
+ from_env(HOST_TRIPLET_ENV, host_triplet);
from_env(VCPKG_ROOT_DIR_ENV, vcpkg_root_dir);
from_env(DOWNLOADS_ROOT_DIR_ENV, downloads_root_dir);
from_env(DEFAULT_VISUAL_STUDIO_PATH_ENV, default_visual_studio_path);
@@ -925,6 +930,8 @@ namespace vcpkg
constexpr StringLiteral VcpkgCmdArguments::TRIPLET_ENV;
constexpr StringLiteral VcpkgCmdArguments::TRIPLET_ARG;
+ constexpr StringLiteral VcpkgCmdArguments::HOST_TRIPLET_ENV;
+ constexpr StringLiteral VcpkgCmdArguments::HOST_TRIPLET_ARG;
constexpr StringLiteral VcpkgCmdArguments::OVERLAY_PORTS_ENV;
constexpr StringLiteral VcpkgCmdArguments::OVERLAY_PORTS_ARG;
constexpr StringLiteral VcpkgCmdArguments::OVERLAY_TRIPLETS_ENV;