メンテナー ガイド
このドキュメントでは、ポートレシピを追加または更新するときに適用する必要がある一連のポリシーの一覧を示します。 これは、 Debian のポリシー マニュアル、 Homebrew のメンテナー ガイドライン、および Homebrew の数式クックブックの役割を果たすことを目的としています。
レジストリの全体的な設計目標
現在のベースラインのポートを同時にインストールできる必要がある
キュレーションされたレジストリ内のライブラリのダウンストリーム ユーザーに、発行する特定のベースライン内のライブラリの組み合わせが、少なくとも一部の構成で連携するようにテストされていることを示したいと考えます。 ポートを互いに除外できるようにすると、このようなテストに必要なビルドの数が 2^number_of_such_cases
に増えるので、このような構成をテストする機能が中断されます。 さらに、追加の依存関係のインストールは常に "安全" と見なされます。ポートまたはエンド ユーザーが依存関係が要件にインストールをアサートする方法はありません。
このような別の状況をユーザーに対して表現する場合は、キュレーションされたレジストリの継続的インテグレーションに組み込まれたポートを追加するのではなくportfile.cmake
にコメントを含む代替フォームを実装して、overlay ポートを作成する方法を説明することを検討してください。 たとえば、 glad@0.1.36 を参照してください。
registriesの導入前に、オーバーレイ ポートの作成を容易にする可能性がある、boringssl
など、テストされていないポートをいくつか受け入れることができました。 レジストリでは、キュレーションされたレジストリを変更せずに、これらの未テストポートの発行が許可されるため、これは受け入れなくなりました。
PR 構造体
ポートごとに個別のプル要求を行う
可能な限り、変更を複数の PR に分割します。 これにより、レビューが大幅に容易になり、1 つの一連の変更に関する問題が他の変更ごとに保持されるのを防ぐことができます。
変更されていないファイルの簡単な変更を回避する
たとえば、問題を修正する理由がないポートファイル内の変数の再フォーマットや名前変更は避けてください。 しかし、PRの主な目的(ライブラリの更新)のためにファイルを変更する必要がある場合は、タイプミスの修正のような明らかに有益な変更が評価されます!
他のリポジトリに対して名前を確認する
ポート名は、ポートがインストールするパッケージを明確にするように試みる必要があります。 理想的には、検索エンジンでポートの名前を検索すると、対応するプロジェクトにすばやく移動します。 複数のリポジトリにまたがる多数のパッケージ名を一度にチェックする優れたサービスは、 Repologyです。
短い名前または一般的な単語の名前が付いたプロジェクトでは、特定の単語に強い関連付けを持つプロジェクトがない場合に、明確さが必要になる場合があります。 たとえば、 ip
という名前のポートは、複数のプロジェクトに同様の名前が付けられる可能性があるため、受け入れできません。
適切なあいまいさを解消する例を次に示します。
- リポジトリの所有者のユーザー名または組織:
google-cloud-cpp
。 - プロジェクトが含まれるライブラリスイートの名前:
boost-dll
。
C++ および オープンソース プロジェクトで使用される一般的なプレフィックスとサフィックスは、有効なあいまいさを解消できません。一部の例は次のとおりですが、これらに限定されません。
cpp
,free
,lib
,open
,- 番号
たとえば、次のポート名を比較する場合: ip-cpp
、 libip
、および ip5
、無効なあいまいさを除去すると、それらはすべて同じステム (ip
) に減少するため、同じ名前であると見なされます。
このガイドラインの例外は、1 つのプロジェクトに厳密に関連付けられている名前に対して行われます。 たとえば、libpng
、openssl
、zlib
のようにします。
GitHub ドラフト PR を使用する
GitHub Draft PR は、まだマージする準備ができていない作業に関する CI または人間のフィードバックを得るための優れた方法です。 ほとんどの新しい PR は下書きとして開き、CI が通過したら通常の PR に変換する必要があります。
GitHub Draft PR の詳細については、「 ドラフト pull requests の概要を参照してください。
Portfiles
非推奨のヘルパー関数を回避する
現時点では、次のヘルパーは非推奨となっています。
vcpkg_extract_source_archive_ex()
vcpkg_extract_source_archive()
のサポートされているオーバーロードに置き換える必要があります (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
and
> vcpkg install b
b
によってインストールされたファイルは、a
の以前のインストールによる影響に関係なく、同じである必要があります。 つまり、ポートは、何らかのアクションを実行する前に、別のポートによってインストールされたツリーに何かが提供されているかどうかを検出しようとしないでください。 このような "パス依存" 動作の具体的で一般的な原因については、以下の「機能を定義する場合、依存関係を明示的に制御する」で説明します。
一意のポート属性ルール
vcpkg システム全体では、ユーザーが同時に使用する必要がある 2 つのポートが同じファイルを提供する可能性はありません。 ポートが別のファイルによって既に提供されているファイルをインストールしようとすると、インストールは失敗します。 たとえば、ポートでヘッダーに非常に一般的な名前を使用する場合は、それらのヘッダーを include
ではなくサブディレクトリに配置する必要があります。
このプロパティは、レジストリにすべてのポートをインストールしようとする継続的インテグレーション実行によって定期的にチェックされます。これは、2 つのポートが同じファイルを提供する場合、 FILE_CONFLICTS
で失敗します。
非公式の名前空間に CMake エクスポートを追加する
vcpkg の中心的な設計の理想は、ユーザーに対して "ロックイン" を作成しないことです。 ビルド システムでは、システムのライブラリと vcpkg のライブラリに応じて違いはありません。 そのため、CMake エクスポートまたはターゲットを既存のライブラリに "わかりやすい名前" で追加することは避け、アップストリームは vcpkg と競合することなく独自の公式の CMake エクスポートを追加できます。
そのためには、アップストリーム ライブラリにないポートがエクスポートする CMake 構成には、プレフィックスとして unofficial-
する必要があります。 追加のターゲットは、 unofficial::<port>::
名前空間に存在する必要があります。
これは、ユーザーに次の情報が表示されることを意味します。
find_package(unofficial-<port> CONFIG)
一意の vcpkg パッケージを取得する方法としてunofficial::<port>::<target>
そのポートからエクスポートされたターゲットとして。
例 :
brotli
はunofficial-brotli
パッケージを作成し、ターゲットunofficial::brotli::brotli
を生成します。
著作権ファイルをインストールする
各ポートは、フォルダー ${CURRENT_PACKAGES_DIR}/share/${PORT}
に copyright
という名前のファイルを提供する必要があります。 パッケージのライセンス コンテンツをソース ファイル内で使用できる場合は、 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
]])
ポートのバージョン制約
ポート内のバージョン制約は、プロジェクトの独立した進化を妨げる可能性があるため、通常は避ける必要があります。 このような制約の追加は、特定の以前のバージョンとの互換性がない実証済みなど、適切に文書化された正当な理由がある場合にのみ許容されます。 これらの制約は、独立したプロジェクトとの同等性を維持するためだけに使用しないでください。
機能
機能を使用して代替手段を実装しない
特徴は追加機能として扱う必要があります。 port[featureA]
インストールしてインストールをport[featureB]
する場合は、port[featureA,featureB]
インストールする必要があります。 さらに、2 つ目のポートが [featureA]
に依存し、3 つ目のポートが [featureB]
に依存している場合は、2 番目と 3 番目のポートの両方をインストールすると、依存関係が満たされている必要があります。
この状況のライブラリでは、vcpkg で表される使用可能なオプションのいずれかを選択する必要があり、別の設定を必要とするユーザーは、現時点でオーバーレイ ポートを使用する必要があります。
旧バージョンとの互換性を保つために、現在は受け入れられない既存の例:
libgit2
libzip
、open62541
はすべて、TLS または暗号化バックエンドを選択するための機能を備えています。curl
には異なる暗号化バックエンド オプションがありますが、実行時に選択できます。つまり、上記のテネットが維持されます。darknet
には、依存関係に使用する opencv のバージョンを制御するopencv2
、opencv3
機能があります。
機能はプレビュー機能またはベータ版の機能を利用する場合があります
上記にかかわらず、プレビュー機能がプレビュー以外の機能 (API の削除なしなど) を中断しない可能性が高いプレビュー ブランチなどがある場合は、この設定をモデル化できます。
例 :
- (フォーム
azure-Xxx
の) Azure SDK には、public-preview
機能があります。 imgui
には、各パブリック番号付きリリースにアタッチされたマージ コミットを使用するプレビュー ドッキング ブランチを使用するexperimental-docking
機能があります。
既定の機能では API を追加できません
既定の機能は、ライブラリを使用していることを知らないお客様に対して、ライブラリの合理的に機能的なビルドが確実にインストールされるようにするためのものです。 ライブラリを使用していることを知らない場合は、機能を一覧表示することはできません。 たとえば、 libarchive
は、圧縮アルゴリズムを有効にする機能を既存の汎用インターフェイスに公開します。そのような機能を使用せずにビルドされた場合、ライブラリにはユーティリティがない可能性があります。
既定の機能の無効化は複雑であるため、機能を既定でオンにする必要があるかどうかを慎重に検討する必要があります。
"推移的" コンシューマーとして既定の機能を無効にする場合は、次のものが必要です。
- すべてのお客様は、
"default-features": false
を使用して既定の機能を明示的に無効にするか、コマンド ラインの機能リストに[core]
を含めます。 vcpkg install
コマンド ラインに推移的な依存関係の名前を付けるか、最上位レベルのマニフェストで直接依存関係として名前を付ける
vcpkg のキュレーション レジストリでは、機能によって追加の API、実行可能ファイル、またはその他のバイナリが追加される場合は、既定でオフになっている必要があります。 不明な場合は、機能を既定としてマークしないでください。
発行済みインターフェイスの代替機能を制御するために機能を使用しない
ポートのコンシューマーがそのポートのコア機能のみに依存している場合、高い確率で機能をオンにして破損してはなりません。 これは、代替手段がコンシューマーによって直接制御されるのではなく、 /std:c++17
/ -std=c++17
などのコンパイラ設定によって制御される場合にさらに重要になります。
旧バージョンとの互換性を保つために、現在は受け入れられない既存の例:
redis-plus-plus[cxx17]
はポリフィルを制御しますが、設定をインストール済みのツリーにベイクしません。ace[wchar]
は、const char*
ではなくconst wchar_t*
を受け入れるようにすべての API を変更します。
インストールされているツリーに置換が組み込まれている場合、機能によってポリフィルがエイリアスに置き換えられる場合があります
上記にかかわらず、ポートは、次の場合に限り、機能を備えたポリフィルを削除できます。
- この機能をオンにすると、ポリフィルがポリフィルエンティティのエイリアスに変更されます
- ABI の不一致 "あり得ない" ランタイム エラーが発生する可能性が低い、ポリフィルの状態がインストールされているヘッダーに組み込まれている
- ポートのコンシューマーは、両方のモードで動作するコードを記述できます。たとえば、ポリフィルされる 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")
ビルド手法
ベンダーの依存関係を使用しない
ライブラリの埋め込みコピーは使用しないでください。 更新および保守できるように、すべての依存関係を分割して個別にパッケージ化する必要があります。
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>
のドキュメントを参照してください。
競合する lib を manual-link
ディレクトリに配置する
次のいずれかの場合、lib は競合すると見なされます。
- 定義する
main
- malloc の定義
- 他のライブラリでも宣言されているシンボルを定義する
競合するライブラリは通常、設計上のものであり、欠陥とは見なされません。 一部のビルド システムは lib ディレクトリ内のすべてにリンクするため、 manual-link
という名前のサブディレクトリに移動する必要があります。
バージョン管理
"version"
フィールドの一般的な規則に従う
新しいポートを作成するときは、パッケージ作成者が使用するバージョン管理規則に従ってください。 ポートを更新する場合は、アップストリームで特に断りがない限り、引き続き同じ規則を使用します。 規則の詳細については、 バージョン管理に関するドキュメントを参照してください。
アップストリームがしばらくリリースを公開していない場合は、最新の変更を取得するために、ポートのバージョン管理スキームを version-date
に変更しないでください。 これらのコミットには、運用環境の準備ができていない変更が含まれる場合があります。 代わりに、アップストリーム リポジトリに新しいリリースを発行するよう依頼してください。
変更されたポートのマニフェスト ファイルの "port-version"
フィールドを更新します
vcpkg は、このフィールドを使用して、特定のポートが古く、ポートの動作が変更されるたびに変更する必要があるかどうかを判断します。
この規則では、アップストリーム バージョンを変更しないポートへの変更に "port-version"
フィールドを使用し、アップストリーム バージョンへの更新が行われたときに "port-version"
をゼロにリセットします。
例:
- Zlib のパッケージ バージョンは現在
1.2.1
されており、明示的な"port-version"
はありません (0
の"port-version"
に相当します)。 - 間違った著作権ファイルがデプロイされていることを発見し、ポートファイル内で修正しました。
- マニフェスト ファイルの
"port-version"
フィールドを1
に更新する必要があります。
詳細については、 バージョン管理のドキュメント を参照してください。
変更されたポートの versions/
でバージョン ファイルを更新する
vcpkg は、一連のメタデータ ファイルを使用してバージョン管理機能を強化します。 これらのファイルは、次の場所にあります。
${VCPKG_ROOT}/versions/baseline.json
、(このファイルはすべてのポートに共通です)、${VCPKG_ROOT}/versions/${first-letter-of-portname}-/${portname}.json
(ポートごとに 1 つ)。
たとえば、関連するファイル 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
変更されたすべてのポートのファイルを一度に更新します。
Note
これらのコマンドを実行する前に、変更をポートにコミットしておく必要があります。 その理由は、これらのバージョン ファイルにはポート ディレクトリの Git SHA が必要であるためです。 ただし、コミットされていないローカル変更がある場合は、 x-add-version
コマンドによって警告が表示されます。
詳細については、「 バージョン管理のリファレンス および レジストリの作成を参照してください。
Patching
vcpkg はパッケージ ソリューションであり、デプロイするコンポーネントの最終的な所有者ではありません。 場合によっては、コンポーネントとプラットフォームの互換性、またはコンポーネントの互換性を向上させるために、パッチを適用する必要があります。
- 次の修正プログラムを回避する必要があります。
- アップストリームは、次の場合と一致しません
- 脆弱性やクラッシュを引き起こす
- アップストリーム バージョンの更新プログラム全体を維持することは不可能です
- は、vcpkg リポジトリ自体とライセンスの絡み合いを引き起こすのに十分な大きさです
アップストリーム関連パッチについてアップストリーム所有者に通知する
アップストリームでパッチが役に立つ可能性がある場合は、アップストリームにパッチの内容を通知する必要があります。 (依存関係の開発など、アップストリームに関係のない vcpkg 固有の動作を適用するパッチでは、通知は必要ありません)。
アップストリームがパッチと一致しない状況を回避するために、そのようなパッチの適用を少なくとも 30 日間待ちます。
変更が正しいという確信が高い場合は、この待機期間をスキップします。 信頼度の高いパッチの例としては、次のようなものがありますが、これらに限定されません。
- アップストリームのパッチとしての受け入れ (たとえば、プル要求アップストリームからの特定の変更のバックポートがマージされました)。
- 不足している
#include
を追加する。 - 小規模で明白な製品コードの修正 (初期化されていない変数の初期化など)。
- テストや例など、ビルドの無関係な 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
として渡すだけでオーバーライドできます。 注目すべき例外の 1 つは、FORCE
パラメーターがset()
に渡される場合です。 詳細については、 CMakeset
のドキュメントを参照してください。
承認されたパッチをポートにチェックインするよりもダウンロードを優先する
承認されたパッチ ファイルまたはマージされたパッチ ファイルをアップストリームから取得できる場合は、ポート ファイルの一部として取得するのではなく、それらをダウンロードして適用する必要があります。 このプロセスは、次の理由で優先されます。
- アップストリームがパッチの変更を受け入れたことを確認します
- onus をアップストリームにシフトすることで、レビュー プロセスを簡略化します。
- パッチを使用していないユーザーの vcpkg リポジトリ のサイズを小さくします
- vcpkg リポジトリとのライセンスの競合を回避します
SHA の競合を回避するには、安定したエンドポイントからパッチをダウンロードする必要があります。
プル要求からパッチ ファイルをダウンロードする場合、または GitHub と GitLab からコミットする場合は、 ?full_index=1
パラメーターをダウンロード URL に追加する必要があります。
例 :
https://github.com/google/farmhash/pull/40.diff?full_index=1
https://github.com/linux-audit/audit-userspace/commit/f8e9bc5914d715cdacb2edc938ab339d5094d017.patch?full_index=1
https://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
などのオプションを確認し、追加のバイナリが無効になっていることを確認します。 これにより、平均ユーザーのビルド時間と依存関係が最小限に抑えられます。
必要に応じて、テストのビルドを可能にする test
機能を追加できますが、これは Default-Features
リストに含めてはなりません。
ライブラリの既存のユーザーが vcpkg に切り替えるようにする
追加しない CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
ライブラリの作成者が既に使用している場合を除き、この CMake 機能は C++ テンプレートと十分に対話せず、特定のコンパイラ機能を中断するため、使用しないでください。 .def ファイルを提供せず、__declspec() 宣言を使用しないライブラリは、単に Windows の共有ビルドをサポートしていないため、 vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
でそのようにマークする必要があります。
アップストリームによって指定された名前の外部にあるバイナリの名前を変更しないでください
つまり、アップストリーム ライブラリの名前がリリースとデバッグで異なる場合 (libx と libxd)、デバッグ ライブラリの名前を libx
に変更しないでください。 逆に、アップストリーム ライブラリがリリースとデバッグで同じ名前を持つ場合は、新しい名前を導入しないでください。
重要な注意事項:
- 多くの場合、静的バリアントと共有バリアントの名前を共通スキームに変更する必要があります。 これにより、コンシューマーは共通名を使用し、ダウンストリーム リンケージを無視できます。 これは、一度に 1 つしか使用できないため、安全です。
ライブラリで CMake 統合ファイル (foo-config.cmake
) が生成される場合は、単に出力アーカイブ/LIB で file(RENAME)
を呼び出すのではなく、CMake ビルド自体に修正プログラムを適用して名前を変更する必要があります。
最後に、Windows 上の DLL ファイルは、生成された LIB を壊すので、ビルド後に名前を変更しないでください。
マニフェスト
マニフェスト ファイルを書式設定する必要があります。 すべてのマニフェスト ファイルを書式設定するには、次のコマンドを使用します。
> vcpkg format-manifest --all
三つ子
現時点では、コミュニティ以外のトリプレットを追加する要求は受け付けていません。 コミュニティから完全なトリプレット状態への昇格は、主にハードウェアがこのようなトリプレットをテストするための予算に基づいており、実際に使用するものが完全にテストされる可能性を最大化するために vcpkg によって送信されたメトリックによって駆動されます。
次の場合は、コミュニティトリプレットを追加します。
- 人々が実際にそのコミュニティトリプレットを使用することが実証されています。そして
- 私たちはそのような三重項が壊れていることを知りません。
たとえば、 https://github.com/microsoft/vcpkg/pull/29034 にトリプレットを追加しませんでした。これは、作成者が実際にそのようなものを使用することを示すのではなく、単に "セットを完了" しようとしていただけであり、結果を再配置可能にするために patchlf ソリューションが作成されるまで linux-dynamic を追加しませんでした。
便利な実装に関する注意事項
ポートファイルはスクリプト モードで実行されます
portfile.cmake
とCMakeLists.txt
は共通の構文とコア CMake 言語コンストラクト ("Scripting Commands") を共有していますが、ポートファイルは "スクリプト モード" で実行されますが、CMakeLists.txt
ファイルは "プロジェクト モード" で実行されます。 これら 2 つのモードの最も重要な違いは、"スクリプト モード" には "Toolchain"、"Language"、"Target" という概念が含まれていないということです。 これらのコンストラクト ( CMAKE_CXX_COMPILER
、 CMAKE_EXECUTABLE_SUFFIX
、 CMAKE_SYSTEM_NAME
など) に依存するスクリプト コマンドを含む動作は正しくありません。
Portfile はトリプレット ファイルで設定された変数に直接アクセスできますが、 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
)。
使用可能な設定の完全な列挙については、 triplet のドキュメント も参照してください。
vcpkg