run-cmake icon indicating copy to clipboard operation
run-cmake copied to clipboard

VCPKG binary caching is no longer working

Open JoostHouben opened this issue 7 months ago • 5 comments

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.

JoostHouben avatar Apr 27 '25 01:04 JoostHouben

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.

SupSuper avatar Apr 27 '25 12:04 SupSuper

@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 avatar Apr 27 '25 22:04 lukka

@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.

JoostHouben avatar Apr 27 '25 23:04 JoostHouben

@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.

SupSuper avatar Apr 28 '25 00:04 SupSuper

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...)

einarsi avatar Jun 23 '25 09:06 einarsi