Files
ResInsight/vcpkg-readme.md
T
Magne Sjaastad f6787a9ea1 vcpkg: Patch snappy for AVX-by-default toolchains via overlay port
snappy 1.2.2, a transitive dependency of arrow, includes <immintrin.h> only
when SNAPPY_HAVE_BMI2 or SNAPPY_HAVE_X86_CRC32 is set, but MemCopy64() selects
an AVX code path on a separate condition, `defined(__x86_64__) &&
defined(__AVX__)`. The vcpkg port passes -DSNAPPY_HAVE_BMI2=OFF and
-DSNAPPY_HAVE_X86_CRC32=OFF to keep the binaries portable, so on a toolchain
whose default target enables AVX that branch is compiled with no intrinsics
header and snappy.cc fails with "'__m256i' was not declared in this scope".

This broke the clang-tidy and clazy-report workflows the first night after they
moved to ubuntu-26.04. The runner switch also changed the vcpkg compiler hash,
so the binary cache went from "Restored 103 package(s)" to "Restored 0
package(s)" and every port was rebuilt from source, which is what exposed
snappy in the first place. The bug is not GCC 15 specific: microsoft/vcpkg#51047
reports it against GCC 14.3.1. It is still present in snappy 1.3.1 and main, and
vcpkg master still ships 1.2.2 with the SNAPPY_HAVE_* options off, so neither a
baseline bump nor a port update fixes it.

Vendor the port under ThirdParty/vcpkg-overlay-ports and add
avx-immintrin.patch, which includes <immintrin.h> for the __AVX__ branch as
well. The patch cannot change the ISA baseline of the result: it only supplies
a header on a path the compiler was already going to take. Verified by
reproducing the failure locally with an overlay triplet setting
-march=x86-64-v3, confirming the patched port builds both with and without that
flag, and checking that objdump finds no AVX instructions in the library built
with the stock toolchain.

Reference the two overlay ports by their individual directories rather than by
the parent directory. The two configurations resolve different versions of both
ports (default: snappy 1.2.2#1, thrift 0.22.0; rhel8: snappy 1.2.1,
thrift 0.20.0#1), so an overlay of the whole directory would downgrade thrift
for the default builds and bump snappy for RHEL8. Dry runs of both manifests
confirm each profile now picks up only its own overlay.

The bumped port-version misses the existing vcpkg binary caches, but those
caches are already cold for the ubuntu-26.04 workflows.
2026-09-29 14:14:51 +02:00

3.1 KiB

vcpkg Configuration

Files

File Purpose
vcpkg-configuration.json Default registry configuration used by all builds
vcpkg-configuration-rhel8.json RHEL8-specific registry configuration with a separate baseline

Overlay ports

ThirdParty/vcpkg-overlay-ports/ holds local copies of upstream vcpkg ports that need a patch the upstream port does not carry. Each configuration file opts in to individual ports rather than the whole directory, because the two baselines resolve different versions: pointing a profile at the parent directory would silently override every port in it.

Port Used by Reason
snappy vcpkg-configuration.json snappy.cc guards <immintrin.h> on SNAPPY_HAVE_BMI2/SNAPPY_HAVE_X86_CRC32, which the port turns off, but MemCopy64() uses AVX intrinsics whenever __AVX__ is defined. Fails on the ubuntu-26.04 runner. microsoft/vcpkg#51047
thrift vcpkg-configuration-rhel8.json Mutex.h uses int64_t without including <cstdint>, which GCC 15 no longer provides transitively

When adding a port, copy it from ThirdParty/vcpkg/ports/<name>, add the patch to PATCHES with a comment explaining why, bump port-version, and add the port's path to the overlay-ports array of the configurations that need it. Drop the overlay once upstream carries an equivalent fix.

Changing the baseline

The baseline field in each configuration file pins the vcpkg registry to a specific commit of microsoft/vcpkg. Packages available at that commit are used for dependency resolution.

  • Update vcpkg-configuration.json for the default (Ubuntu/Windows) builds.
  • Update vcpkg-configuration-rhel8.json independently when a different baseline is needed for RHEL8 (Rocky Linux 8) compatibility — e.g. to match older system libraries (glibc 2.28, OpenSSL 1.1).

RHEL8 CI usage

Selecting the RHEL8 configuration does not rename or overwrite the tracked vcpkg-configuration.json. Instead, the root CMakeLists.txt accepts a RESINSIGHT_VCPKG_PROFILE cache variable. When set, it copies vcpkg.json and vcpkg-configuration-<profile>.json into a profile-specific directory under the build tree and points vcpkg's VCPKG_MANIFEST_DIR at it, before project() triggers the vcpkg toolchain file. This must happen before project(): the toolchain file only defaults VCPKG_MANIFEST_DIR to CMAKE_SOURCE_DIR when the variable is not already defined, and it reads that value while processing project().

The workflows .github/workflows/rhel8-unit-tests.yml and .github/workflows/rhel8-package.yml (and .github/docker/Dockerfile.rhel8) select the RHEL8 baseline by passing this flag to cmake:

cmake -S /src -B /src/cmakebuild -G Ninja \
  ... \
  -DRESINSIGHT_VCPKG_PROFILE=rhel8 \
  -DCMAKE_TOOLCHAIN_FILE=ThirdParty/vcpkg/scripts/buildsystems/vcpkg.cmake

This ensures vcpkg uses the RHEL8 baseline without affecting other CI runs, and without ever mutating a tracked file in the source tree.