Search code examples
c++linuxcmakevcpkg

Using custom triplets with vcpkg and CMake in manifest mode


I'm trying to configure vcpkg to compile dependencies using address sanitizer and thread sanitizer. To do this, I need to pass the compilation flag -fsanitize=address or fsanitize=thread to all compilation commands. Reading here, the best way to do this seems to be to use the "overlay-triplets" feature in vcpkg. However, I having some trouble understanding on how exactly this works. Following, the documentation, I created a custom-triplets folder in my project's root directory with two files called x64-linux-asan and x64-linux-tsan, which look like:

set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)

set(VCPKG_CMAKE_SYSTEM_NAME Linux)

set(VCPKG_CXX_FLAGS "${VCPKG_CXX_FLAGS} -fsanitize=address")

Now, I don't quite understand how do I configure CMake to use for example the x64-linux-asan triplet. I'm using vcpkg in manifest mode. The docs mention that you can create a vcpkg-configuration.json file to use custom triplets, but how does one selected a specific triplet from the custom list of files? I have tried with this:

cmake -B build -DVCPKG_TARGET_TRIPLET=x64-linux-asan

but it doesn't work and vcpkg complains:

error: Invalid triplet: x64-linux-asan


Solution

  • To use custom triplets you also have to set VCPKG_OVERLAY_TRIPLETS variable so vcpkg can find them. Just set it to the directory that contains your custom triplet.

    I would recommend setting those variables using cmake presets, so that they are automatically filled:

    {
      "name": "vcpkg",
      "hidden": true,
      "cacheVariables": {
        "VCPKG_OVERLAY_TRIPLETS": "${sourceDir}/triplets",
        "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
      }
    },
    {
      "name": "linux-asan",
      "hidden": true,
      "cacheVariables": {
        "VCPKG_TARGET_TRIPLET": "x64-linux-asan"
      }
    },
    

    With this you can create a cmake presets that inherit from those two, and automatically set all of those CMake variables without baking them into your scripts.