Skip to content

Commit 17aa8f5

Browse files
authored
Pre-install and initialize vcpkg in Windows GitLab (#8962)
## Summary of changes Initialize vcpkg and pre-install its dependencies in Windows GitLab image ## Reason for change vcpkg is used to download libdatadog, but the first time it runs, it downloads and installs all its own dependencies (git, 7zip, powershell etc). That can cause flake, and is unecessary work to do on every build ## Implementation details - Preinstall the vcpkg depencencies in the GitLab windows image - Stop specifying a custom download location for these deps, and instead use the default (I don't see a good reason _not_ to do this). Note that this does not change where _packages_ are downloaded to, only vcpkg dependencies. - We can re-use this inside the Azure VMs, but for now, those are unchanged (requires updating the VM scripts and rebuilding them) ## Test coverage The PR is the test. Rebuilt the image, and built in Gitlab and verified we're no longer downloading vcpkg. Azure Devops is unchanged. ## Other details We _could_ (arguably _should_) pre-download the libdatadog version too, and cache that in the image, and then rebuild the image when we need to bump the version. However, that made the solution more complicated, needing to copy files around, include it in the build context etc, so kept the scope limited for now. We can always extend it to include libdatadog later. #incident-57303
1 parent db340bf commit 17aa8f5

5 files changed

Lines changed: 71 additions & 4 deletions

File tree

profiler/Directory.Build.targets

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
<VcpkgDepsDir>$(VcpkgManifestRoot)\artifacts\deps\vcpkg\</VcpkgDepsDir>
66
<!-- trying mimicking what's vcpkg does by default but redirecting where we want the final files -->
77
<VcpkgInstalledDir>$(VcpkgDepsDir)$(VcpkgTriplet)</VcpkgInstalledDir>
8-
<VcpkgAdditionalInstallOptions>--downloads-root $(VcpkgIntermediateFolder)/downloads --x-packages-root $(VcpkgIntermediateFolder)/packages --x-buildtrees-root $(VcpkgIntermediateFolder)/buildtrees --clean-after-build</VcpkgAdditionalInstallOptions>
8+
<!-- We leave downloads-root (for vcpkg deps) as the default, so that we can pre-populate it once (e.g. in CI)-->
9+
<VcpkgAdditionalInstallOptions>--x-packages-root $(VcpkgIntermediateFolder)/packages --x-buildtrees-root $(VcpkgIntermediateFolder)/buildtrees --clean-after-build</VcpkgAdditionalInstallOptions>
910
</PropertyGroup>
1011
<ItemDefinitionGroup Condition="'$(VcpkgUseStatic)' == 'true' and '$(VcpkgEnabled)' == 'true' and '$(MSBuildProjectExtension)' == '.vcxproj'">
1112
<Link>

tracer/build/_build/Build.Steps.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,6 @@ async Task DownloadWafVersion(string libddwafVersion = null, string uncompressFo
661661
// note that the following are all quoted when entered into the vcpkg call itself
662662
// this is necessary to support cases where we have a space in the folder name
663663
var installRoot = $@"{BuildArtifactsDirectory}\deps\vcpkg\{triplet}";
664-
var downloads = $@"{BuildArtifactsDirectory}\obj\vcpkg\downloads";
665664
var packages = $@"{BuildArtifactsDirectory}\obj\vcpkg\packages";
666665
var buildTrees = $@"{BuildArtifactsDirectory}\obj\vcpkg\buildtrees";
667666

@@ -672,8 +671,9 @@ async Task DownloadWafVersion(string libddwafVersion = null, string uncompressFo
672671
try
673672
{
674673
Logger.Information($"Attempt {attempt}: Running vcpkg install for {triplet}...");
675-
// This big line is the same generated by VS when installing libdatadog while building the profiler
676-
vcpkg($@"install --x-wait-for-lock --triplet ""{triplet}"" --vcpkg-root ""{vcpkgRoot}"" ""--x-manifest-root={RootDirectory}"" ""--x-install-root={installRoot}"" --downloads-root ""{downloads}"" --x-packages-root ""{packages}"" --x-buildtrees-root ""{buildTrees}"" --clean-after-build");
674+
// This big line is the same generated by VS when installing libdatadog while building the profiler.
675+
// We leave downloads-root (for vcpkg deps) as the default, so that we can pre-populate it once (e.g. in CI)
676+
vcpkg($@"install --x-wait-for-lock --triplet ""{triplet}"" --vcpkg-root ""{vcpkgRoot}"" ""--x-manifest-root={RootDirectory}"" ""--x-install-root={installRoot}"" --x-packages-root ""{packages}"" --x-buildtrees-root ""{buildTrees}"" --clean-after-build");
677677
Logger.Information($"vcpkg install succeeded on attempt {attempt}.");
678678
break; // Exit loop on success
679679
}
@@ -2883,6 +2883,7 @@ private async Task DownloadAndExtractVcpkg(AbsolutePath destinationFolder)
28832883
var keepTrying = true;
28842884
var vcpkgZip = TempDirectory / "vcpkg.zip";
28852885
using var client = new HttpClient();
2886+
// Keep this version in sync with VCPKG_VERSION in gitlab.windows.dockerfile
28862887
const string vcpkgVersion = "2024.11.16";
28872888
while (keepTrying)
28882889
{

tracer/build/_build/docker/gitlab/UPDATING_IMAGE.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ Once `build-windows-ci-image` is green, re-run the `build:` job (or any other Wi
4141
- The `:latest` tag is **only** used to seed the Docker build cache on the next rebuild. Nothing in the pipeline consumes `:latest` as an input at runtime; the consumer always pins to the content hash.
4242
- Changes to `compute-image-hash.ps1` itself also invalidate the hash, because the script hashes its own directory.
4343

44+
### vcpkg toolchain
45+
46+
`install_vcpkg.ps1` installs vcpkg into `C:\vcpkg` and pre-fetches the helper tools vcpkg would otherwise download on every build (e.g, `cmake`, `7zip` etc).
47+
48+
- Keep `VCPKG_VERSION` in `gitlab.windows.dockerfile` in sync with the `vcpkgVersion` constant in `tracer/build/_build/Build.Steps.cs`, so the pre-fetched tool versions match what the build's vcpkg expects.
49+
4450
### Example PR
4551

4652
- [dd-trace-dotnet#7492](https://github.com/DataDog/dd-trace-dotnet/pull/7492) (earlier, local-build flow — for structural reference)

tracer/build/_build/docker/gitlab/gitlab.windows.dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ RUN powershell -Command .\install_java.ps1
5454
# Install Windows Code Signer
5555
COPY --from=registry.ddbuild.io/windows-code-signer/go:v0.7.0 c:/windows-code-signer/windows-code-signer.exe c:/devtools/windows-code-signer.exe
5656

57+
# Install vcpkg and pre-fetch its helper toolchain.
58+
# Keep VCPKG_VERSION in sync with the vcpkgVersion constant in
59+
# Build.Steps.cs. See UPDATING_IMAGE.md.
60+
ENV VCPKG_VERSION="2024.11.16" \
61+
VCPKG_ROOT="C:\vcpkg"
62+
63+
COPY install_vcpkg.ps1 .
64+
RUN powershell -Command .\install_vcpkg.ps1 -Version $ENV:VCPKG_VERSION -InstallRoot $ENV:VCPKG_ROOT
65+
5766
# Copy everything else
5867
COPY . .
5968
ENTRYPOINT ["/entrypoint.bat"]
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
param (
2+
[Parameter(Mandatory=$true)][string]$Version,
3+
[Parameter(Mandatory=$false)][string]$InstallRoot = "C:\vcpkg"
4+
)
5+
6+
# Installs and bootstraps vcpkg into a fixed location, then pre-fetches the helper tools it downloads
7+
# on first use (cmake, 7zip, powershell-core, ninja). GetVcpkg() in tracer/build/_build/Build.Steps.cs
8+
# finds vcpkg.exe on PATH, and the build no longer relocates vcpkg's downloads root, so these
9+
# pre-fetched tools (under $InstallRoot\downloads\tools) are reused instead of downloaded on every
10+
# build. Keep $Version in sync with the vcpkgVersion constant in Build.Steps.cs so the pre-fetched
11+
# tool versions match the ones the build's vcpkg expects.
12+
13+
$ErrorActionPreference = 'Stop'
14+
$ProgressPreference = 'SilentlyContinue'
15+
16+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
17+
18+
$out = "$($PSScriptRoot)\vcpkg.zip"
19+
$url = "https://github.com/microsoft/vcpkg/archive/refs/tags/$Version.zip"
20+
21+
Write-Host -ForegroundColor Green "Downloading vcpkg $Version from $url to $out"
22+
(New-Object System.Net.WebClient).DownloadFile($url, $out)
23+
24+
Write-Host -ForegroundColor Green "Extracting $out"
25+
$parent = Split-Path -Parent $InstallRoot
26+
Expand-Archive -Path $out -DestinationPath $parent -Force
27+
Remove-Item $out
28+
29+
# The archive expands to a "vcpkg-<version>" folder; rename it to the fixed install root.
30+
if (Test-Path $InstallRoot) { Remove-Item -Recurse -Force $InstallRoot }
31+
Rename-Item -Path (Join-Path $parent "vcpkg-$Version") -NewName (Split-Path -Leaf $InstallRoot)
32+
33+
Write-Host -ForegroundColor Green "Bootstrapping vcpkg"
34+
& "$InstallRoot\bootstrap-vcpkg.bat" -disableMetrics
35+
if ($LASTEXITCODE -ne 0) { throw "bootstrap-vcpkg.bat failed with exit code $LASTEXITCODE" }
36+
37+
# Add vcpkg to the machine PATH so it is resolved by ToolPathResolver.GetPathExecutable at build time.
38+
[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) + ";$InstallRoot", [System.EnvironmentVariableTarget]::Machine)
39+
40+
# Pre-fetch the helper tools vcpkg would otherwise download on first use. These land under
41+
# $InstallRoot\downloads\tools, which is the default downloads root the build uses now that it no
42+
# longer overrides --downloads-root.
43+
foreach ($tool in @('git', 'cmake', '7zip', 'powershell-core', 'ninja')) {
44+
Write-Host -ForegroundColor Green "Pre-fetching vcpkg tool: $tool"
45+
& "$InstallRoot\vcpkg.exe" fetch $tool
46+
if ($LASTEXITCODE -ne 0) { throw "vcpkg fetch $tool failed with exit code $LASTEXITCODE" }
47+
}
48+
49+
Write-Host -ForegroundColor Green "Installed vcpkg $Version to $InstallRoot"
50+
& "$InstallRoot\vcpkg.exe" version

0 commit comments

Comments
 (0)