C++ vcpkg 고급 활용 | Manifest·Triplet·오버레이·바이너리 캐시 가이드
이 글의 핵심
C++ vcpkg 고급 기능 Manifest 모드·커스텀 Triplet·오버레이·버전 제약·바이너리 캐시, CI 연동, 자주 발생하는 에러와 프로덕션 패턴까지 실전 예제로 다룹니다.
들어가며: vcpkg 기본을 넘어서
문제 시나리오
vcpkg로 fmt, spdlog를 설치하고 빌드에 성공했다면, 이제 이런 상황을 마주할 수 있습니다:
"Windows에서는 되는데 Linux 서버에서만 링크 에러가 나요."
"사내에서 수정한 라이브러리를 vcpkg로 쓰고 싶어요."
"CI에서 매번 30분씩 vcpkg 빌드하는데, 캐시로 줄일 수 없나요?"
"프로젝트 A는 Boost 1.82, 프로젝트 B는 1.84를 써야 하는데 충돌해요."
"정적 링크로 배포해야 하는데 triplet 설정이 복잡해요."
"builtin-baseline 업데이트 후 갑자기 빌드가 깨졌어요."
이 글에서 다루는 것:
- Manifest 모드 심화: 버전 제약, 플랫폼별 의존성, builtin-baseline 전략
- 커스텀 Triplet: 정적 링크, 특수 컴파일러, 크로스 컴파일
- 오버레이 포트: 사내 라이브러리, 포트 수정본 통합
- 바이너리 캐시: CI 빌드 시간 대폭 단축
- 완전한 실전 예제: 복사 후 바로 사용 가능한 프로젝트 구조
- 자주 발생하는 에러와 해결법
- 베스트 프랙티스와 프로덕션 패턴
요구 환경: vcpkg 2024.01+, CMake 3.20+, C++17 이상
실무 적용 경험: 이 글은 대규모 C++ 프로젝트에서 실제로 겪은 문제와 해결 과정을 바탕으로 작성되었습니다. 책이나 문서에서 다루지 않는 실전 함정과 디버깅 팁을 포함합니다.
목차
- 문제 시나리오: vcpkg 고급 활용이 필요한 상황
- Manifest 모드 심화
- 커스텀 Triplet
- 오버레이 포트
- 바이너리 캐시
- 완전한 vcpkg 고급 예제
- 자주 발생하는 에러와 해결법
- 베스트 프랙티스
- 프로덕션 패턴
- 정리
1. 문제 시나리오: vcpkg 고급 활용이 필요한 상황
시나리오 1: 멀티 플랫폼 빌드 실패
개발: Windows (MSVC) → 빌드 성공
CI: Ubuntu (GCC) → "undefined reference to spdlog::..."
배포: macOS (Clang) → "library not found for -lssl"
원인: triplet이 플랫폼별로 다르고, 동적/정적 링크 설정이 통일되지 않음.
해결 방향: 커스텀 triplet으로 팀 전체가 동일한 빌드 설정을 사용.
시나리오 2: 사내 라이브러리 통합
"우리 회사에서 fork한 OpenSSL을 vcpkg로 쓰고 싶어요."
"공식 포트에 버그가 있어서 패치를 적용했어요."
원인: vcpkg 공식 레지스트리에 없는 패키지 또는 수정된 버전 필요.
해결 방향: 오버레이 포트로 사내 포트 디렉터리를 vcpkg에 등록.
시나리오 3: CI 빌드 시간 폭증
"PR마다 vcpkg가 Boost, OpenSSL을 처음부터 빌드해서 40분 걸려요."
"캐시를 넣었는데도 매번 새로 빌드해요."
원인: vcpkg 빌드 결과를 캐시하지 않거나, 바이너리 캐시를 활용하지 않음.
해결 방향: 바이너리 캐시(아티팩트, GitHub Actions cache)로 빌드 결과 재사용.
시나리오 4: 버전 충돌과 재현성
"builtin-baseline을 올렸더니 fmt 10.2로 올라가서 우리 코드가 깨졌어요."
"팀원 A는 빌드되는데 B는 실패해요. vcpkg 버전이 다르대요."
원인: baseline·버전 제약이 없거나 팀원마다 vcpkg 상태가 다름.
해결 방향: builtin-baseline 고정, version>= 제약, vcpkg를 서브모듈로 관리.
flowchart TD
subgraph problems[문제]
P1[멀티 플랫폼 불일치]
P2[사내 라이브러리]
P3[CI 빌드 지연]
P4[버전·재현성]
end
subgraph solutions[해결]
S1[커스텀 Triplet]
S2[오버레이 포트]
S3[바이너리 캐시]
S4[Manifest + baseline]
end
P1 --> S1
P2 --> S2
P3 --> S3
P4 --> S4
2. Manifest 모드 심화
버전 제약 문법
vcpkg.json에서 의존성 버전을 세밀히 제어할 수 있습니다.
{
"name": "my-production-app",
"version": "1.0.0",
"dependencies": [
"fmt",
{
"name": "spdlog",
"version>=": "1.11.0",
"version<": "2.0.0"
},
{
"name": "openssl",
"version>=": "3.0.0",
"platform": "!windows"
},
{
"name": "zlib",
"platform": "windows"
}
],
"builtin-baseline": "a1b2c3d4e5f6789012345678901234567890abc"
}
설명:
version>=: 최소 버전 (이 버전 이상)version<: 최대 버전 (이 버전 미만, 호환성 깨짐 방지)platform: 특정 플랫폼에서만 의존성 추가"windows": Windows에서만"!windows": Windows 제외 (Linux, macOS)"linux","osx"등
builtin-baseline 전략
builtin-baseline은 vcpkg 포트 저장소의 특정 커밋 해시입니다. 이 해시에 따라 사용 가능한 패키지 버전이 결정됩니다.
# vcpkg 최신 커밋 해시 확인
cd vcpkg
git pull
git rev-parse HEAD
# 출력: a1b2c3d4e5f6789012345678901234567890abc
권장 전략:
- 프로덕션: baseline을 고정하고, 별도 브랜치에서 업데이트 테스트 후 반영
- 개발: 주기적으로 baseline 업데이트, 전체 테스트 후 커밋
- CI:
vcpkg.json과vcpkg.lock을 Git에 커밋해 재현성 확보
vcpkg.lock 활용
Manifest 모드로 빌드하면 vcpkg.lock이 생성됩니다. 이 파일을 Git에 커밋하면 정확히 동일한 버전으로 빌드됩니다.
{
"version": 1,
"port-version": 0,
"builtin-baseline": "a1b2c3d4e5f6789012345678901234567890abc",
"packages": [
{
"name": "fmt",
"version": "10.1.1",
"port-version": 0
},
{
"name": "spdlog",
"version": "1.12.1",
"port-version": 0
}
]
}
주의: vcpkg.lock이 있으면 vcpkg가 이 버전을 우선 사용합니다. 의존성 추가/변경 시 lock 파일이 자동 갱신되므로, 변경 후 테스트하고 커밋하세요.
플랫폼별 의존성 예제
Windows에서는 시스템 SSL 대신 vcpkg OpenSSL, Linux에서는 시스템 OpenSSL을 쓰는 예:
{
"dependencies": [
"fmt",
"spdlog",
{
"name": "openssl",
"platform": "windows"
}
]
}
# CMakeLists.txt - OpenSSL은 Windows에서만 vcpkg, Linux는 시스템
if(WIN32)
find_package(OpenSSL REQUIRED)
target_link_libraries(myapp PRIVATE OpenSSL::SSL OpenSSL::Crypto)
endif()
3. 커스텀 Triplet
Triplet이란?
Triplet은 arch-vendor-os 형식으로, 대상 플랫폼·아키텍처·빌드 타입을 지정합니다.
| Triplet | 설명 |
|---|---|
x64-windows | Windows 64비트, 동적 링크 |
x64-windows-static | Windows 64비트, 정적 링크 |
x64-linux | Linux 64비트 |
x64-osx | macOS Intel |
arm64-osx | macOS Apple Silicon |
커스텀 Triplet 생성
정적 링크 + 특정 컴파일러 플래그가 필요할 때 커스텀 triplet을 만듭니다.
triplets/custom-static.cmake (프로젝트 내):
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE static)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME WindowsDesktop)
# 추가 컴파일러 플래그
set(VCPKG_CXX_FLAGS "/MT /W4")
set(VCPKG_CXX_FLAGS_DEBUG "/MTd /Od")
set(VCPKG_CXX_FLAGS_RELEASE "/MT /O2")
triplets/x64-linux-static.cmake (Linux 정적):
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE static)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Linux)
Triplet 사용
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE="$(pwd)/vcpkg/scripts/buildsystems/vcpkg.cmake" \
-DVCPKG_TARGET_TRIPLET=custom-static
또는 VCPKG_DEFAULT_TRIPLET 환경 변수:
export VCPKG_DEFAULT_TRIPLET=x64-windows-static
cmake -B build -S .
Triplet 오버레이
프로젝트별 triplet을 triplets/ 디렉터리에 두고 vcpkg에 알려줍니다:
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE="$(pwd)/vcpkg/scripts/buildsystems/vcpkg.cmake" \
-DVCPKG_OVERLAY_TRIPLETS="$(pwd)/triplets"
4. 오버레이 포트
오버레이란?
오버레이는 vcpkg 공식 레지스트리보다 우선 적용되는 포트 디렉터리입니다. 사내 라이브러리, 수정된 포트, 아직 upstream되지 않은 패키지를 사용할 때 씁니다.
오버레이 디렉터리 구조
my-ports/
├── company-openssl/ # 사내 fork OpenSSL
│ ├── portfile.cmake
│ └── vcpkg.json
├── patched-spdlog/ # 공식 spdlog에 패치 적용
│ ├── portfile.cmake
│ ├── vcpkg.json
│ └── patches/
│ └── fix-logging.patch
└── internal-lib/ # 완전히 사내 라이브러리
├── portfile.cmake
└── vcpkg.json
사내 포트 예제: internal-lib
my-ports/internal-lib/vcpkg.json:
{
"name": "internal-lib",
"version": "1.0.0",
"description": "사내 공통 라이브러리",
"license": "Proprietary",
"dependencies": [fmt]
}
my-ports/internal-lib/portfile.cmake:
vcpkg_from_git(
OUT_SOURCE_PATH SOURCE_PATH
URL "https://git.company.com/libs/internal-lib.git"
REF "v1.0.0"
)
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
)
vcpkg_cmake_install()
vcpkg_copy_pdbs()
file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
오버레이 사용
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE="$(pwd)/vcpkg/scripts/buildsystems/vcpkg.cmake" \
-DVCPKG_OVERLAY_PORTS="$(pwd)/my-ports"
vcpkg.json에서 오버레이 포트를 의존성으로 추가:
{
"dependencies": [
"fmt",
"internal-lib"
]
}
공식 포트 패치 적용
공식 spdlog 포트를 복사한 뒤 패치만 추가하는 예:
my-ports/patched-spdlog/portfile.cmake:
# 공식 포트를 가져온 뒤
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO gabime/spdlog
REF "v1.12.1"
SHA512 "..."
)
# 패치 적용
vcpkg_apply_patches(
SOURCE_PATH "${SOURCE_PATH}"
PATCHES "${CMAKE_CURRENT_LIST_DIR}/patches/fix-logging.patch"
)
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS -DSPDLOG_ENABLE_PCH=OFF
)
vcpkg_cmake_install()
vcpkg_copy_pdbs()
5. 바이너리 캐시
바이너리 캐시란?
vcpkg가 패키지를 빌드한 결과를 재사용하는 기능입니다. CI에서 매번 소스부터 빌드하는 대신, 이전에 빌드한 바이너리를 가져와 빌드 시간을 크게 줄입니다.
로컬 디렉터리 캐시
# 빌드 결과를 ./vcpkg-cache에 저장
export VCPKG_BINARY_SOURCES="clear;default,readwrite,./vcpkg-cache"
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=...
첫 빌드 후 vcpkg-cache/에 바이너리가 쌓이고, 이후 빌드에서는 여기서 읽어옵니다.
GitHub Actions 아티팩트 캐시
# .github/workflows/build.yml
env:
VCPKG_BINARY_SOURCES: "clear;default,readwrite,github,https://github.com/${{ github.repository }},readwrite"
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Configure and Build
run: |
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build build
주의: GitHub 아티팩트는 저장소별·용량 제한이 있습니다. 대안으로 actions/cache를 사용합니다.
actions/cache로 vcpkg 캐시
- name: Cache vcpkg
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/vcpkg/buildtrees
${{ github.workspace }}/vcpkg/packages
${{ github.workspace }}/vcpkg/downloads
key: vcpkg-${{ runner.os }}-${{ hashFiles('vcpkg.json', 'vcpkg.lock') }}
restore-keys: vcpkg-${{ runner.os }}-
- name: Configure CMake
run: |
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake
hashFiles('vcpkg.json', 'vcpkg.lock')가 바뀌면 새 캐시가 만들어지고, 그렇지 않으면 이전 빌드 결과를 재사용합니다.
6. 완전한 vcpkg 고급 예제
예제 1: 프로덕션 수준 프로젝트 구조
my-vcpkg-app/
├── .github/
│ └── workflows/
│ └── build.yml
├── CMakeLists.txt
├── CMakePresets.json
├── vcpkg.json
├── vcpkg.lock # Git 커밋 권장
├── triplets/
│ └── x64-windows-static.cmake
├── vcpkg/ # git submodule
└── src/
└── main.cpp
vcpkg.json (완전한 예제)
{
"name": "my-vcpkg-app",
"version": "1.0.0",
"description": "vcpkg 고급 활용 예제",
"dependencies": [
{
"name": "fmt",
"version>=": "10.0.0"
},
{
"name": "spdlog",
"version>=": "1.11.0",
"version<": "2.0.0"
},
{
"name": "openssl",
"platform": "windows"
}
],
"builtin-baseline": "a1b2c3d4e5f6789012345678901234567890abc"
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(my-vcpkg-app VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake"
CACHE STRING "Vcpkg toolchain")
add_executable(my-app src/main.cpp)
find_package(fmt CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)
if(WIN32)
find_package(OpenSSL REQUIRED)
target_link_libraries(my-app PRIVATE OpenSSL::SSL OpenSSL::Crypto)
endif()
target_link_libraries(my-app PRIVATE
fmt::fmt
spdlog::spdlog
)
target_compile_features(my-app PRIVATE cxx_std_17)
main.cpp
#include <spdlog/spdlog.h>
#include <fmt/core.h>
int main() {
spdlog::set_level(spdlog::level::debug);
spdlog::info("vcpkg 고급 예제: {}", fmt::format("Hello, vcpkg!"));
return 0;
}
CMakePresets.json (팀 설정 통일)
{
"version": 3,
"configurePresets": [
{
"name": "vcpkg-default",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake"
}
},
{
"name": "vcpkg-static",
"inherits": "vcpkg-default",
"cacheVariables": {
"VCPKG_TARGET_TRIPLET": "x64-windows-static"
}
}
]
}
GitHub Actions 워크플로 (완전한 예제)
name: Build (vcpkg)
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Cache vcpkg
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/vcpkg/buildtrees
${{ github.workspace }}/vcpkg/packages
${{ github.workspace }}/vcpkg/downloads
key: vcpkg-${{ runner.os }}-${{ hashFiles('vcpkg.json', 'vcpkg.lock') }}
restore-keys: vcpkg-${{ runner.os }}-
- name: Configure
run: |
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DCMAKE_BUILD_TYPE=Release
- name: Build
run: cmake --build build --config Release
예제 2: 오버레이 + 커스텀 triplet
# vcpkg를 서브모듈로
git submodule add https://github.com/Microsoft/vcpkg.git vcpkg
# CMake 설정 (오버레이 + triplet)
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE="$(pwd)/vcpkg/scripts/buildsystems/vcpkg.cmake" \
-DVCPKG_OVERLAY_PORTS="$(pwd)/my-ports" \
-DVCPKG_OVERLAY_TRIPLETS="$(pwd)/triplets" \
-DVCPKG_TARGET_TRIPLET=x64-windows-static
7. 자주 발생하는 에러와 해결법
에러 1: “Could not find a package configuration file provided by ‘fmt’”
CMake Error: Could not find a package configuration file provided by "fmt"
원인: CMAKE_TOOLCHAIN_FILE을 지정하지 않았거나, vcpkg가 패키지를 아직 빌드하지 않음.
해결법:
# 1. 툴체인 파일 반드시 지정
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE="$(pwd)/vcpkg/scripts/buildsystems/vcpkg.cmake"
# 2. build 폴더 삭제 후 재시도 (캐시된 잘못된 설정 제거)
rm -rf build
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=...
에러 2: “Port xxx is not in the baseline”
Error: Could not find a version that satisfies the requirement ...
원인: builtin-baseline이 오래되었거나, 해당 패키지가 baseline에 없음.
해결법:
cd vcpkg
git pull
git rev-parse HEAD # 이 해시를 vcpkg.json의 builtin-baseline에 넣기
{
"builtin-baseline": "최신_커밋_해시"
}
에러 3: “Building package xxx failed”
Building package spdlog:x64-linux failed
원인: 패키지 빌드 중 컴파일 에러, 의존성 누락, 네트워크 오류 등.
해결법:
# 상세 로그로 원인 파악
export VCPKG_VERBOSE=1
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=...
# 특정 패키지만 수동 빌드
./vcpkg install spdlog --debug
에러 4: “A suitable version of cmake was not found”
Error: vcpkg was unable to find the version of cmake in your PATH
원인: PATH에 CMake가 없거나 버전이 낮음 (3.20+ 권장).
해결법:
which cmake
cmake --version
# 3.20 이상이어야 함. PATH에 추가하거나 최신 CMake 설치
에러 5: “Multiple definitions” / 링크 에러
error: multiple definition of 'spdlog::...'
원인: 정적/동적 링크 혼용, triplet 불일치.
해결법:
- triplet을 팀 전체가 동일하게 사용 (예:
x64-windows-static) - vcpkg로 설치한 라이브러리와 시스템 라이브러리 혼용 금지
에러 6: “C++ 표준 불일치”
error: #error "spdlog requires C++17 or later"
원인: 프로젝트가 C++14로 빌드되는데 의존성이 C++17 요구.
해결법:
target_compile_features(my-app PRIVATE cxx_std_17)
# 또는
set(CMAKE_CXX_STANDARD 17)
에러 7: 오버레이 포트를 찾을 수 없음
Error: Could not find port internal-lib
원인: VCPKG_OVERLAY_PORTS 경로가 잘못되었거나, 포트 디렉터리 구조가 맞지 않음.
해결법:
# 경로 확인 (절대 경로 권장)
ls -la my-ports/internal-lib/vcpkg.json
cmake -B build -S . \
-DVCPKG_OVERLAY_PORTS="$(pwd)/my-ports"
에러 8: vcpkg.lock과 vcpkg.json 충돌
Error: Version conflict: lock file expects [email protected] but vcpkg.json allows 10.2.0
원인: vcpkg.json을 수정했는데 vcpkg.lock을 갱신하지 않음.
해결법:
# lock 파일 삭제 후 재생성
rm vcpkg.lock
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=...
# 새 vcpkg.lock 생성됨 → Git 커밋
에러 9: CI에서만 “Could NOT find” 발생
원인: 로컬에 Classic 모드로 설치한 패키지에 의존. CI에는 해당 패키지가 없음.
해결법: Manifest 모드로 전환. vcpkg.json에 의존성 선언하고 CMAKE_TOOLCHAIN_FILE 지정.
에러 10: 바이너리 캐시에서 손상된 패키지
Error: Failed to restore package from binary cache
원인: 캐시가 손상되었거나 triplet/버전이 달라서 호환되지 않음.
해결법:
# 캐시 비우고 재빌드
rm -rf vcpkg-cache
# 또는 CI에서 cache key 변경
8. 베스트 프랙티스
1. Manifest 모드 사용
vcpkg.json을 프로젝트 루트에 두고 Git에 커밋- Classic 모드(
vcpkg install전역 설치)는 레거시. 신규 프로젝트는 Manifest 모드
2. builtin-baseline 고정
- 재현 가능한 빌드를 위해 특정 커밋 해시 사용
- 업데이트 시 별도 브랜치에서 테스트 후 main 반영
3. vcpkg.lock 커밋
vcpkg.lock을 Git에 커밋하면 팀 전체가 동일한 버전 사용- 의존성 추가/변경 시 lock 갱신 후 테스트·커밋
4. vcpkg 서브모듈
git submodule add https://github.com/Microsoft/vcpkg.git vcpkg
- vcpkg 버전을 프로젝트와 함께 고정
- CI에서
submodules: recursive로 체크아웃
5. find_package CONFIG 모드
find_package(fmt CONFIG REQUIRED)
target_link_libraries(my-app PRIVATE fmt::fmt)
- vcpkg 패키지는 대부분 Config 모드.
CONFIG명시 권장
6. 의존성 최소화
- 꼭 필요한 패키지만 추가
- 헤더 전용 라이브러리(nlohmann-json 등)는 빌드 없이 사용 가능
7. CI 캐시 활용
buildtrees,packages,downloads캐시hashFiles('vcpkg.json', 'vcpkg.lock')를 key에 포함
8. CMake Presets
CMakePresets.json으로 팀 전체 설정 통일cmake --preset vcpkg-default로 간편 설정
9. 프로덕션 패턴
패턴 1: 멀티 플랫폼 CI 매트릭스
strategy:
matrix:
include:
- os: ubuntu-latest
triplet: x64-linux
- os: windows-latest
triplet: x64-windows-static
- os: macos-latest
triplet: arm64-osx
steps:
- run: |
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_TARGET_TRIPLET=${{ matrix.triplet }}
패턴 2: 사내 오버레이 공유
회사 레포지토리: company/vcpkg-ports
각 프로젝트에서:
-DVCPKG_OVERLAY_PORTS="$(pwd)/../vcpkg-ports"
또는 서브모듈로 vcpkg-ports 포함
패턴 3: Docker + vcpkg
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y git cmake g++ build-essential
RUN git clone https://github.com/Microsoft/vcpkg.git /vcpkg && \
/vcpkg/bootstrap-vcpkg.sh
ENV CMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake
WORKDIR /app
COPY . .
RUN cmake -B build -S . && cmake --build build
패턴 4: 의존성 업데이트 전략
1. 개발: 주기적으로 baseline 업데이트, 로컬 테스트
2. 스테이징: 업데이트 후 CI 전체 통과 확인
3. 프로덕션: vcpkg.lock 커밋으로 버전 고정
패턴 5: 버전 제약으로 호환성 유지
{
"dependencies": [
{
"name": "spdlog",
"version>=": "1.11.0",
"version<": "2.0.0"
}
]
}
version<로 마이저 업그레이드 시 예기치 않은 깨짐 방지
10. 정리
| 항목 | 설명 |
|---|---|
| Manifest 심화 | 버전 제약, 플랫폼별 의존성, builtin-baseline, vcpkg.lock |
| 커스텀 Triplet | 정적 링크, 특수 컴파일러, 오버레이 triplet |
| 오버레이 | 사내 라이브러리, 패치된 포트 통합 |
| 바이너리 캐시 | 로컬/CI 캐시로 빌드 시간 단축 |
| 에러 해결 | 툴체인 지정, baseline 업데이트, triplet 통일 |
| 프로덕션 | 멀티 플랫폼 CI, 오버레이 공유, Docker, 업데이트 전략 |
구현 체크리스트
- Manifest 모드 + vcpkg.json
- builtin-baseline 고정
- vcpkg.lock Git 커밋
- vcpkg 서브모듈
- CMAKE_TOOLCHAIN_FILE 지정
- CI에서 vcpkg 캐시
- 필요 시 오버레이·커스텀 triplet
자주 묻는 질문 (FAQ)
Q. vcpkg Classic 모드와 Manifest 모드 차이는?
A. Classic 모드는 vcpkg install로 전역 설치. Manifest 모드는 프로젝트 vcpkg.json에 의존성을 선언하고 CMake 설정 시 자동 설치. 재현 가능한 빌드를 위해 Manifest 모드를 권장합니다.
Q. 사내 라이브러리를 vcpkg로 쓰려면?
A. 오버레이 포트를 만듭니다. my-ports/내라이브러리/에 vcpkg.json과 portfile.cmake를 두고, -DVCPKG_OVERLAY_PORTS로 경로를 지정합니다.
Q. CI 빌드가 너무 느려요.
A. actions/cache로 vcpkg의 buildtrees, packages, downloads를 캐시하세요. hashFiles('vcpkg.json', 'vcpkg.lock')를 key에 넣으면 의존성 변경 시에만 캐시가 갱신됩니다.
Q. builtin-baseline을 언제 업데이트하나요?
A. 보안 패치·버그 수정이 필요할 때. 별도 브랜치에서 업데이트 후 전체 테스트를 돌리고, 통과하면 main에 반영합니다.
한 줄 요약: vcpkg Manifest·Triplet·오버레이·바이너리 캐시를 활용하면 멀티 플랫폼·재현 가능·빠른 CI 빌드를 구축할 수 있습니다.
다음 글: [C++ #53-4] Conan 레시피 작성 | 패키지 배포·의존성 관리
이전 글: [C++ #53-2] Visual Studio C++ 완벽 가이드
관련 글
- C++ vcpkg 기초 완벽 가이드 | 설치·Manifest·Triplet·버전·커스텀 포트 [#53-3]
- C++ vcpkg 패키지 만들기 | 포트 파일·빌드·배포 완벽 가이드 [#53-3]
- C++ Conan 고급 완벽 가이드 | lockfile·크로스 빌드·사내 레포·프로덕션 패턴 [#53-4]
- CMake 입문 | 수십 개 파일 컴파일할 때 필요한 빌드 자동화 (CMakeLists.txt 기초)