1

I am trying to understand how vcpkg can integrate with docker caching mechanism.

Here is my first naive attempt:

% cat Dockerfile
[...]
RUN vcpkg.exe install libpng # neat caching to prevent (re)compilation
WORKDIR c:/app
COPY . . # anything after this line will be (re)compiled
RUN cmake -S . -B build

My app contains a vcpkg.json file:

{
  "name": "my-proj",
  "version": "0.1.0",
  "dependencies": [
    {
      "name": "libpng"
    },
[...]

The line vcpkg.exe install libpng is a nice trick since upon the next run, docker will directly re-use the cache and will not redo the complete libpng rebuild.

Now my question is what if I need to vcpkg install a private dependency ? For example a public or private project that is not listed on the main vcpkg registry ?

Per documentation I cannot specify an alternate registry (vcpkg-configuration.json):

Is there another simple solution to build a dependency and cache it so that it is not re-build on the cmake -S . -B build line ?

malat
  • 12,152
  • 13
  • 89
  • 158

1 Answers1

0

Now my question is what if I need to vcpkg install a private dependency ?

The command line option you are looking for in classic mode is --overlay-ports=<path-to-directory-with-more-ports>.

Typical steps would be:

WORKDIR c:/deps
RUN git clone https://github.com/example/my-vcpkg-registry
RUN git clone https://github.com/microsoft/vcpkg
RUN .\vcpkg\bootstrap-vcpkg.bat # -disable-metrics
# VCPKG_DEFAULT_BINARY_CACHE or CLI option --binarysource=<config> can be used to configure binary caching. (where vcpkg stores and retrieves already build packages)
# Binary caching is enabled by default into `%SOMEDEFAULT%/vcpkg` so you probably want to control that to keep the docker size minimal
# X_VCPKG_ASSET_SOURCES or --x-asset-sources=<config> in addition to VCPKG_DOWNLOADS or --downloads-root=<path> can be used to control where vcpkg obtains already cached sources/tools from

RUN .\vcpkg\vcpkg.exe install libpng private_port --overlay-ports=./my-vcpkg-registry
# at this point libpng/private_port is properly installed in docker 
# you probably want to remove packages/, buildtrees/ and downloads/ from the vcpkg root here to keep the docker container minimal

---- # Split here. You would provide the above as its own docker image and import it for the below or you have an external binary cache setup which vcpkg can pull/push to. 

WORKDIR c:/app
# anything after this line will be (re)compiled
COPY . . 
RUN cmake -S . -B build

Is there another simple solution to build a dependency and cache it so that it is not re-build on the cmake -S . -B build line ?

Binary Caching:
https://learn.microsoft.com/en-us/vcpkg/users/binarycaching
If it is in the cache it will reinstall (if necessary) but not rebuild.
Having an ABI match however can be hard if you don't completely control all tools going into the hash calculation.

Alexander Neumann
  • 1,479
  • 8
  • 17
  • If I understand your comment about `--overlay-ports=` it seems to me that the install step will install the cache in a non-standard location... – malat Jul 10 '23 at 12:05
  • You just do `vcpkg.exe install libpng private_port --overlay-ports=`. The installation location will not change. – Alexander Neumann Jul 10 '23 at 13:35
  • Please review my edits. I did not understood wether or not binarycaching applied in my case. Could you add pseudo steps ? – malat Jul 11 '23 at 06:04
  • Ok I re-read how docker works since it has been quite a bit of time since I last used it. You are using Dockers caching mechanism to store whatever vcpkg does. That is not directly required if you setup a binary cache for vcpkg. Basically setting up an external binary cache for vcpkg allows you to use manifest mode in docker with a similar effect as running classic mode in docker except that in manifest mode files actually have to be moved. So your question just boils down to: "how to use my own ports with vcpkg in classic mode" and the answer is `--overlay-ports=` – Alexander Neumann Jul 11 '23 at 08:05