diff --git a/.github/docker/Dockerfile.rhel8 b/.github/docker/Dockerfile.rhel8 index 1861014a71..e7809400d6 100644 --- a/.github/docker/Dockerfile.rhel8 +++ b/.github/docker/Dockerfile.rhel8 @@ -110,15 +110,21 @@ ENV VCPKG_DEFAULT_BINARY_CACHE=/opt/vcpkg-cache # ordinary source commits -- nightly rebuilds reuse the previously compiled # vcpkg binaries instead of recompiling every port. COPY ThirdParty/vcpkg /src/ThirdParty/vcpkg +COPY ThirdParty/vcpkg-overlay-ports /src/ThirdParty/vcpkg-overlay-ports COPY vcpkg.json /src/vcpkg.json COPY vcpkg-configuration-rhel8.json /src/vcpkg-configuration.json # A direct manifest install compiles every dependency into -# VCPKG_DEFAULT_BINARY_CACHE. The dependency set has no manifest features or -# overlay ports, and CC/CXX below match the ResInsight configure in the -# warmup stage and in CI, so the vcpkg ABI hashes match and the cache is -# reused there. x64-linux is the triplet the vcpkg CMake toolchain defaults -# to on Linux. +# VCPKG_DEFAULT_BINARY_CACHE. vcpkg-configuration-rhel8.json's overlay-ports +# entry ("ThirdParty/vcpkg-overlay-ports") is resolved relative to the +# directory vcpkg-configuration.json lives in, i.e. /src here, so that +# directory must be copied in too, not just ThirdParty/vcpkg. CC/CXX below +# match the ResInsight configure in the warmup stage and in CI, so the vcpkg +# ABI hashes match and the cache is reused there. x64-linux-release matches +# the triplet the CI workflows and the warmup stage below pass via +# VCPKG_TARGET_TRIPLET/VCPKG_HOST_TRIPLET -- using the plain (debug+release) +# x64-linux triplet here would populate the cache under different ABI hashes +# and none of it would be reused downstream. # # After the install, verify the cache contains a plausible number of entries. # vcpkg's `files` binary provider stores one .zip per package under @@ -132,7 +138,7 @@ RUN git config --global --add safe.directory '*' \ && ( cd /src/ThirdParty/vcpkg && ./bootstrap-vcpkg.sh ) \ && export CC=/opt/rh/gcc-toolset-14/root/usr/bin/gcc \ && export CXX=/opt/rh/gcc-toolset-14/root/usr/bin/g++ \ - && ( cd /src && ./ThirdParty/vcpkg/vcpkg install --triplet x64-linux ) \ + && ( cd /src && ./ThirdParty/vcpkg/vcpkg install --triplet x64-linux-release --host-triplet x64-linux-release ) \ && vcpkg_zip_count=$(find "${VCPKG_DEFAULT_BINARY_CACHE}" -type f -name '*.zip' | wc -l) \ && echo "vcpkg binary cache entries: ${vcpkg_zip_count}" \ && test "${vcpkg_zip_count}" -ge 20 \ @@ -167,7 +173,6 @@ COPY . /src # (the command line is part of the hash). RUN --mount=type=cache,id=ri-rhel8-buildcache,target=/var/cache/buildcache,sharing=locked \ git config --global --add safe.directory '*' \ - && cp /src/vcpkg-configuration-rhel8.json /src/vcpkg-configuration.json \ && source /opt/rh/gcc-toolset-14/enable \ && ( cd /src/ThirdParty/vcpkg && ./bootstrap-vcpkg.sh ) \ && export CC=/opt/rh/gcc-toolset-14/root/usr/bin/gcc \ @@ -182,6 +187,9 @@ RUN --mount=type=cache,id=ri-rhel8-buildcache,target=/var/cache/buildcache,shari -DRESINSIGHT_ENABLE_HDF5=false \ -DRESINSIGHT_ENABLE_GRPC=false \ -DRESINSIGHT_GCC_STDCPP_EXP_PATH=/opt/libstdcxx-exp/lib \ + -DRESINSIGHT_VCPKG_PROFILE=rhel8 \ + -DVCPKG_TARGET_TRIPLET=x64-linux-release \ + -DVCPKG_HOST_TRIPLET=x64-linux-release \ -DCMAKE_TOOLCHAIN_FILE=ThirdParty/vcpkg/scripts/buildsystems/vcpkg.cmake \ && cmake --build /src/cmakebuild --target ResInsight-tests -- -j"$(nproc)" \ && buildcache -s \ diff --git a/.github/workflows/build-rhel8-image.yml b/.github/workflows/build-rhel8-image.yml index c0b4169c24..80aa42edee 100644 --- a/.github/workflows/build-rhel8-image.yml +++ b/.github/workflows/build-rhel8-image.yml @@ -15,6 +15,7 @@ on: - ".dockerignore" - "vcpkg.json" - "vcpkg-configuration-rhel8.json" + - "ThirdParty/vcpkg-overlay-ports/**" - ".gitmodules" workflow_dispatch: inputs: diff --git a/.github/workflows/rhel8-package.yml b/.github/workflows/rhel8-package.yml index 34ea9cdd29..29f8205ebd 100644 --- a/.github/workflows/rhel8-package.yml +++ b/.github/workflows/rhel8-package.yml @@ -78,9 +78,6 @@ jobs: cd ThirdParty/vcpkg ./bootstrap-vcpkg.sh - - name: Use RHEL8 vcpkg configuration - run: cp vcpkg-configuration-rhel8.json vcpkg-configuration.json - - name: Configure CMake env: CC: /opt/rh/gcc-toolset-14/root/usr/bin/gcc @@ -103,6 +100,9 @@ jobs: -DRESINSIGHT_ENABLE_HDF5=false \ -DRESINSIGHT_ENABLE_GRPC=false \ -DRESINSIGHT_GCC_STDCPP_EXP_PATH=/opt/libstdcxx-exp/lib \ + -DRESINSIGHT_VCPKG_PROFILE=rhel8 \ + -DVCPKG_TARGET_TRIPLET=x64-linux-release \ + -DVCPKG_HOST_TRIPLET=x64-linux-release \ -DCMAKE_TOOLCHAIN_FILE=ThirdParty/vcpkg/scripts/buildsystems/vcpkg.cmake - name: Build install target diff --git a/.github/workflows/rhel8-unit-tests.yml b/.github/workflows/rhel8-unit-tests.yml index 6f41cb7510..bfe994c65d 100644 --- a/.github/workflows/rhel8-unit-tests.yml +++ b/.github/workflows/rhel8-unit-tests.yml @@ -80,9 +80,6 @@ jobs: cd ThirdParty/vcpkg ./bootstrap-vcpkg.sh - - name: Use RHEL8 vcpkg configuration - run: cp vcpkg-configuration-rhel8.json vcpkg-configuration.json - - name: Configure CMake env: CC: /opt/rh/gcc-toolset-14/root/usr/bin/gcc @@ -104,6 +101,9 @@ jobs: -DRESINSIGHT_ENABLE_HDF5=false \ -DRESINSIGHT_ENABLE_GRPC=false \ -DRESINSIGHT_GCC_STDCPP_EXP_PATH=/opt/libstdcxx-exp/lib \ + -DRESINSIGHT_VCPKG_PROFILE=rhel8 \ + -DVCPKG_TARGET_TRIPLET=x64-linux-release \ + -DVCPKG_HOST_TRIPLET=x64-linux-release \ -DCMAKE_TOOLCHAIN_FILE=ThirdParty/vcpkg/scripts/buildsystems/vcpkg.cmake - name: Build diff --git a/CMakeLists.txt b/CMakeLists.txt index 84c360044b..55ceb795bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,10 @@ include(FetchContent) # subdirectory CMakeLists.txt files pull in via their own find_package(). set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE) +# Must be include()'d before project() -- see cmake/ResInsightVcpkgProfile.cmake +# for why. +include(cmake/ResInsightVcpkgProfile.cmake) + project(ResInsight) # Include common settings diff --git a/cmake/ResInsightVcpkgProfile.cmake b/cmake/ResInsightVcpkgProfile.cmake new file mode 100644 index 0000000000..b83551a1f2 --- /dev/null +++ b/cmake/ResInsightVcpkgProfile.cmake @@ -0,0 +1,67 @@ +# Select an alternate vcpkg-configuration.json without renaming/copying any +# tracked file. The vcpkg toolchain +# (ThirdParty/vcpkg/scripts/buildsystems/vcpkg.cmake) defaults +# VCPKG_MANIFEST_DIR to CMAKE_SOURCE_DIR only when it is not already defined, +# and it must see the final value before project() triggers toolchain-file +# processing. This file must therefore be include()'d from the root +# CMakeLists.txt before project() is called -- code that runs after project() +# is too late. +# +# A profile's vcpkg-configuration file is expected at +# "vcpkg-configuration-${RESINSIGHT_VCPKG_PROFILE}.json" in the source root, +# e.g. vcpkg-configuration-rhel8.json for -DRESINSIGHT_VCPKG_PROFILE=rhel8. +# vcpkg.json is copied alongside it so both manifest files live in the same +# directory, as vcpkg requires; the copy is regenerated on every configure so it +# can never drift from the root vcpkg.json. +set(RESINSIGHT_VCPKG_PROFILE + "" + CACHE + STRING + "Optional vcpkg-configuration profile, e.g. 'rhel8' to use vcpkg-configuration-rhel8.json" +) +if(RESINSIGHT_VCPKG_PROFILE) + set(_resinsight_vcpkg_profile_config + "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg-configuration-${RESINSIGHT_VCPKG_PROFILE}.json" + ) + if(NOT EXISTS "${_resinsight_vcpkg_profile_config}") + message( + FATAL_ERROR "RESINSIGHT_VCPKG_PROFILE='${RESINSIGHT_VCPKG_PROFILE}' but " + "${_resinsight_vcpkg_profile_config} does not exist" + ) + endif() + + set(_resinsight_vcpkg_manifest_dir + "${CMAKE_BINARY_DIR}/vcpkg-manifest-${RESINSIGHT_VCPKG_PROFILE}" + ) + file(MAKE_DIRECTORY "${_resinsight_vcpkg_manifest_dir}") + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg.json" + "${_resinsight_vcpkg_manifest_dir}/vcpkg.json" COPYONLY + ) + configure_file( + "${_resinsight_vcpkg_profile_config}" + "${_resinsight_vcpkg_manifest_dir}/vcpkg-configuration.json" COPYONLY + ) + + # overlay-ports/overlay-triplets entries (e.g. + # "ThirdParty/vcpkg-overlay-ports") are resolved by vcpkg relative to the + # directory vcpkg-configuration.json lives in. Since the copy above now lives + # under the build tree instead of the source root, rewrite those repo-relative + # "ThirdParty/..." paths to absolute paths so they still resolve to the real + # source tree. + file(READ "${_resinsight_vcpkg_manifest_dir}/vcpkg-configuration.json" + _resinsight_vcpkg_profile_json + ) + string(REPLACE "\"ThirdParty/" "\"${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/" + _resinsight_vcpkg_profile_json + "${_resinsight_vcpkg_profile_json}" + ) + file(WRITE "${_resinsight_vcpkg_manifest_dir}/vcpkg-configuration.json" + "${_resinsight_vcpkg_profile_json}" + ) + + set(VCPKG_MANIFEST_DIR + "${_resinsight_vcpkg_manifest_dir}" + CACHE PATH "" FORCE + ) +endif() diff --git a/vcpkg-readme.md b/vcpkg-readme.md index a1464d2f9d..e22a7cf4dc 100644 --- a/vcpkg-readme.md +++ b/vcpkg-readme.md @@ -16,11 +16,26 @@ The `baseline` field in each configuration file pins the vcpkg registry to a spe ## RHEL8 CI usage -The workflow `.github/workflows/rhel8-unit-tests.yml` copies `vcpkg-configuration-rhel8.json` over `vcpkg-configuration.json` before invoking cmake: +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-.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()`. -```yaml -- name: Use RHEL8 vcpkg configuration - run: cp vcpkg-configuration-rhel8.json vcpkg-configuration.json +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. +This ensures vcpkg uses the RHEL8 baseline without affecting other CI runs, +and without ever mutating a tracked file in the source tree.