Skip to content

Instantly share code, notes, and snippets.

@dpogue
Last active January 13, 2024 19:54
Show Gist options
  • Save dpogue/020d9abce4148e40aefedd5cf2c89c20 to your computer and use it in GitHub Desktop.
Save dpogue/020d9abce4148e40aefedd5cf2c89c20 to your computer and use it in GitHub Desktop.

vcpkg in H-uru/Plasma

The H-uru/Plasma repo uses vcpkg to manage C++ library dependencies. The libraries provided by vcpkg are called "ports" and it's a model similar to MacPorts, pacman (PKGBUILD), and other common software package managers.

One difference from typical package managers is that vcpkg also tries to accomodate different target compilers and target systems, as well as different build configuations. To do this, it uses a concept it calls "triplets". A triplet is an architecture, platform, and linking type (i.e., x86-windows-dynamic or x64-windows-static).

When you install Visual Studio 2022 with Desktop C++ component, vcpkg is automatically installed as well. You can also download vcpkg as a standalone tool, or use it as part of a CMake build system. The H-uru/Plasma repo uses CMake as its build system, so it has opted to use vcpkg's CMake integration, controlled by the USE_VCPKG boolean flag. By default this is enabled on Windows, and opt-in for other platforms.

H-uru/Plasma includes vcpkg as a git submodule, so that we have some degree of control over the version of the vcpkg tool and port definitions that we use. The vcpkg tool that ships with Visual Studio is updated as part of Visual Studio patches, but vcpkg itself sometimes has more frequent updates.

The Manifest File

H-uru/Plasma uses vcpkg in what is called "Manifest Mode", which is to say that there is a vcpkg.json file in the root of the repository that declares the project dependencies along with some additional configuration options. You can see the H-uru/Plasma manifest file here.

Dependencies

Each library dependency is listed in the manifest file. If a library is only needed on particular platforms, that can also be specified. Some port definitions in vcpkg have different optional features which can be enabled (such as maintaining Windows 7 support for Python).

Baseline & Overrides

Sometimes vcpkg's upstream port definitions have moved to a new version of a library, and a project prefers to remain on an older version for compatibility or stability reasons. In this case, vcpkg allows overriding the version of a port to use any previous versions that existed in vcpkg's history.

However, to do that also requires explicitly specifying the "current" baseline point in history. This is the git commit hash of the vcpkg version that we want to pull port definitions from by default.

Note

PhysX has been updated to version 5 in upstream vcpkg, and that includes breaking API changes as well as a significant curtailing of supported platforms: chiefly no 32-bit Windows support and no macOS support. We put a lot of time into patching PhysX 4.1.2 to support all our target platforms, so we're sticking with that for a while. This is accomplished by pinning to an older version of PhysX in the vcpkg.json manifest file.

Overlay Ports & Triplets

Sometimes a project may need to use a custom library that isn't supported by upstream vcpkg, or requires some specific patches that wouldn't be accepted into general upstream ports. To accomodate this, vcpkg allows a project to provide its own port definitions that take precedence over the ones from the baseline repository.

Projects can also specify their own custom triplets, either to extend support for platforms that aren't supported by upstream vcpkg or to customize build flags and linking options for a particular platform.

Note

H-uru/Plasma includes both custom triplets and custom ports.

Custom Triplets

Custom Triplet definitions

Ideally we want all libraries to be statically linked so that we don't have to distribute any .dll, .so, or .dylib files. However, part of our build process (optionally) involves running a Python script to assemble cursor images from SVG source files, and that requires Python and Cairo to be dynamically linked.

Custom Ports

Custom Port definitions

  • libepoxy is used for dynamic function lookups for the OpenGL pipeline. This is a patched upstream port, to make it not crash when built with threading on Windows.

  • python3-cairosvg is a custom port used by the optional build script to generate resources.dat with the cursor and loader images.

  • python3 is a patched upstream port targeting Python 3.10.7 with build fixes to support macOS Apple Silicon (arm64) builds.

Installing Dependencies

If you're wanting to build the client and tools and install dependencies all in a single step, it's easiest to just use the existing USE_VCPKG=ON option with CMake. Because this is the default on Windows, it also means that you can tell Visual Studio to open the H-uru/Plasma folder, and it will automatically build and configure all the necessary dependencies.

If you want to install the dependencies as a separate step, such as if you wanted to have a multi-stage pipeline where the first stage is just building the dependencies, you can do this by running vcpkg install --triplet=TRIPLET. It will automatically read the vcpkg.json manifest file and install the needed dependencies for the specified triplet.

Conveniently, vcpkg also includes a command to package up all of the built library artifacts into a zip file that can be used to feed into a second build step.

A complete "Build vcpkg dependencies" workflow would look something like this (in bash):

git clone https://github.com/H-uru/Plasma.git
vcpkg install --triplet=x86-windows-plasma
vcpkg export --zip --output-dir=exports
# Grab the zip file from the exports directory
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment