VCPKG binary caching is no longer working
I believe this is due to this upstream issue: microsoft/vcpkg#45073
I tried applying some of the work arounds mentioned in that issue discussion (manually caching and restoring the vcpkg binary archive). But this didn't seem to work; I think maybe because run-cmake overrides the binary cache settings that vcpkg uses internally?
It would be great if a work-around could be implemented in run-cmake while this issue is unresolved upstream.
You need to override the environment variable, eg.
VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg-binary-cache,readwrite
Then you can save and restore that path as usual.
Hopefully this will be built-in in the future.
@JoostHouben, could you clarify which settings run-cmake is overriding? @SupSuper, could you help me understand this better? I see you are setting VCPKG_BINARY_SOURCES, and I'd be glad to see the whole workflow you are describing.
@lukka I think the env variable SupSuper mentioned is the one. I initially tried caching VCPKG binaries from their default location, and I also tried setting VCPKG_DEFAULT_BINARY_CACHE explicitly, but neither worked. I think this is because VCPKG_BINARY_SOURCES is set by run-cmake here.
Setting VCPKG_BINARY_SOURCES in the workflow as SupSuper suggested seems to work. I can then set up cache actions for the customized location.
I have a PR in my own repo here which attempts to implement this. I think it's working OK now (the PR has some other changes mixed in too, apologies for that). What I ended up doing is adding an explicit cache job which runs a CMake configure on the full repo for the relevant triplets. On my other jobs I then use a cache restore and VCPKG_BINARY_SOURCES with only the read setting. This is because those other jobs only build a subset of the repo, and so don't necessarily build all VCPKG dependencies.
Not sure if it's the best way of doing it, but I think it works. If integrated into run-cmake as a feature, there should probably be a way for the user to customize the cache key (in addition to or instead of basing it on the vcpkg config) to accommodate similar scenarios.
Even still, this kind of caching will now be an all-or-nothing thing compared to the per-library caching that was previously provided. But I think it's the best that can be done without deeper vcpkg integration.
@lukka This is the workflow I ended up with:
env:
VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg_cache,readwrite
steps:
- name: Restore vcpkg cache
uses: actions/cache/restore@v4
with:
path: ${{ github.workspace }}/vcpkg_cache
key: vcpkg-${{ matrix.triplet }}-${{ hashFiles('vcpkg.json') }}
restore-keys: vcpkg-${{ matrix.triplet }}-
...
- name: Save vcpkg cache
uses: actions/cache/save@v4
with:
path: ${{ github.workspace }}/vcpkg_cache
key: vcpkg-${{ matrix.triplet }}-${{ hashFiles('vcpkg.json') }}
The trick is figuring out the right cache keys for your project, since it may depend on the version of vcpkg / compiler / platform / job / etc. You can find other examples here: https://github.com/microsoft/vcpkg/issues/45073#issuecomment-2833052839 But this is good enough for me since my project dependencies rarely change.
If this was built into run-cmake/run-vcpkg, I would add the cache steps behind some "cache: true" flag, and let the user customize the key.
Thank you very much for your workaround, @SupSuper. While adapting it to my use, I found that it should not be necessary to include both a save and a restore step: If you simply use actions/cache@v4, then it will automatically perform a post-step to save the cache. This is a straight copy-paste of what I used, including the sequence of other related tasks that may or may not be relevant:
steps:
- uses: actions/checkout@v4
- name: Setup CMake
uses: lukka/get-cmake@latest
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
- name: Cache vcpkg
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/vcpkg_cache
key: vcpkg-${{ matrix.triplet }}-${{ hashFiles('vcpkg.json', 'vcpkg_overlay/**', 'CMakeLists.txt', '**/CMakeLists.txt', 'CMakePresets.json') }}
- name: Setup vcpkg
uses: lukka/run-vcpkg@v11
- name: Run CMake for ${{ matrix.build_preset }}
uses: lukka/run-cmake@v10
env:
VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg_cache,readwrite
VCPKG_DEFAULT_TRIPLET: ${{ matrix.triplet }}
with:
configurePreset: ${{ matrix.configure_preset }}
configurePresetAdditionalArgs: "['-DCMAKE_COMPILE_WARNING_AS_ERROR=ON']"
buildPreset: ${{ matrix.build_preset }}
(... therafter follows unit tests, reporting etc...)