---
name: vcpkg-export-consumer-debug
description: >
  Debug iccDEV vcpkg, install/export, uninstall, and packaged consumer
  failures, especially Windows static CRT and path quoting regressions.
allowed-tools:
  - bash
  - read
  - grep
  - glob
  - shell(git:*)
  - shell(gh:*)
---

# vcpkg Export Consumer Debug

Use this skill when a review or workflow log mentions `ci-vcpkg-ports`,
`ci-pr-action`, `examples/hello-iccdev`, install manifests, uninstall, or
packaged CMake consumers.

## Port Pin Check

For source refreshes without an upstream version bump, update the port as
`version#port-version`: increment `ports/iccdev/vcpkg.json` `port-version`, and
refresh `ports/iccdev/portfile.cmake` `REF` plus `SHA512` together. CI should
use local source mode (`VCPKG_ICCDEV_SOURCE` and `VCPKG_KEEP_ENV_VARS`) so it
tests the checked-out branch, not the GitHub archive fallback.

## Dependency Manifest Sync

For direct build dependencies, compare and synchronize:

- `vcpkg.json`
- `Build/Cmake/vcpkg.json`
- `ports/iccdev/vcpkg.json`

Keep dependency-specific CMake options explicit in
`ports/iccdev/portfile.cmake`. For zlib, all three manifests declare `zlib`,
the portfile passes `-DICC_USE_ZLIB=ON`, and the overlay `port-version` is
incremented. Do not add zlib directly to `examples/hello-iccdev/vcpkg.json`;
that consumer receives it through the `iccdev` port.

For a registry baseline update, synchronize the root and `Build/Cmake`
manifests, `examples/hello-iccdev/vcpkg-configuration.json`, the explicit
checkouts in `ci-vcpkg-ports.yml`, and `VCPKG_BASELINE` in `ci.yml`. The
overlay port manifest intentionally has no registry baseline.

## Staleness Check

1. Compare the tested ref with the current PR head:

```bash
gh pr view <PR> --repo InternationalColorConsortium/iccDEV \
  --json headRefOid,headRefName,baseRefName,statusCheckRollup
git rev-parse HEAD
```

2. If the review SHA is not current, do not discard the finding. Re-check the
   current head for the exact source pattern or failing workflow path.
3. Treat the review as still actionable when the same source pattern remains
   present on the current head.

## Common Windows Failures

### Static vcpkg Consumer Uses the Wrong CRT

Signal:

```text
MT_StaticRelease from Icc*2-static.lib conflicts with MD_DynamicRelease
LNK1169
```

Cause: the `x64-windows-static` packaged libraries were built with `/MT`, but
the consumer executable used the default `/MD` runtime.

Fix: when configuring the packaged Windows static consumer, pass the matching
runtime explicitly:

```powershell
cmake -S "examples\hello-iccdev" -B $exampleBuild `
  -G "Visual Studio 17 2022" `
  -A x64 `
  -DCMAKE_BUILD_TYPE=Release `
  -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake" `
  -DVCPKG_MANIFEST_MODE=OFF `
  -DVCPKG_TARGET_TRIPLET=x64-windows-static `
  -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded
```

### Installed-Package Consumer Cannot Find Parent Dependencies

Signal:

```text
Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)
```

Cause: `iccdev.installed-package-consumer` disables manifest mode for its
nested projects. If the driver does not also forward the parent build's
`VCPKG_INSTALLED_DIR`, the vcpkg toolchain searches its global classic tree
instead of the manifest tree already populated for the parent build.

Fix contract: pass the parent installed tree into the CTest driver and forward
it to each nested configure together with `CMAKE_TOOLCHAIN_FILE`,
`VCPKG_MANIFEST_MODE=OFF`, and `VCPKG_TARGET_TRIPLET`. Keep
`build-test-binaries` dependent on every shared and static library artifact the
test stages.

Focused Windows validation:

```powershell
cmake --build out\vs2022-x64 --config Release --target build-test-binaries
ctest --test-dir out\vs2022-x64 -C Release `
  -R '^iccdev\.installed-package-consumer$' --output-on-failure --no-tests=error
```

### Source Uninstall Breaks on CMake Path Spaces

Signal:

```text
cmake --build ... --target uninstall --config Release
C:/Program Files/CMake/bin/cmake.exe is split at the space
```

Cause: generated uninstall scripts used unquoted `@CMAKE_COMMAND@`.

Fix:

```cmake
execute_process(
    COMMAND "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}"
)
```

## Validation

Run local checks before pushing:

```bash
git diff --check -- \
  vcpkg.json \
  Build/Cmake/vcpkg.json \
  ports/iccdev/vcpkg.json \
  ports/iccdev/portfile.cmake \
  Build/Cmake/RefIccMAXUninstall.cmake.in \
  .github/workflows/ci-vcpkg-ports.yml \
  .github/skills/vcpkg-export-consumer-debug/SKILL.md

python3 -c "import json; [json.load(open(p)) for p in ['vcpkg.json', 'Build/Cmake/vcpkg.json', 'ports/iccdev/vcpkg.json', 'examples/hello-iccdev/vcpkg.json']]; print('vcpkg JSON OK')"
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci-vcpkg-ports.yml')); print('YAML parse OK')"
actionlint -no-color .github/workflows/ci-vcpkg-ports.yml
file vcpkg.json Build/Cmake/vcpkg.json ports/iccdev/vcpkg.json \
  ports/iccdev/portfile.cmake \
  Build/Cmake/RefIccMAXUninstall.cmake.in \
  .github/skills/vcpkg-export-consumer-debug/SKILL.md
```

Final proof for these failures requires a GitHub-hosted Windows runner. Monitor
the source install/uninstall job and the packaged `hello-iccdev` consumer job
after pushing.

## References

- `../../workflows/ci-vcpkg-ports.yml`
- `../../../Build/Cmake/RefIccMAXUninstall.cmake.in`
- `../../../examples/hello-iccdev/CMakeLists.txt`
- `../../../ports/iccdev/portfile.cmake`
