이 문서에는 포트 레시피를 추가하거나 업데이트할 때 적용해야 하는 정책 집합이 나열되어 있습니다. Debian의 정책 설명서, Homebrew의 유지 관리자 지침 및 Homebrew의 수식 요리책 역할을 하기 위한 것입니다.
전체 레지스트리 디자인 목표
현재 기준의 포트를 동시에 설치할 수 있어야 합니다.
큐레이팅된 레지스트리에서 라이브러리의 다운스트림 사용자에게 게시하는 지정된 기준의 라이브러리 조합이 적어도 일부 구성에서 함께 작동하도록 테스트되었음을 표시할 수 있기를 바랍니다. 포트가 서로를 제외하도록 허용하면 이러한 테스트에 필요한 빌드 수가 다음과 같이 2^number_of_such_cases증가하므로 이러한 구성을 테스트하는 기능이 중단됩니다. 또한 추가 종속성 설치는 항상 "안전"으로 간주됩니다. 포트 또는 최종 사용자가 해당 요구 사항에 종속성이 설치되지 않았다고 어설션할 수 있는 방법은 없습니다.
사용자에게 그러한 대체 상황을 나타내려면, 큐레이트된 레지스트리의 지속적인 통합 과정에서 결코 빌드되지 않은 포트를 추가하려고 시도하기보다는, 주석 내 대체 양식을 구현하는 오버레이 포트를 만드는 방법을 설명하는 것이 좋습니다. 예를 들어 glad@0.1.36을 참조 하세요.
레지스트리를 도입하기 전에는, 제작 오버레이 포트를 더 쉽게 만들기 위해 테스트되지 않은 여러 포트를 대체안으로 수락했습니다. 예를 들어, 와 같은 것이 있습니다. 레지스트리는 큐레이팅된 레지스트리를 수정하지 않고 이러한 테스트되지 않은 포트를 게시할 수 있으므로 더 이상 허용되지 않습니다.
16진수 문자열에 소문자 사용
vcpkg의 많은 기능은 16진수 문자열을 비교하는 데 의존합니다. 일부 예에는 SHA512 해시, Git 커밋 ID 및 트리 개체 해시가 포함되지만 제한되지는 않습니다.
내부적으로 vcpkg는 대소문자가 중요하지 않은 값의 비교를 위해 소문자 정규화를 사용합니다. 그러나 vcpkg의 인프라를 기반으로 구축된 도구는 동일한 고려 사항을 고려하지 않을 수 있습니다. 이러한 이유로 16진수 문자열이 필요합니다.
다음 시나리오에서 일관성을 위해 소문자를 지정합니다.
-
SHA512vcpkg 도우미 함수의 매개 변수입니다. - 값이
REF16진수 문자열인 경우 vcpkg 도우미 함수의 매개 변수입니다. -
git-tree버전 데이터베이스 파일의 개체입니다. -
sha512파일의scripts/vcpkg-tools.json개체입니다. - 16진수 문자열의 대소문자 구분이 중요하지 않은 다른 경우들입니다.
PR 구조
포트당 별도의 끌어오기 요청 만들기
가능하면 변경 내용을 여러 PR로 구분합니다. 이렇게 하면 검토하기가 훨씬 쉬워지고 한 일련의 변경 내용으로 인해 다른 모든 변경 내용이 유지되지 않도록 방지할 수 있습니다.
손길이 닿지 않은 파일에서 사소한 변경 방지
예를 들어 현재 문제에 대해 수정할 이유가 없는 포트파일의 변수를 다시 포맷하거나 이름을 변경하지 않도록 합니다. 그러나 PR의 기본 목적(라이브러리 업데이트)을 위해 파일을 수정해야 하는 경우 오타 수정과 같은 분명히 유익한 변경 내용을 확인할 수 있습니다.
다른 리포지토리에 대한 이름 확인
포트 이름은 포트가 설치되는 패키지에 대해 명확하게 설명해야 합니다. 검색 엔진에서 포트 이름을 검색하면 해당 프로젝트로 빠르게 연결되는 것이 이상적입니다. 여러 리포지토리에서 여러 패키지 이름을 한 번에 확인하는 좋은 서비스는 Repology입니다.
이름이 짧거나 일반 단어의 이름을 따서 명명된 프로젝트는 특히 지정된 단어와 강한 연관성이 있는 프로젝트가 없는 경우 명확성이 필요할 수 있습니다. 예를 들어 이름이 ip 지정된 포트는 여러 프로젝트의 이름이 비슷하게 지정될 가능성이 있으므로 허용되지 않습니다.
좋은 구별하는 도구의 예는 다음과 같습니다.
- 리포지토리의 소유자 사용자 이름 또는 조직:
google-cloud-cpp. - 프로젝트가 속한 라이브러리 모음의 이름은 다음과
boost-dll같습니다.
C++ 및 오픈 소스 프로젝트에서 사용하는 일반적인 접두사 및 접미사는 유효한 명확성자가 아니며, 일부 예에서는 다음을 포함하지만 제한되지는 않습니다.
-
cpp; -
free; -
lib; -
open; - 숫자
예를 들어 다음 포트 이름을 ip-cpplibip 비교하고 ip5 잘못된 명확성을 제거할 때 모두 동일한 스템(ip)으로 축소되므로 이름이 같은 것으로 간주됩니다.
단일 프로젝트와 강력하게 연결된 이름에 대해서는 이 지침에 대한 예외가 발생합니다. 예: libpng, openssl 및 zlib
사용자에게 혼동을 방지하기 위해 공용 레지스트리에 포트가 추가되면 포트 이름을 바꿀 수 있는 빈도를 제한할 수 있습니다. 현재 정책은 연간 두 개 이상의 이름 바꾸기를 허용하지 않는 것입니다.
GitHub 초안 PR 사용
GitHub 초안 PR은 아직 병합할 준비가 되지 않은 작업에 대한 CI 또는 사용자 피드백을 얻을 수 있는 좋은 방법입니다. CI가 통과되면 대부분의 새 PR을 초안으로 열고 일반 PR로 변환해야 합니다.
GitHub 초안 풀 리퀘스트에 대한 자세한 내용은 초안 풀 리퀘스트 소개를 참조하세요.
vcpkg 팀은 검토 프로세스 중에 PR을 초안으로 변환할 수 있습니다. 일반적으로 PR을 검토 준비로 표시할 시기를 나타내는 코드 또는 주석을 변경하라는 요청이 있습니다.
비활성 PR 닫기
부실한 PR이 누적되지 않도록 vcpkg 팀은 60일 이상 기여자 작업을 기다리고 있는 PR을 닫을 수 있습니다. 이 카운트다운은 vcpkg 유지 관리자가 변경 또는 피드백을 요청하는 마지막 시간부터 시작되며, 60일 이내에 활동이 관찰되지 않는 경우 PR은 부실한 것으로 간주되며 vcpkg의 팀 재량에 따라 폐쇄될 수 있습니다.
포트 파일
사용되지 않는 도우미 함수 방지
현재 다음 도우미는 더 이상 사용되지 않습니다.
-
vcpkg_extract_source_archive_ex()은vcpkg_extract_source_archive()와 함께 지원되는ARCHIVE오버로드로 바꿔야 합니다. - 더 이상 사용되지 않는
vcpkg_extract_source_archive()오버로드는 지원되는ARCHIVE오버로드로 바꿔야 합니다. -
vcpkg_apply_patches()는 "extract" 도우미의 인수PATCHES으로 바꿔야 합니다(예:vcpkg_from_github()). -
vcpkg_build_msbuild()는 다음으로 바꿔야 합니다.vcpkg_install_msbuild() -
vcpkg_copy_tool_dependencies()는 다음으로 바꿔야 합니다.vcpkg_copy_tools() -
vcpkg_configure_cmake를 제거한 후vcpkg_cmake_configure()를PREFER_NINJA로 바꿔야 합니다. -
vcpkg_build_cmake는 다음으로 바꿔야 합니다.vcpkg_cmake_build() -
vcpkg_install_cmake는 다음으로 바꿔야 합니다.vcpkg_cmake_install() -
vcpkg_fixup_cmake_targets는 다음으로 바꿔야 합니다.vcpkg_cmake_config_fixup
일부 대체 도우미 함수는 소비자가 특정 버전에서 동작을 고정하여 특정 버전에서 도우미의 동작을 잠글 수 있도록 하는 "도구 포트"에 있습니다. 다음과 같이 도구 포트를 포트에 "dependencies"추가해야 합니다.
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
포트파일에서 과도한 주석 방지
이상적으로 포트파일은 짧고 단순하며 가능한 한 선언적이어야 합니다.
PR을 제출하기 전에 create 명령으로 추가된 보일러 플레이트 주석을 제거하세요.
포트는 경로에 종속되어서는 안 됩니다.
이미 설치된 포트에 따라 포트의 설치 콘텐츠를 변경하는 방식으로 포트의 동작을 변경해서는 안 됩니다. 예를 들어 다음과 같은 조건이 있습니다.
> vcpkg install a
> vcpkg install b
> vcpkg remove a
및
> vcpkg install b
설치한 파일은 b 이전 설치 a의 영향과 관계없이 동일해야 합니다. 즉, 일부 작업을 수행하기 전에 포트가 설치된 트리에서 다른 포트에 의해 제공된 항목을 검색하지 않아야 합니다. 이러한 "경로 종속" 동작의 구체적이고 일반적인 원인은 아래 "기능을 정의할 때 종속성을 명시적으로 제어"에 설명되어 있습니다.
고유 포트 특성 규칙
전체 vcpkg 시스템에서는 사용자가 동시에 사용할 것으로 예상되는 두 개의 포트가 동일한 파일을 제공할 수 없습니다. 포트가 다른 파일에서 이미 제공한 파일을 설치하려고 하면 설치가 실패합니다. 예를 들어 포트가 헤더에 매우 일반적인 이름을 사용하려는 경우 해당 헤더를 내부가 아닌 include하위 디렉터리에 배치해야 합니다.
이 속성은 레지스트리의 모든 포트를 설치하려고 하는 연속 통합 실행을 통해 정기적으로 확인되며, 두 포트가 동일한 파일을 제공하는 경우 실패 FILE_CONFLICTS 합니다.
비공식 네임스페이스에 CMake 내보내기 추가
vcpkg의 핵심 디자인 이상은 사용자에 대한 "잠금"을 만들지 않는 것입니다. 빌드 시스템에서 시스템 라이브러리에 의존하는 것과 vcpkg의 라이브러리에 의존하는 것 사이에 차이가 없어야 합니다. 이를 위해 업스트림이 vcpkg와 충돌하지 않고 고유한 공식 CMake 내보내기를 추가할 수 있도록 "명백한 이름"을 사용하여 기존 라이브러리에 CMake 내보내기 또는 대상을 추가하지 않습니다.
이를 위해, 포트에서 내보내는 CMake 설정 중 업스트림 라이브러리에 포함되지 않은 것들은 unofficial-를 접두사로 가져야 합니다. 추가 대상은 네임스페이스에 unofficial::<port>:: 있어야 합니다.
즉, 사용자에게 다음이 표시됩니다.
-
find_package(unofficial-<port> CONFIG)vcpkg에만 있는 특별한 패키지를 가져오는 방법 -
unofficial::<port>::<target>은 해당 포트에서 내보낸 대상입니다.
예:
-
brotli는unofficial-brotli패키지를 생성하여 대상unofficial::brotli::brotli를 만듭니다.
저작권 파일 설치
각 포트는 폴더copyright에 명명된 ${CURRENT_PACKAGES_DIR}/share/${PORT} 파일을 제공해야 합니다. 패키지의 라이선스 콘텐츠를 원본 파일 내에서 사용할 수 있는 경우 이 파일을 호출하여 vcpkg_install_copyright()만들어야 합니다.
vcpkg_install_copyright 또한 필요한 경우 여러 저작권 파일을 번들로 묶습니다.
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")
이 파일을 수동으로 만드는 이전 메서드는 CMake의 기본 제공 file 명령을 사용하는 것입니다. 새로운 포트에서는 vcpkg_install_copyright을(를) 선호하지만 여전히 허용됩니다.
file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
업스트림 원본 파일의 라이선스 콘텐츠가 텍스트 형식(예: PDF 파일) copyright 이 아닌 경우 사용자가 라이선스 요구 사항을 찾는 방법에 대한 설명을 포함해야 합니다. 가능하면 이를 나타내는 원래 원본 파일에 대한 링크도 포함해야 하므로 사용자는 최신 상태인지 확인할 수 있습니다.
file(WRITE "${CURRENT_PACKAGES_DIR}/share/${PORT}/copyright" [[As of 2023-07-25, according to
https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Public-Documents/README.md#end-user-license-agreement
this software is bound by the "SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT" PDF located at
https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Public-Documents/ADL%20SDK%20EULA.pdf
]])
포트의 버전 제약 조건
포트 내의 버전 제약 조건은 프로젝트의 독립적인 진화를 방해할 수 있으므로 일반적으로 방지해야 합니다. 이러한 제약 조건을 추가하는 것은 특정 이전 버전과 호환되지 않는 것으로 입증된 것과 같이 잘 문서화된 타당성이 있는 경우에만 허용됩니다. 이러한 제약 조건은 독립 프로젝트와의 패리티를 유지하기 위해만 사용해서는 안 됩니다.
변수는 MAYBE_UNUSED_VARIABLES 하나 이상의 구성에 적용해야 합니다.
CMake 구성 단계에서 경고를 무시하기 위해 MAYBE_UNUSED_VARIABLES에 새 변수를 추가할 때, 새 변수가 적용되는 상황에 대한 설명을 주석으로 추가해야 합니다. 변수가 구성에 적용되지 않는 경우 기본 버그(예: 철자가 틀린 변수 이름)가 존재하고 추가해도 빌드에 실제로 영향을 주지 않을 가능성이 큽니다.
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
FEATURES
windowsfeature WINDOWS_OPTION
)
vcpkg_configure_cmake(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
${FEATURE_OPTIONS}
MAYBE_UNUSED_VARIABLES
# Applies only on Windows
WINDOWS_OPTION
)
기능
기능을 사용하여 대안을 구현하지 마세요.
기능은 추가 기능으로 처리되어야 합니다.
port[featureA]가 설치되고 port[featureB]가 설치되면, port[featureA,featureB]도 설치해야 합니다. 또한 두 번째 포트가 종속 [featureA] 되고 세 번째 포트가 종속된 [featureB]경우 두 번째 포트와 세 번째 포트를 모두 설치하면 해당 종속성이 충족되어야 합니다.
이 상황에서 라이브러리는 vcpkg에 표현된 대로 사용 가능한 옵션 중 하나를 선택해야 하며, 다른 설정을 원하는 사용자는 현재 오버레이 포트를 사용해야 합니다.
이전 버전과의 호환성을 위해 현재는 허용하지 않는 기존 예제:
-
libgit2,libzipopen62541모두 TLS 또는 암호화 백 엔드를 선택하는 기능이 있습니다.curl에는 다른 암호화 백 엔드 옵션이 있지만 런타임에 둘 중에서 선택할 수 있습니다. 즉, 위의 테넌트가 유지됩니다. -
darknetopencv2에는opencv3종속성에 사용할 opencv 버전을 제어하는 기능이 있습니다.
기능은 미리 보기 또는 베타 기능을 사용할 수 있습니다.
위와는 달리 미리 보기 기능이 미리 보기가 아닌 기능(예: API 제거 없음)을 방해하지 않을 가능성이 높은 미리 보기 분기 또는 이와 유사한 경우 이 설정을 모델링할 수 있는 기능이 허용됩니다.
예:
- Azure SDK(양식
azure-Xxx)에는 기능이 있습니다public-preview. -
imguiexperimental-docking에는 각 공개 번호가 매겨진 릴리스에 병합 커밋을 추가하는 미리 보기 도킹 브랜치를 활성화하는 기능이 있습니다.
기본 기능은 API를 추가하지 않아야 합니다.
비고
업스트림 빌드 시스템에서 기본적으로 사용하도록 설정된 기능은 해당 기능을 항목에 default-features 추가해야 한다는 의미는 아닙니다. 의도된 목적은 default-features 업스트림에서 내린 결정을 모델링하는 것이 아니라 클래식 모드 사용자에게 편의를 제공하는 것입니다.
기본 기능은 라이브러리를 사용하고 있는지 모르는 고객을 위해 라이브러리의 합리적으로 기능적인 빌드가 설치되도록 하기 위한 것입니다. 라이브러리를 사용하고 있는지 모르는 경우 기능을 나열할 수 없습니다. 예를 들어 libarchive 압축 알고리즘을 사용하도록 설정하는 기능을 기존 제네릭 인터페이스에 노출합니다. 이러한 기능 없이 빌드된 경우 라이브러리에 유틸리티가 없을 수 있습니다.
기본 기능을 사용하지 않도록 설정하는 것은 복잡하기 때문에 기본적으로 기능을 켜야 하는지 여부를 신중하게 고려해야 합니다.
기본 기능을 '전이적' 소비자로 비활성화하려면 다음이 필요합니다.
- 모든 고객은
"default-features": false를 통해 기본 기능을 명시적으로 비활성화하거나 명령줄의 기능 목록에[core]을 포함합니다. -
vcpkg install명령줄에서 전이적 종속성 지정 또는 최상위 매니페스트에서 직접 종속성으로 지정하기
vcpkg의 큐레이팅된 레지스트리에서 기능이 추가 API, 실행 파일 또는 기타 이진 파일을 추가하는 경우 기본적으로 꺼져 있어야 합니다. 확실하지 않은 경우 기능을 기본값으로 표시하지 마세요.
게시된 인터페이스에서 대안을 제어하기 위해 기능을 사용하지 마세요.
포트 소비자가 해당 포트의 핵심 기능에만 의존하는 경우, 기능을 켬으로써 그 기능이 중단되지 않을 가능성이 높습니다. 이는 소비자가 직접 제어하는 것이 아니라 다음과 같은 /std:c++17 / -std=c++17컴파일러 설정에 의해 대체가 제어되는 경우 더욱 중요합니다.
이전 버전과의 호환성을 위해 현재는 허용하지 않는 기존 예제:
-
redis-plus-plus[cxx17]는 폴리필을 제어하지만, 설치된 트리에 설정을 영구적으로 통합하지는 않습니다. -
ace[wchar]는const wchar_t*대신const char*를 수락하도록 모든 API를 변경합니다.
기능은 교체가 설치된 트리에 통합되는 경우 폴리필을 별칭으로 대체할 수 있습니다.
위의 내용에도 불구하고 포트는 특정 기능을 사용하여 폴리필을 제거할 수 있는 경우가 있습니다.
- 기능을 켜면 폴리필이 폴리필링된 엔터티의 별칭으로 변경됩니다.
- 폴리필의 상태가 설치된 헤더에 내장되어 있으며, ABI 불일치로 인한 발생 불가능한 런타임 오류는 발생 가능성이 거의 없습니다.
- 포트의 소비자는 양쪽 모드에서 작동하는 코드를 작성할 수 있습니다. 예를 들어, polyfill이 적용된 typedef을 사용하거나 적용되지 않은 typedef을 사용할 수 있습니다.
예시:
-
abseil[cxx17]은absl::string_view을/를std::string_view로 대체하거나 변경합니다; 패치는 베이킹 요구 사항을 구현합니다.
권장 솔루션
기본 대안을 노출하는 것이 중요한 경우 빌드 시 사용자에게 포트를 프라이빗 오버레이로 복사하는 방법을 지시하는 메시지를 제공하는 것이 좋습니다.
set(USING_DOG 0)
message(STATUS "This version of LibContoso uses the Kittens backend. To use the Dog backend instead, create an overlay port of this with USING_DOG set to 1 and the `kittens` dependency replaced with `dog`.")
message(STATUS "This recipe is at ${CMAKE_CURRENT_LIST_DIR}")
message(STATUS "See the overlay ports documentation at https://github.com/microsoft/vcpkg/blob/master/docs/specifications/ports-overlay.md")
건축 기술
공급업체 종속성 사용 안 함
라이브러리의 포함된 복사본을 사용하지 마세요. 모든 종속성을 분할하고 별도로 패키징하여 업데이트하고 유지 관리해야 합니다.
공급업체 종속성은 안정적이고 일관되며 유지 관리 가능한 패키지 관리 시스템을 제공하는 vcpkg의 목표와 충돌하는 몇 가지 과제를 소개합니다.
업데이트의 어려움: 라이브러리의 포함된 복사본을 사용하면 업스트림 프로젝트에서 보안 패치를 포함한 업데이트를 추적하고 적용하기가 더 어려워집니다. 이로 인해 잠재적인 보안 위험과 에코시스템의 오래된 종속성이 발생합니다.
기호 충돌: 공급업체 종속성으로 인해 여러 패키지에 동일한 라이브러리의 다른 버전이 포함된 경우 기호 충돌이 발생할 수 있습니다.
예를 들어 패키지 A 공급업체 라이브러리 X(버전 1) 및 패키지 B 공급업체 라이브러리 X(버전 2)의 경우 두 패키지를 연결하는 애플리케이션에서 충돌하는 기호로 인해 런타임 오류 또는 정의되지 않은 동작이 발생할 수 있습니다.
vcpkg는 종속성을 별도로 패키징하여 모든 패키지에서 단일 버전의 라이브러리를 사용하도록 보장하여 이러한 충돌을 제거합니다.
라이선싱 규정 준수: 공급업체 종속성은 포함된 라이브러리의 라이선스를 모호하게 만들 수 있으며, 잠재적으로 해당 약관을 위반하거나 호환성 문제를 발생시킬 수 있습니다.
유지 관리 부담 증가: 공급업체 종속성을 업스트림 버전과 동기화 상태로 유지하려면 상당한 수동 작업이 필요하며 패키지 간에 중복된 작업이 발생하는 경우가 많습니다.
CMake를 사용하는 것이 좋습니다.
여러 빌드 시스템을 사용할 수 있는 경우 CMake를 사용하는 것이 좋습니다.
또한 적절한 경우 지시문을 사용하여 file(GLOB) 대체 빌드 시스템을 CMake로 다시 작성하는 것이 더 쉽고 유지 관리가 용이할 수 있습니다.
예: abseil
정적 또는 공유 바이너리 중 하나 선택
CMake 라이브러리를 vcpkg_cmake_configure() 빌드할 때 사용자가 요청한 변형에 따라 BUILD_SHARED_LIBS의 올바른 값을 전달합니다.
를 사용하여 string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" ...)대체 구성 매개 변수를 계산할 수 있습니다.
# portfile.cmake
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" KEYSTONE_BUILD_STATIC)
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" KEYSTONE_BUILD_SHARED)
vcpkg_cmake_configure(
SOURCE_PATH ${SOURCE_PATH}
OPTIONS
-DKEYSTONE_BUILD_STATIC=${KEYSTONE_BUILD_STATIC}
-DKEYSTONE_BUILD_SHARED=${KEYSTONE_BUILD_SHARED}
)
라이브러리에서 빌드 변형을 선택하는 구성 옵션을 제공하지 않는 경우 빌드를 패치해야 합니다. 빌드를 패치할 때는 항상 포트의 향후 유지 관리를 최대화해야 합니다. 일반적으로 이는 현재 문제를 해결하기 위해 처리해야 하는 줄 수를 최소화하는 것을 의미합니다.
예: 원치 않는 변형을 빌드하지 않도록 CMake 라이브러리 패치
예를 들어, CMake 기반 라이브러리를 패치할 때, 필요하지 않은 대상을 EXCLUDE_FROM_ALL에 추가하고 install(TARGETS ...) 호출을 if(BUILD_SHARED_LIBS)로 래핑하는 것만으로 충분할 수 있습니다. 이는 원치 않는 변형을 언급하는 모든 줄을 래핑하거나 삭제하는 것보다 짧습니다.
다음 내용이 포함된 프로젝트의 CMakeLists.txt 경우:
add_library(contoso SHARED contoso.c)
add_library(contoso_static STATIC contoso.c)
install(TARGETS contoso contoso_static EXPORT ContosoTargets)
install(EXPORT ContosoTargets
FILE ContosoTargets
NAMESPACE contoso::
DESTINATION share/contoso)
install(TARGETS) 줄만 패치해야 합니다.
add_library(contoso SHARED contoso.c)
add_library(contoso_static STATIC contoso.c)
if(BUILD_SHARED_LIBS)
set_target_properties(contoso_static PROPERTIES EXCLUDE_FROM_ALL 1)
install(TARGETS contoso EXPORT ContosoTargets)
else()
set_target_properties(contoso PROPERTIES EXCLUDE_FROM_ALL 1)
install(TARGETS contoso_static EXPORT ContosoTargets)
endif()
install(EXPORT ContosoTargets
FILE ContosoTargets
NAMESPACE contoso::
DESTINATION share/contoso)
기능을 정의할 때 종속성을 명시적으로 제어합니다.
선택적 종속성을 캡처하는 기능을 정의할 때 기능이 명시적으로 사용하도록 설정되지 않은 경우 종속성이 실수로 사용되지 않도록 합니다.
set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB ON)
set(CMAKE_REQUIRE_FIND_PACKAGE_ZLIB OFF)
if ("zlib" IN_LIST FEATURES)
set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB OFF)
set(CMAKE_REQUIRE_FIND_PACKAGE_ZLIB ON)
endif()
vcpkg_cmake_configure(
SOURCE_PATH ${SOURCE_PATH}
OPTIONS
-DCMAKE_DISABLE_FIND_PACKAGE_ZLIB=${CMAKE_DISABLE_FIND_PACKAGE_ZLIB}
-DCMAKE_REQUIRE_FIND_PACKAGE_ZLIB=${CMAKE_REQUIRE_FIND_PACKAGE_ZLIB}
)
아래 사용 vcpkg_check_features() 코드 조각은 동일합니다.
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
FEATURES
"zlib" CMAKE_REQUIRE_FIND_PACKAGE_ZLIB
INVERTED_FEATURES
"zlib" CMAKE_DISABLE_FIND_PACKAGE_ZLIB
)
vcpkg_cmake_configure(
SOURCE_PATH ${SOURCE_PATH}
OPTIONS
${FEATURE_OPTIONS}
)
ZLIB은 코드 조각에서 대소문자를 구분합니다. 자세한 내용은 CMAKE_DISABLE_FIND_PACKAGE_<PackageName> 및 CMAKE_REQUIRE_FIND_PACKAGE_<PackageName> 문서를 참조하세요.
충돌하는 라이브러리를 manual-link 디렉터리에 배치하세요.
lib는 다음 중 어느 것을 수행하는 경우 충돌하는 것으로 간주됩니다.
- 정의
main - malloc를 정의하다
- 다른 라이브러리에도 선언된 기호 정의
충돌하는 라이브러리는 보통 일부러 그렇게 설계된 것이며, 결함으로 간주되지 않습니다. 일부 빌드 시스템은 lib 디렉터리의 모든 항목에 연결되므로 이름이 지정된 manual-link하위 디렉터리로 이동해야 합니다.
미리 빌드된 바이너리 파일 설치
미리 빌드된(이진 전용) 아티팩트를 설치하는 포트는 허용되지만 다른 포트의 버전 변경을 효과적으로 차단하지 않는 경우 사용하지 않는 것이 좋습니다. 컴파일러 또는 플래그를 변경하는 모든 vcpkg 설정을 준수하기 때문에 원본에서 빌드하는 것이 좋습니다.
다음 조건을 모두 충족하는 포트를 거부합니다.
- 원본에서 빌드하는 대신 미리 컴파일된 바이너리를 설치하고
- 해당 이진 파일들은 큐레이션된 레지스트리의 다른 포트가 제공하는 종속성을 현재 가지고 있거나 런타임 시 필요로 합니다.
- 설치된 아티팩트는 vcpkg의 배포된 링크 도메인에 통합됩니다. 즉, 이는 다운스트림 포트나 사용자 프로젝트가 연결해야 하는 라이브러리/헤더/CMake 또는 pkg-config 메타데이터를 설치하는 것을 의미합니다.
근거: 이 조합은 종속성 그래프의 ABI를 업스트림 미리 빌드된 버전에 효과적으로 잠깁니다. vcpkg는 ODR/ABI가 미묘하게 깨짐으로서 미리 빌드된 라이브러리에 연결하는 소비자가 위험을 겪지 않도록 적절하게 zlib, openssl 등 유사한 종속성을 업데이트할 수 없으며, 이로 인해 사용자가 중요한 보안 패치를 놓칠 위험이 있습니다.
"게시된 링크 도메인 입력"은 일반적으로 다음 중 어느 것을 의미합니다.
- 소비자가 연결할
.lib,.a,.so,.dylib와 같은 라이브러리를 설치하거나 가져오기. - 직접 또는 인라인/템플릿 코드를 통해 다른 vcpkg 포트에서 기호, 형식 또는 매크로를 참조하는 헤더 전달
- 다른 vcpkg 포트에서
find_dependency()/Requires:을 호출하도록 하는 CMake 구성/pkg-config 파일 설치
허용되는(하지만 여전히 권장되지 않는) 시나리오:
- 호스트 전용 도우미 도구(실행 파일)는 빌드 타임에 사용되며, 이 도구의 출력은 활용되지만 종속 포트에 의해 링크되지 않습니다. 이들은 종속성을 개인적으로 번들하거나, 유비쿼터스 시스템 런타임 라이브러리에만 의존합니다.
- 모든 OSS 종속성을 정적으로 연결하고 설치된 헤더 또는 내보낸 인터페이스를 통해 해당 기호 또는 형식을 노출하지 않는 완전히 자체 포함된 미리 빌드된 라이브러리(소비자는 전이적 ABI를 관찰하거나 종속할 수 없음).
- 사용자 코드에 연결되지 않은 데이터 전용, 펌웨어 또는 자산 패키지입니다.
사용할 수 없는 예:
- 미리 빌드된
libfoo로,lib/libfoo.lib외에<zlib.h>가 포함된 헤더를 설치하여 특정zlib버전에 맞춰 컴파일됩니다. 이후 소비자는 기대하는 호환성을 위해libfoo에 연결합니다. - 이전 OpenSSL 릴리스에 대해 이진 파일이 컴파일되는 동안 CMake 패키지 파일 호출
find_dependency(OpenSSL)을 설치하는 미리 빌드된 SDK입니다.
완화 방법/대안:
- 업스트림 스크립트를 사용하여 원본에서 빌드를 제공하거나 얇은 CMake 래퍼를 추가합니다.
- 업스트림에 소스 기반 릴리스 또는 재현 가능한 빌드 지침을 게시하도록 요청하십시오.
portfile.cmake또는vcpkg.json의 주석에 업스트림 문제/PR을 연결하십시오. - 이러한 규칙을 충족할 수 없는 조직별 미리 빌드된 항목에는 오버레이 포트 또는 프라이빗 레지스트리를 사용합니다.
버전 관리
필드에 대한 일반적인 규칙 따르기 "version"
새 포트를 만들 때 패키지 작성자가 사용하는 버전 관리 규칙을 따릅니다. 포트를 업데이트할 때 업스트림이 달리 명시하지 않는 한 동일한 규칙을 계속 사용합니다. 규칙에 대한 전체 설명은 버전 관리 설명서를 참조하세요.
업스트림에서 릴리스를 게시하지 않은 경우 최신 변경 내용을 가져오기 위해 포트의 버전 관리 체계 version-date 를 변경하지 마세요. 이러한 커밋에는 프로덕션 준비가 되지 않은 변경 내용이 포함될 수 있습니다. 대신 업스트림 리포지토리에 새 릴리스를 게시하도록 요청합니다.
· "port-version" 필드를 수정된 포트의 매니페스트 파일에서 업데이트하십시오.
vcpkg는 이 필드를 사용하여 지정된 포트가 만료되었는지 여부를 확인하고 포트의 동작이 변경될 때마다 변경해야 합니다.
그 규칙은 업스트림 버전에는 영향을 주지 않는 포트의 변경에 대해 `"port-version"` 필드를 사용하고, 업스트림 버전 업데이트가 이루어질 때 `"port-version"`을 0으로 초기화하는 것입니다.
예를 들면 다음과 같습니다.
- Zlib의 패키지 버전은 현재
1.2.1이며, 명시적인"port-version"은 없고 ("port-version"의0에 해당)입니다. - 잘못된 저작권 파일이 배포된 것을 발견하고 포트파일에서 수정했습니다.
- 매니페스트 파일
"port-version"의1필드를 .로 업데이트해야 합니다.
자세한 내용은 버전 관리 설명서를 참조하세요.
수정된 포트의 versions/ 버전 파일 업데이트
vcpkg는 메타데이터 파일 집합을 사용하여 버전 관리 기능을 지원합니다. 이러한 파일은 다음 위치에 있습니다.
-
${VCPKG_ROOT}/versions/baseline.json, (이 파일은 모든 포트에 공통) 및 -
${VCPKG_ROOT}/versions/${first-letter-of-portname}-/${portname}.json(포트당 하나씩).
예를 들어 관련 파일의 경우 zlib 다음과 같습니다.
${VCPKG_ROOT}/versions/baseline.json${VCPKG_ROOT}/versions/z-/zlib.json
포트를 업데이트할 때마다 해당 버전 파일도 업데이트할 것으로 예상됩니다.
이러한 파일을 업데이트하는 권장 방법은 다음과 같은 명령을 실행하는 x-add-version 것입니다.
vcpkg x-add-version zlib
여러 포트를 동시에 업데이트하는 경우 다음을 실행할 수 있습니다.
vcpkg x-add-version --all
수정된 모든 포트에 대한 파일을 한 번에 업데이트합니다.
자세한 내용은 버전 관리 참조 및 레지스트리 문서를 참조하세요.
수정 작업
vcpkg는 배포하는 구성 요소의 최종 소유자가 아닌 패키징 솔루션입니다. 플랫폼과의 구성 요소 호환성 또는 구성 요소의 호환성을 개선하기 위해 경우에 따라 패치를 적용해야 합니다.
- 다음과 같은 패치를 방지하려고 합니다.
- 업스트림은 동의하지 않을 것입니다.
- 취약성 또는 충돌 원인
- 업스트림 버전 업데이트에서 유지 관리할 수 없습니다.
- vcpkg 리포지토리 자체와의 라이선스 엉킴을 일으킬 정도로 충분히 큽니다.
상위 소유자에게 상위 관련 패치를 알리십시오.
패치가 업스트림에서 유용할 수 있는 경우 업스트림에 패치의 콘텐츠에 대한 알림을 받아야 합니다. (vcpkg에 특정하고 업스트림과 관련이 없는, 예를 들어 종속성을 제거하는 패치의 적용은 알림이 필요하지 않습니다.)
업스트림이 패치에 동의하지 않는 상황을 방지하기 위해 이러한 패치를 적용하기 위해 최소 30일을 기다립니다.
변경 내용이 정확하다는 확신이 높은 경우 이 대기 기간을 건너뜁니다. 높은 신뢰도 패치의 예로는 다음이 포함되지만 제한되지는 않습니다.
- 업스트림이 패치로 승인한 경우(예: 업스트림에서 병합된 끌어오기 요청의 특정 변경 사항을 백포팅하는 경우)
- 누락된
#includes를 추가합니다. - 작고 명백한 제품 코드 수정(예: 초기화되지 않은 변수 초기화).
- 테스트 또는 예제와 같은 빌드의 관련 없는 vcpkg 구성 요소를 사용하지 않도록 설정
패치보다 옵션 선호
설정을 직접 패치하는 것보다 호출 vcpkg_configure_xyz()에서 옵션을 설정하는 것이 좋습니다.
패치를 방지할 수 있는 일반적인 옵션:
- [MSBUILD]
<PropertyGroup>매개 변수를 통해/p:프로젝트 파일 내의 설정을 재정의할 수 있습니다. - [CMAKE] CMake 스크립트에서
find_package(XYz)호출은-DCMAKE_DISABLE_FIND_PACKAGE_XYz=ON을 통해 비활성화할 수 있습니다. - [CMAKE] 캐시 변수(로 선언된
set(VAR "value" CACHE STRING "Documentation")또는option(VAR "Documentation" "Default Value"))는 명령줄에서-DVAR:STRING=Foo로 전달하여 재정의할 수 있습니다. 한 가지 주목할 만한 예외는FORCE매개 변수가set()에 전달되는 경우입니다. 자세한 내용은 CMakeset설명서를 참조하세요.
포트에 체크 인하는 대신 승인된 패치를 다운로드하는 것이 좋습니다.
승인되거나 병합된 패치 파일을 업스트림에서 가져올 수 있는 경우 포트는 이를 다운로드하여 포트 파일의 일부로 사용하는 대신 적용해야 합니다. 이 프로세스는 다음과 같은 이유로 선호됩니다.
- 업스트림이 패치 변경 내용을 수락했는지 확인합니다.
- 책임을 초기 단계로 이동하여 검토 프로세스를 간소화합니다.
- 패치를 사용하지 않는 사용자의 vcpkg 리포지토리 크기를 줄입니다.
- vcpkg 리포지토리와 라이선스 충돌 방지
SHA 충돌을 방지하려면 안정적인 엔드포인트에서 패치를 다운로드해야 합니다.
끌어오기 요청에서 패치 파일을 다운로드하거나 GitHub 및 GitLab에서 커밋할 때 매개 변수를 ?full_index=1 다운로드 URL에 추가해야 합니다.
예:
https://github.com/google/farmhash/pull/40.diff?full_index=1https://github.com/linux-audit/audit-userspace/commit/f8e9bc5914d715cdacb2edc938ab339d5094d017.patch?full_index=1https://gitlab.kitware.com/paraview/paraview/-/merge_requests/6375.diff?full_index=1
값을 덮어쓰는 것보다 패치하는 것을 선호합니다 VCPKG_<VARIABLE>.
VCPKG_<VARIABLE>로 시작하는 일부 변수에는 해당하는 CMAKE_<VARIABLE> 변수가 있습니다.
그러나 모든 패키지가 내부 패키지 빌드 에 전달되는 것은 아닙니다(구현 참조: Windows 도구 체인).
다음 예시를 참조하세요.
set(VCPKG_C_FLAGS "-O2 ${VCPKG_C_FLAGS}")
set(VCPKG_CXX_FLAGS "-O2 ${VCPKG_CXX_FLAGS}")
기본 제공 도구 체인을 사용하면 vcpkg값 VCPKG_<LANG>_FLAGS 이 적절한 CMAKE_LANG_FLAGS 변수로 전달되기 때문에 작동합니다. 그러나 vcpkg의 변수를 인식하지 못하는 사용자 지정 도구 체인은 이를 전달하지 않습니다.
이 때문에 CMAKE_<LANG>_FLAGS를 설정할 때 빌드 시스템을 직접 패치하는 것이 바람직합니다.
패치 최소화
라이브러리를 변경할 때 최종 차이 최소화를 위해 노력합니다. 즉, 지역에 영향을 주는 변경을 수행할 때 업스트림 소스 코드를 다시 포맷해서는 안 됩니다. 조건부 사용을 해제할 때는 조건부의 모든 줄을 삭제하는 것보다 조건에 AND FALSE 또는 && 0을 추가하는 것이 좋습니다. 비활성화해야 하는 큰 영역이 있는 경우, 패치의 모든 줄을 삭제하는 것보다 해당 영역을 if(0) 또는 #if 0으로 둘러싸는 것이 더 간단합니다.
포트가 오래된 경우 패치를 추가하지 마세요. 최신 릴리스 버전으로 포트를 업데이트하면 동일한 문제가 해결됩니다. vcpkg는 오래된 버전 패치보다 포트를 업데이트하는 것을 선호합니다.
이렇게 하면 vcpkg 리포지토리의 크기를 줄이면서 패치가 향후 코드 버전에 적용될 가능성을 높일 수 있습니다.
패치에서 기능 구현 안 함
vcpkg에서 패치를 적용하는 목적은 컴파일러, 라이브러리 및 플랫폼과의 호환성을 사용하도록 설정하는 것입니다. 적절한 오픈 소스 프로시저(문제/PR/등 제출)를 따르는 대신 새 기능을 구현하지 않습니다.
기본적으로 테스트/문서/예제를 빌드하지 마세요.
새 포트를 제출할 때 BUILD_TESTS나 WITH_TESTS 또는 POCO_ENABLE_SAMPLES와 같은 옵션을 확인하고, 추가 이진 파일이 비활성화되었는지 확인합니다. 이렇게 하면 평균 사용자에 대한 빌드 시간과 종속성이 최소화됩니다.
필요에 따라 테스트를 빌드할 수 있는 기능을 추가할 수 있지만, 이 기능은 목록에 포함되지 않아야 합니다.
라이브러리의 기존 사용자가 vcpkg로 전환할 수 있도록 설정
추가하지 마십시오 CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
라이브러리 작성자가 이미 사용하고 있지 않으면 C++ 템플릿과 제대로 상호 작용하지 않고 특정 컴파일러 기능을 중단하므로 이 CMake 기능을 사용하면 안 됩니다. .def 파일을 제공하지 않고 __declspec() 선언을 사용하지 않는 라이브러리는 Windows용 공유 빌드를 지원하지 않으므로 다음과 같이 표시해야 합니다.
if(VCPKG_TARGET_IS_WINDOWS)
vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
endif()
업스트림에서 지정한 이름 외부에 있는 이진 파일의 이름을 바꾸지 마세요.
즉, 업스트림 라이브러리의 릴리스 및 디버그 이름(libx 및 libxd)이 서로 다른 경우 디버그 라이브러리의 이름을 바꿔 libx서는 안 됩니다. 그 반대로, 업스트림 라이브러리가 릴리스 및 디버그에서 동일한 이름을 갖는 경우 새 이름을 도입해서는 안 됩니다.
중요한 주의 사항:
- 정적 및 공유 변형의 이름을 일반적인 체계로 바꿔야 하는 경우가 많습니다. 이를 통해 소비자는 일반 이름을 사용하고 다운스트림 연결을 무시할 수 있습니다. 한 번에 하나씩만 사용할 수 있기 때문에 안전합니다.
라이브러리에서 CMake 통합 파일()foo-config.cmake을 생성하는 경우 단순히 출력 보관 파일/LIB를 호출 file(RENAME) 하는 대신 CMake 빌드 자체를 패치하여 이름을 변경해야 합니다.
마지막으로 Windows의 DLL 파일은 생성된 LIB를 중단하므로 빌드 후 이름을 바꿔서는 안 됩니다.
매니페스트
매니페스트 파일의 형식을 지정해야 합니다. 다음 명령을 사용하여 모든 매니페스트 파일의 서식을 지정합니다.
> vcpkg format-manifest --all
쌍둥이
현재는 공동체 외의 트리플렛 추가 요청을 수락하지 않습니다. 커뮤니티에서 완전한 트리플릿 상태로 승격되는 것은 주로 이러한 트리플릿을 테스트할 하드웨어 예산에 기반하며, vcpkg에서 제출된 메트릭에 의해 사람들이 실제로 사용하는 것이 완전히 테스트될 가능성을 최대화할 수 있도록 구동될 것입니다.
다음과 같은 경우 커뮤니티 트리플렛을 추가합니다.
- 사람들이 실제로 그 커뮤니티 3중 구조를 사용한다는 것이 입증되었습니다.
- 우리는 그러한 삼둥이가 깨졌다는 것을 알지 못합니다.
예를 들어, 작성자가 실제로 이런 항목을 사용할 것이라는 의미가 아니라 단순히 "집합을 완료"하려는 것이었기 때문에 삼중항 https://github.com/microsoft/vcpkg/pull/29034을 추가하지 않았으며, 결과를 재배치할 수 있는 patchelf 솔루션이 만들어질 때까지 linux-dynamic을 추가하지 않았습니다.
유용한 구현 정보
포트파일은 스크립트 모드에서 실행됩니다.
portfile.cmake's 및 CMakeLists.txt's는 일반적인 구문과 핵심 CMake 언어 구문(즉, "스크립팅 명령")을 공유하지만 포트파일은 "스크립트 모드"에서 실행되는 반면 CMakeLists.txt 파일은 "프로젝트 모드"에서 실행됩니다. 이러한 두 모드 간의 가장 중요한 차이점은 "스크립트 모드"에 "도구 체인", "언어" 및 "대상" 개념이 없다는 것입니다. 이러한 구문(예: CMAKE_CXX_COMPILER, CMAKE_EXECUTABLE_SUFFIXCMAKE_SYSTEM_NAME)에 따라 달라지는 스크립팅 명령을 비롯한 모든 동작은 올바르지 않습니다.
포트파일은 트리플릿 파일에 설정된 변수에 직접 액세스할 수 있지만, CMakeLists.txt는 그렇지 않습니다 (대신 VCPKG_LIBRARY_LINKAGE와 BUILD_SHARED_LIBS 간에 번역이 발생하는 경우가 많습니다).
포트파일에서 호출된 포트파일 및 프로젝트 빌드는 서로 다른 프로세스에서 실행됩니다. 개념적:
+----------------------------+ +------------------------------------+
| CMake.exe | | CMake.exe |
+----------------------------+ +------------------------------------+
| Triplet file | ====> | Toolchain file |
| (x64-windows.cmake) | | (scripts/buildsystems/vcpkg.cmake) |
+----------------------------+ +------------------------------------+
| Portfile | ====> | CMakeLists.txt |
| (ports/foo/portfile.cmake) | | (buildtrees/../CMakeLists.txt) |
+----------------------------+ +------------------------------------+
포트파일의 호스트를 확인하기 위해 표준 CMake 변수는 괜찮습니다(CMAKE_HOST_WIN32).
포트파일에서 대상을 확인하려면 vcpkg triplet 변수를 사용해야 합니다(VCPKG_CMAKE_SYSTEM_NAME).
가능한 설정의 전체 목록을 보려면 삼중 문서도 참조하세요.
vcpkg