Provides official patterns for integrating and managing C++ libraries via vcpkg in imodel-native.

Install

mkdir -p .claude/skills/vcpkg && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/17818" && unzip -o skill.zip -d .claude/skills/vcpkg && rm skill.zip

Installs to .claude/skills/vcpkg

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Authoritative guide for vcpkg library integration in imodel-native. USE FOR adding a new vcpkg-managed library, migrating an existing library to vcpkg, or updating a vcpkg-managed library version. Covers the sequential install chain, PartFile wiring, mke patterns, triplet selection, and version pinn
300 chars · catalog description✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

Key capabilities

  • Add a new vcpkg-managed library to imodel-native.
  • Migrate an existing library to vcpkg management.
  • Update a vcpkg-managed library version.
  • Create manifest and configuration files for new libraries.
  • Wire consumer PartFile dependencies for vcpkg libraries.

How it works

This skill guides the process of integrating vcpkg libraries by defining a sequential install chain and specifying the necessary manifest, configuration, and build files. It ensures proper dependency management and build integrity.

Inputs & outputs

You give it
A new library, an existing library to migrate, or a version update for a vcpkg-managed library.
You get back
Integrated vcpkg library with correct build wiring in imodel-native.

When to use vcpkg

  • Adding a new dependency
  • Updating a vcpkg library
  • Migrating existing libs to vcpkg

About this skill

vcpkg Integration in imodel-native

All vcpkg documentation for humans lives in iModelCore/libsrc/VCPKG.md. This skill summarises the patterns an agent needs to get the build wiring right.


The Sequential Install Chain

All vcpkg install calls run through a single sequential chain defined in iModelCore/libsrc/vcpkg.PartFile.xml. The chain currently is:

vcpkg (bootstrap)
  └─► vcpkg_install_compress
        └─► vcpkg_install_png
              └─► vcpkg_install_pugixml
                    └─► vcpkg_install_openssl
                          └─► vcpkg_install_curl
                                └─► vcpkg_install_crashpad

Each link is a separate Part with its own vcpkg_install_<consumer>.mke that calls vcpkg_run_install.ps1 / vcpkg_run_install.sh. Chaining ensures no two vcpkg processes ever run concurrently — concurrent runs against the same install root collide on vcpkg-running.lock and corrupt the build.

Consumer .mke files do NOT call vcpkg_run_install themselves. By the time a consumer .mke runs, its install is already complete.


Adding a New vcpkg Library

Always update iModelCore/libsrc/README.md — add a row to the library table with the directory, library name, version, and Yes in the vcpkg column.

1. Create the manifest directory

Under iModelCore/libsrc/<mylib>/:

  • vcpkg.json — list dependency with version>= under dependencies and exact version under overrides
  • vcpkg-configuration.json — copy from an existing consumer (e.g. compress/); update baseline if needed
  • vcpkg-mend.json — list the triplet graph(s) whose union downloads all upstream source used by the consumer; the scan never compiles for the selected target, so triplets need not match the Mend host; prefer one source-superset graph, and add multiple triplets only for platform-specific downloads
  • triplets/ — platform-specific triplet files if the defaults in iModelCore/libsrc/ are not sufficient (see compress/triplets/ for examples)

For every Apple overlay triplet, explicitly set VCPKG_OSX_DEPLOYMENT_TARGET. Before creating or changing an arm64-osx.cmake or arm64-ios.cmake triplet, check the effective MACOS_DEPLOYMENT_TARGET or IOS_DEPLOYMENT_TARGET used by BentleyBuild. Their public defaults are defined in $(SrcRoot)bsicommon/PublicSDK/ApplyToolSet_CLang.mki, but build strategies may override them. Mirror the effective build value, not the product's official OS support floor. Omitting this setting lets vcpkg inherit the host SDK's deployment target and can produce objects that are too new to link into BentleyBuild outputs.

Check whether the library links cleanly into Windows DEBUG builds. Some libraries fail to link into Windows DEBUG unless their debug artifact is made release-CRT-compatible — either by forcing release-only triplets (set(VCPKG_BUILD_TYPE release)) or by fixing up the vcpkg Debug config to link the release CRT while keeping its diagnostics; others are fine without any change. See the Windows debug builds link the release CRT pitfall below to decide, and for both fixes. crashpad/triplets/ and pugixml/triplets/ are working examples of libraries that needed it.

2. Create iModelCore/libsrc/vcpkg_install_<mylib>.mke

%include mdl.mki

mylibDir    = $(_MakeFilePath)<mylib>
installRoot = $(OutputRootDir)vcpkg_installed/<mylib>

# Add vcpkgWindowsMDCRT = 1 here if the library must link /MD on Windows (like openssl).
# Add vcpkgUseVeracodeTriplet = 1 here ONLY if this library's base triplet sets explicit
# -RTC flags and you have provided a triplets/x64-windows-static-veracode.cmake overlay
# that omits them (see compress/ and crashpad/). Libraries whose triplets set no -RTC
# flags need no veracode variant and should leave this undefined.
%include $(_MakeFilePath)vcpkg.mki

always:
%if defined (winNT)
    powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$(_MakeFilePath)vcpkg_run_install.ps1" "$(mylibDir)" "$(installRoot)" "$(vcpkgTriplet)"
%else
    $(_MakeFilePath)vcpkg_run_install.sh $(mylibDir) $(installRoot) $(vcpkgTriplet)
%endif

$(_MakeFilePath) resolves to libsrc/ because the file lives there, so the paths to <mylib>/, vcpkg_run_install.ps1/.sh, and vcpkg.mki are all correct.

3. Extend the chain in iModelCore/libsrc/vcpkg.PartFile.xml

Insert a new link into the chain. The chain must stay linear, and — with one important exception below — where a link sits does not affect correctness because every consumer depends on its own named part. Prefer placing a more basic/foundational library (e.g. a compression or image codec that other libraries build on) earlier in the chain, and insert a new link wherever it reads most naturally alongside its peers.

Platform-coverage constraint (do not violate). The real invariant is that the chain must be linear on every individual platform: no two vcpkg_install_* parts that are both built on a given platform may run without a dependency edge between them, or they race on vcpkg-running.lock and corrupt the build. Across platforms the graph may fork into a tree — only each platform's projection of it has to be a single line. Consequences:

  • A chain link must depend on a predecessor built on at least the same platforms as the link itself. Some links are platform-restricted (e.g. vcpkg_install_crashpad carries OnlyPlatforms="linux*,x*,macos*" — desktop only). If an all-platform link were appended after a platform-restricted one, then on the excluded platforms (iOS/Android) its predecessor is skipped, the link loses its chain predecessor, and it can run concurrently with an earlier link.
  • Keep platform-restricted links at (or near) the tail, after every all-platform link. When adding an all-platform link, depend it on the last all-platform predecessor (not on a platform-restricted one). If a restricted link currently sits where the new one belongs, insert the new link before it and re-parent the restricted link onto the new one.
  • Two links whose platform sets overlap must stay linearly ordered (one depends on the other).
  • Two links whose platform sets are disjoint never build on the same platform, so they can never run concurrently — they may safely fork off a common all-platform predecessor. This is when the tail becomes a tree: e.g. a hypothetical iOS-only library and desktop-only crashpad would each depend on the last all-platform link (vcpkg_install_curl), one branch live on iOS, the other on desktop. Do not instead chain a desktop-only link behind an iOS-only link (or vice-versa): that edge is dead on both platforms yet still strands one link without a predecessor.

Example: curl (all platforms) was inserted before crashpad (desktop-only) — curl → openssl, and crashpad was re-parented from openssl onto curl. On iOS/Android crashpad is skipped and curl is the tail, still ordered after openssl.

To append at the end (only when the current last link is built on a superset of your platforms):

<Part Name="vcpkg_install_<mylib>" BentleyBuildMakeFile="vcpkg_install_<mylib>.mke">
    <SubPart PartName="vcpkg_install_<current-last>" LibType="Static"/>
</Part>

To insert mid-chain, point the new part at its predecessor and re-parent the following link onto the new part, keeping the chain linear. Whichever position you choose, update the sibling .mke comment ("Runs after vcpkg_install_<prev>…") on every link whose predecessor changed.

Also add the new part to the vcpkg_install_all aggregate so the shared binary-cache warmer includes it. Mend source scanning treats a directory as a consumer only when it holds all three of vcpkg.json, vcpkg-configuration.json, and vcpkg-mend.json; anything else is skipped, so vendored upstream trees that ship their own vcpkg.json are harmless. Because an omitted vcpkg-mend.json would just skip the library, vcpkg_run_install.ps1 and vcpkg_run_install.sh refuse to install a manifest directory that has no vcpkg-mend.json with a non-empty triplets array — so the omission fails that library's normal build on every platform. Every configured triplet must also have a matching overlay file. Select the smallest triplet set whose manifest and portfile branches cover all upstream downloads, and make sure it reaches every port pinned in overrides — the scan verifies that the ports named in dependencies and overrides all produced extracted source. The selected triplet does not need to match the Mend host because nothing is compiled for that target; for example, curl's x64-linux graph includes its common sources plus conditional c-ares, so no Windows graph is needed even though Mend runs on Windows. The host still needs a working toolchain of its own, since vcpkg builds host-triplet helper ports (vcpkg-cmake and friends) either way. The cross-consumer checks the wrappers cannot make — a misplaced vcpkg-mend.json, or a triplet with no overlay file — also run during Windows builds via the vcpkg_validate_mend part, so those mistakes fail the PR rather than the Mend pipeline.

Auditing platform coverage

Every consumer currently lists only x64-linux, which is a source-superset claim rather than a default. Nothing enforces it: the materialization check only sees ports named in dependencies and overrides, so a download that happens solely on an unlisted platform is skipped in silence. Two things put a download there, and both are easy to grep for:

# platform-qualified dependency or feature (curl's c-ares is "osx |

---

*Content truncated.*

When not to use it

  • When the library is not vcpkg-managed.
  • When the task is not related to imodel-native vcpkg integration.

Limitations

  • All `vcpkg install` calls run through a single sequential chain.
  • Concurrent runs against the same install root collide on `vcpkg-running.lock`.
  • Dynamic builds do not run `vcpkg install` at all.

How it compares

This skill provides a structured, step-by-step process for vcpkg integration specific to imodel-native, ensuring adherence to established patterns and preventing common build conflicts, unlike general vcpkg usage.

Compared to similar skills

vcpkg side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
vcpkg (this skill)02moNo flagsAdvanced
arm-cortex-expert295moNo flagsAdvanced
game-engine-resources144moNo flagsAdvanced
pc-games57moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry