Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dokumen ini mencantumkan serangkaian kebijakan yang harus Anda terapkan saat menambahkan atau memperbarui resep port. Ini dimaksudkan untuk berfungsi sebagai Manual Kebijakan Debian, Panduan Pemeliharaan Homebrew, dan Buku Resep Formula Homebrew.
Tujuan desain registri secara keseluruhan
Port-port dalam garis dasar saat ini harus dapat diinstal secara bersamaan
Kami ingin dapat menunjukkan kepada pengguna akhir pustaka dalam registri yang dikurasi bahwa kombinasi pustaka dalam baseline tertentu yang kami terbitkan telah diuji untuk bekerja bersama dalam setidaknya beberapa konfigurasi. Memungkinkan port untuk saling mengecualikan memutus kemampuan untuk menguji konfigurasi tersebut, karena jumlah build yang diperlukan untuk pengujian tersebut akan tumbuh seperti 2^number_of_such_cases. Selain itu, menginstal dependensi tambahan selalu dianggap "aman": tidak ada cara bagi port atau pengguna akhir untuk menegaskan bahwa dependensi tidak diinstal dalam persyaratan mereka.
Jika Anda ingin mewakili situasi alternatif seperti itu bagi pengguna, pertimbangkan untuk menjelaskan bagaimana seseorang dapat membuat overlay port yang menerapkan bentuk alternatif dengan komentar di portfile.cmake daripada mencoba menambahkan port tambahan yang tidak pernah dibangun dalam integrasi berkelanjutan registri terkurasi. Misalnya, lihat glad@0.1.36.
Sebelum pengenalan registri , kami menerima beberapa port yang tidak diuji sebagai alternatif, seperti boringssl, yang dapat membuat penulisan port overlay lebih mudah. Ini tidak lagi diterima karena registri memungkinkan penerbitan port yang belum diuji ini tanpa memodifikasi registri terkurasi.
Menggunakan huruf kecil untuk string digit heksadesimal
Banyak fitur dalam vcpkg mengandalkan perbandingan string digit heksadesimal. Beberapa contoh termasuk, tetapi tidak terbatas pada, hash SHA512, ID komit Git, dan hash objek pohon.
Secara internal, vcpkg menggunakan normalisasi huruf kecil untuk perbandingan nilai tersebut ketika casing tidak relevan. Namun, alat yang dikembangkan berdasarkan infrastruktur vcpkg mungkin tidak membuat pertimbangan yang sama. Untuk alasan ini, kami memerlukan string heksadesimal
untuk dijadikan huruf kecil demi konsistensi dalam skenario berikut:
- Parameter
SHA512dalam fungsi pembantu vcpkg. - Parameter
REFdalam fungsi pembantu vcpkg, ketika nilainya adalah string heksadesimal. - Objek
git-treedalam file database versi. - Objek
sha512dalamscripts/vcpkg-tools.jsonfile. - Tempat lain di mana casing string heksadesimal tidak penting.
Struktur PR
Membuat permintaan pull terpisah per port
Jika memungkinkan, pisahkan perubahan menjadi beberapa PR. Ini membuatnya jauh lebih mudah untuk ditinjau dan mencegah masalah dengan satu set perubahan menghambat perubahan lainnya.
Hindari perubahan sepele dalam file yang tidak tersentuh
Misalnya, hindari memformat ulang atau mengganti nama variabel dalam portfiles yang sebaliknya tidak memiliki alasan untuk dimodifikasi untuk masalah yang ditangani. Namun, jika Anda perlu memodifikasi file untuk tujuan utama PR (memperbarui pustaka), maka jelas perubahan yang bermanfaat seperti memperbaiki kesalahan ketik dihargai!
Periksa nama dengan repositori lain
Nama port harus berusaha jelas tentang paket mana yang diinstal oleh port tersebut. Idealnya, mencari nama port di mesin pencari harus dengan cepat mengarahkan Anda ke proyek yang sesuai. Layanan yang baik untuk memeriksa banyak nama paket di beberapa repositori sekaligus adalah Repologi.
Proyek dengan nama pendek atau dinamai sesuai dengan kata-kata umum mungkin memerlukan disambiguasi, khususnya ketika tidak ada proyek dengan asosiasi yang kuat dengan kata yang diberikan. Misalnya, port dengan nama ip tidak dapat diterima karena kemungkinan beberapa proyek akan diberi nama yang sama.
Contoh disambiguator yang baik adalah:
- Nama pengguna atau organisasi pemilik repositori:
google-cloud-cpp. - Nama rangkaian pustaka yang merupakan bagian dari proyek:
boost-dll.
Awalan dan akhiran umum yang digunakan oleh C++ dan proyek sumber terbuka tidak merupakan disambiguator yang sah, beberapa contoh meliputi, namun tidak terbatas pada:
-
cpp, -
free, -
lib, -
open, - Angka
Misalnya, saat membandingkan nama port berikut: ip-cpp, libip dan ip5 dan menghapus disambiguator yang tidak valid, semuanya dikurangi ke batang yang sama (ip) dan dengan demikian dianggap memiliki nama yang sama.
Pengecualian untuk pedoman ini dibuat untuk nama yang sangat terkait dengan satu proyek. Misalnya: libpng, openssl dan zlib.
Untuk menghindari kebingungan bagi pengguna, kami dapat membatasi frekuensi di mana port dapat diganti namanya setelah ditambahkan ke registri publik. Kebijakan kami saat ini adalah tidak mengizinkan lebih dari satu penggantian nama per tahun.
Menggunakan Draf Pull Request di GitHub
GitHub Draft PR adalah cara yang bagus untuk mendapatkan CI atau umpan balik manusia tentang pekerjaan yang belum siap untuk digabungkan. Sebagian besar PR baru harus dibuka sebagai draf dan dikonversi ke PR normal setelah CI lolos.
Untuk informasi selengkapnya tentang draf permintaan tarik GitHub, lihat Memperkenalkan draf permintaan tarik.
Tim vcpkg dapat mengonversi PR Anda ke draf selama proses peninjauan. Biasanya, dengan permintaan untuk membuat perubahan pada kode atau komentar Anda yang menunjukkan kapan harus menandai PR sebagai Siap Untuk Ditinjau.
Tutup PR yang tidak aktif
Untuk menghindari akumulasi PR kedaluarsa, tim vcpkg dapat menutup PR yang telah menunggu tindakan kontributor selama lebih dari 60 hari. Hitung mundur ini dimulai sejak terakhir kali seorang penjaga vcpkg membuat permintaan perubahan atau umpan balik, jika tidak ada aktivitas yang diamati dalam waktu 60 hari, PR dianggap kedaluarsa dan dapat ditutup atas kebijakan tim vcpkg.
Portfile
Hindari fungsi pembantu yang tidak digunakan lagi
Saat ini, pembantu berikut tidak digunakan lagi:
-
vcpkg_extract_source_archive_ex()harus diganti dengan kelebihan bebanvcpkg_extract_source_archive()yang didukung (denganARCHIVE) - Pemakaian berlebihan
vcpkg_extract_source_archive()yang sudah usang tanpaARCHIVEharus digantikan dengan beban berlebih yang didukung denganARCHIVE. -
vcpkg_apply_patches()harus diganti oleh argumenPATCHESpada fungsi pembantu "ekstrak" (misalnyavcpkg_from_github()) -
vcpkg_build_msbuild()harus diganti denganvcpkg_install_msbuild() -
vcpkg_copy_tool_dependencies()harus diganti denganvcpkg_copy_tools() -
vcpkg_configure_cmakeharus diganti denganvcpkg_cmake_configure()setelah menghapusPREFER_NINJA -
vcpkg_build_cmakeharus diganti denganvcpkg_cmake_build() -
vcpkg_install_cmakeharus diganti denganvcpkg_cmake_install() -
vcpkg_fixup_cmake_targetsharus diganti denganvcpkg_cmake_config_fixup
Beberapa fungsi pembantu pengganti berada di "tools ports" untuk memungkinkan konsumen mengunci perilaku mereka pada versi tertentu, memungkinkan penguncian perilaku pembantu pada versi khusus. Port alat harus ditambahkan ke "dependencies" port Anda, seperti ini:
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
Hindari komentar berlebihan di portfiles
Idealnya, portfiles harus pendek, sederhana, dan sedeklaratif mungkin.
Hapus komentar pola umum yang dihasilkan oleh perintah create sebelum mengirimkan PR.
Port tidak boleh bergantung pada jalur
Port-port tidak boleh mengubah perilakunya berdasarkan port mana yang sudah diinstal dalam bentuk yang akan mengubah konten yang diinstal oleh port tersebut. Misalnya, jika diberikan:
> vcpkg install a
> vcpkg install b
> vcpkg remove a
dan
> vcpkg install b
file yang diinstal oleh b harus sama, terlepas dari pengaruhnya oleh penginstalan asebelumnya. Ini berarti bahwa port tidak boleh berusaha untuk mendeteksi apakah sesuatu disediakan di pohon instalasi oleh port lain sebelum mengambil tindakan. Penyebab spesifik dan umum dari perilaku "dependen jalur" tersebut dijelaskan di bawah ini dalam "Saat menentukan fitur, secara eksplisit mengontrol dependensi."
Aturan atribusi pelabuhan yang unik
Dalam seluruh sistem vcpkg, tidak ada dua port yang diharapkan digunakan pengguna secara bersamaan dapat menyediakan file yang sama. Jika port mencoba menginstal file yang sudah disediakan oleh file lain, penginstalan akan gagal. Jika port ingin menggunakan nama yang sangat umum untuk header, misalnya, port harus menempatkan header tersebut dalam subdirektori daripada di include.
Properti ini diperiksa secara teratur oleh eksekusi integrasi berkelanjutan yang mencoba menginstal semua port di registri, yang akan gagal dengan FILE_CONFLICTS jika dua port menyediakan file yang sama.
Menambahkan ekspor CMake dalam namespace tak resmi
Cita-cita desain inti vcpkg adalah untuk tidak membuat "lock-in" untuk pengguna. Dalam sistem build, seharusnya tidak ada perbedaan antara bergantung pada pustaka dari sistem dan bergantung pada pustaka dari vcpkg. Untuk itu, kami menghindari penambahan ekspor atau target CMake ke pustaka yang ada dengan "nama yang sudah dikenal", untuk memungkinkan pengembang sumber asli (upstream) menambahkan ekspor CMake resmi mereka sendiri tanpa bertentangan dengan vcpkg.
Untuk itu, konfigurasi CMake apa pun yang diekspor oleh port dan tidak ada di pustaka upstream harus memiliki unofficial- sebagai awalan. Target tambahan apa pun harus berada di namespace unofficial::<port>::.
Ini berarti bahwa pengguna akan melihat:
-
find_package(unofficial-<port> CONFIG)sebagai cara untuk mendapatkan paket yang unik untuk vcpkg -
unofficial::<port>::<target>sebagai target yang diimpor dari port tersebut.
Contoh:
-
brotlimembuat paketunofficial-brotli, menghasilkan targetunofficial::brotli::brotli.
Menginstal file hak cipta
Setiap port harus menyediakan file bernama copyright di folder ${CURRENT_PACKAGES_DIR}/share/${PORT}. Jika konten lisensi paket tersedia dalam file sumbernya, file ini harus dibuat dengan panggilan ke vcpkg_install_copyright().
vcpkg_install_copyright juga menggabungkan beberapa file hak cipta jika perlu.
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")
Metode lama untuk membuat file ini secara manual adalah dengan perintah file bawaan CMake. Meskipun masih diizinkan, penggunaan ini tidak disarankan dan lebih diutamakan vcpkg_install_copyright untuk port baru.
file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
Jika konten lisensi dalam file sumber upstream tidak dalam bentuk teks (misalnya file PDF), copyright harus berisi penjelasan tentang bagaimana pengguna dapat menemukan persyaratan lisensi. Jika memungkinkan, ini juga harus menyertakan tautan ke file sumber asli yang menunjukkan hal ini, sehingga pengguna dapat memeriksa apakah sudah diperbarui.
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
]])
Batasan versi dalam port
Batasan versi dalam port umumnya harus dihindari, karena dapat menghambat evolusi proyek yang independen. Menambahkan batasan tersebut hanya diizinkan ketika ada pembenaran yang didokumenkan dengan baik, seperti ketidaksesuaian yang terbukti dengan versi tertentu yang lebih lama. Batasan ini tidak boleh digunakan hanya untuk mempertahankan paritas dengan proyek independen.
Variabel di MAYBE_UNUSED_VARIABLES harus berlaku untuk setidaknya satu konfigurasi
Saat menambahkan variabel baru untuk MAYBE_UNUSED_VARIABLES membungkam peringatan selama langkah konfigurasi CMake, Anda harus menambahkan komentar yang menjelaskan kasus saat variabel baru berlaku. Jika variabel tidak berlaku dalam konfigurasi apa pun, maka sangat mungkin bug yang mendasar ada (misalnya, nama variabel yang salah eja) dan menambahkannya tidak memiliki efek aktual pada build.
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
)
Fitur
Jangan gunakan fitur untuk mengimplementasikan alternatif
Fitur harus diperlakukan sebagai fungsionalitas aditif. Jika port[featureA] menginstal dan port[featureB] diinstal, maka port[featureA,featureB] harus menginstal. Selain itu, jika port kedua tergantung pada [featureA] dan port ketiga tergantung pada [featureB], menginstal port kedua dan ketiga harus memenuhi dependensinya.
Perpustakaan dalam situasi ini harus memilih salah satu opsi yang tersedia seperti yang ditentukan dalam vcpkg, dan pengguna yang menginginkan pengaturan yang berbeda harus menggunakan port overlay pada saat ini.
Contoh-contoh yang saat ini tidak akan kami terima dipertahankan demi kesesuaian ke belakang.
-
libgit2,libzip,open62541semua memiliki fitur untuk memilih TLS atau backend kripto.curlmemiliki opsi backend kripto yang berbeda tetapi memungkinkan pemilihan di antara mereka pada runtime, yang berarti tenet di atas dipertahankan. -
darknetmemiliki fituropencv2,opencv3, untuk mengontrol versi opencv mana yang akan digunakan untuk dependensinya.
Fitur dapat melibatkan fungsionalitas pratinjau atau beta
Terlepas dari hal di atas, jika ada cabang pratinjau atau serupa di mana fungsionalitas pratinjau memiliki probabilitas tinggi untuk tidak mengganggu fungsionalitas non-pratinjau (misalnya, tidak ada penghapusan API), fitur dapat diterima untuk memodelkan pengaturan ini.
Contoh:
- Azure SDK (dari formulir
azure-Xxx) memiliki fiturpublic-preview. -
imguimemiliki fiturexperimental-dockingyang melibatkan cabang docking pratinjau mereka yang menggunakan penerapan penggabungan yang dilampirkan ke masing-masing rilis bernomor publik mereka.
Fitur default tidak boleh menambahkan API
Nota
Fitur yang diaktifkan secara default oleh sistem build upstream, tidak menyiratkan bahwa fitur harus ditambahkan ke entri-entri default-features. Karena tujuan default-features yang dimaksudkan adalah untuk tidak memodelkan keputusan yang dibuat oleh hulu tetapi untuk memberikan kenyamanan bagi pengguna mode klasik .
Fitur default dimaksudkan untuk memastikan bahwa pustaka yang berfungsi dengan baik diinstal untuk pelanggan yang tidak sadar mereka menggunakannya. Jika mereka tidak tahu bahwa mereka menggunakan pustaka, mereka tidak dapat mengetahui untuk menyebutkan fitur-fitur. Misalnya, libarchive mengekspos fitur yang memungkinkan algoritma kompresi ke antarmuka generik yang ada; jika dibangun tanpa fitur seperti itu, pustaka mungkin tidak memiliki utilitas.
Seseorang harus mempertimbangkan dengan cermat apakah fitur harus aktif secara default, karena menonaktifkan fitur default rumit.
Menonaktifkan fitur default sebagai konsumen 'transitif' memerlukan:
- Semua pelanggan secara eksplisit menonaktifkan fitur default melalui
"default-features": falseatau menyertakan[core]dalam daftar fitur di baris perintah. - Penamaan dependensi transitif pada baris perintah
vcpkg install, atau sebagai dependensi langsung dalam manifes tingkat atas
Dalam registri yang terkurasi vcpkg, jika fitur menambahkan API tambahan, executable, atau biner lainnya, secara default harus nonaktif. Jika ragu, jangan menandai fitur sebagai default.
Jangan gunakan fitur untuk mengontrol alternatif di antarmuka yang diterbitkan
Jika konsumen port hanya bergantung pada fungsionalitas inti port tersebut, dengan probabilitas tinggi, mereka tidak seharusnya terganggu ketika fitur diaktifkan. Ini bahkan lebih penting ketika alternatif tidak dikontrol langsung oleh konsumen, tetapi dengan pengaturan kompilator seperti /std:c++17 / -std=c++17.
Contoh-contoh yang saat ini tidak akan kami terima dipertahankan demi kesesuaian ke belakang.
-
redis-plus-plus[cxx17]mengontrol polyfill tetapi tidak mengintegrasikan pengaturan ke dalam struktur yang terpasang. -
ace[wchar]mengubah semua API untuk menerimaconst wchar_t*daripadaconst char*.
Fitur dapat mengganti polyfill dengan alias asalkan penggantian ini sudah terintegrasi ke dalam sistem yang terpasang.
Terlepas dari hal di atas, port dapat menghapus polyfill dengan adanya fitur, selama:
- Mengaktifkan fitur ini mengubah polyfill menjadi alias dari entitas yang dipolyfill.
- Status polyfill ditanamkan dalam header yang diinstal, sehingga kesalahan runtime "tidak mungkin" akibat ketidakcocokan ABI tidak mungkin terjadi.
- Dimungkinkan bagi konsumen port untuk menulis kode yang berfungsi di kedua mode, misalnya dengan menggunakan typedef yang diisi polifil atau tidak
Contoh:
-
abseil[cxx17]menggantiabsl::string_viewdengan penggantian ataustd::string_view; patch menerapkan persyaratan pemanggangan.
Solusi yang direkomendasikan
Jika penting untuk mengekspos alternatif yang mendasar, sebaiknya berikan pesan pada waktu build untuk menginstruksikan pengguna tentang cara menyalin port ke overlay privat:
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")
Teknik Pembangunan
Jangan gunakan dependensi yang dipasok vendor
Jangan gunakan salinan pustaka yang disematkan. Semua dependensi harus dibagi dan dipaketkan secara terpisah sehingga dapat diperbarui dan dikelola.
Dependensi vendor memperkenalkan beberapa tantangan yang bertentangan dengan tujuan vcpkg untuk menyediakan sistem manajemen paket yang andal, konsisten, dan dapat dipertahankan:
Kesulitan dalam Pembaruan: Salinan library yang disematkan membuatnya lebih sulit untuk melacak dan menerapkan pembaruan, termasuk patch keamanan, dari proyek upstream. Hal ini menyebabkan potensi risiko keamanan dan dependensi kedaluarsa dalam ekosistem.
Konflik Simbol: Dependensi yang dibundel dapat menyebabkan konflik simbol ketika beberapa paket menyertakan versi yang berbeda dari perpustakaan yang sama.
Misalnya: Jika Paket A menyertakan Pustaka X (versi 1) dan Paket B menyertakan Pustaka X (versi 2), aplikasi yang menghubungkan kedua paket mungkin mengalami kesalahan waktu eksekusi atau perilaku yang tidak terdefinisi karena simbol yang bertentangan.
Dengan mengemas dependensi secara terpisah, vcpkg memastikan satu versi pustaka digunakan di semua paket, menghilangkan konflik tersebut.
Kepatuhan Lisensi: Dependensi yang disediakan oleh vendor dapat mengaburkan lisensi pustaka yang disematkan, berpotensi melanggar persyaratan lisensi mereka atau menimbulkan masalah kompatibilitas.
Peningkatan Beban Pemeliharaan: Menjaga dependensi yang di-vendor tetap sinkron dengan versi upstream mereka membutuhkan upaya manual yang signifikan dan sering menyebabkan pekerjaan duplikat di seluruh paket.
Lebih suka menggunakan CMake
Saat beberapa buildsystem tersedia, lebih suka menggunakan CMake.
Selain itu, jika sesuai, dapat lebih mudah dan lebih dapat dipertahankan untuk menulis ulang buildsystem alternatif ke dalam CMake menggunakan arahan file(GLOB).
Contoh: abseil
Pilih file biner statis atau terbagi
Saat membangun pustaka CMake, vcpkg_cmake_configure() akan meneruskan nilai yang benar untuk BUILD_SHARED_LIBS berdasarkan varian yang diminta pengguna.
Anda dapat menghitung parameter konfigurasi alternatif dengan menggunakan 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}
)
Jika pustaka tidak menawarkan opsi konfigurasi untuk memilih varian build, build harus diperbaiki. Saat menambal build, Anda harus selalu mencoba memaksimalkan keberlangsungan port di masa mendatang. Biasanya ini berarti meminimalkan jumlah baris yang perlu disentuh untuk memperbaiki masalah yang sedang dihadapi.
Contoh: Menambal pustaka CMake agar tidak membangun varian yang tidak diinginkan
Misalnya, saat menambal pustaka berbasis CMake, mungkin cukup dengan menambahkan EXCLUDE_FROM_ALL ke target yang tidak diinginkan dan membungkus panggilan install(TARGETS ...) dalam if(BUILD_SHARED_LIBS). Ini akan lebih pendek daripada membungkus atau menghapus setiap baris yang menyebutkan varian yang tidak diinginkan.
Untuk proyek CMakeLists.txt dengan konten berikut:
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)
Hanya garis install(TARGETS) yang perlu ditambal.
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)
Saat menentukan fitur, secara eksplisit mengontrol dependensi
Saat menentukan fitur yang mengambil dependensi opsional, pastikan bahwa dependensi tidak akan digunakan secara tidak sengaja ketika fitur tidak diaktifkan secara eksplisit.
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}
)
Cuplikan di bawah ini menggunakan vcpkg_check_features() yang setara.
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 dalam cuplikan peka terhadap huruf besar/kecil. Untuk informasi selengkapnya, lihat dokumentasi CMAKE_DISABLE_FIND_PACKAGE_<PackageName> dan CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>.
Menempatkan libs yang bertentangan dalam direktori manual-link
Lib dianggap bertentangan jika melakukan salah satu hal berikut:
- Tentukan
main - Definisikan malloc
- Tentukan simbol yang juga dideklarasikan di pustaka lain
Libs yang bertentangan biasanya berdasarkan desain dan tidak dianggap cacat. Karena beberapa sistem build menautkan terhadap segala sesuatu di direktori lib, ini harus dipindahkan ke subdirektori bernama manual-link.
Menginstal biner bawaan
Port yang menginstal artefak bawaan (khusus biner) diizinkan tetapi sangat tidak disarankan, asalkan mereka tidak secara efektif memblokir perubahan versi port lain. Membangun dari sumber lebih disukai karena menghormati semua pengaturan vcpkg yang mengubah pengkompilasi atau bendera.
Kami akan menolak port yang memenuhi semua kondisi berikut:
- Pasang biner yang sudah dibangun sebelumnya daripada membangun dari sumber, dan
- Biner tersebut memiliki dependensi yang disediakan oleh port lain dalam registri yang sudah dikurasi, atau memerlukannya saat runtime, dan
- Artefak yang terpasang memasuki domain tautan vcpkg yang diterbitkan – yaitu mereka menginstal pustaka/header/CMake atau metadata pkg-config yang diharapkan dapat ditautkan dengan port hilir atau proyek pengguna.
Alasan: Kombinasi ini secara efektif mengunci ABI dari grafik ketergantungan ke versi yang digunakan ketika prebuilt upstream dihasilkan. vcpkg tidak dapat memperbarui dengan aman (misalnya) zlib, openssl, atau dependensi serupa tanpa mempertaruhkan kerusakan ODR / ABI yang halus bagi konsumen yang menghubungkan dengan pustaka yang dibangun sebelumnya, dan pengguna mungkin melewatkan patch keamanan penting.
"Memasukkan domain tautan yang diterbitkan" biasanya berarti salah satu dari:
- Menginstal pustaka
.lib,.a,.so,.dylibatau pustaka impor yang ditujukan bagi konsumen untuk ditautkan. - Mengirim header yang mereferensikan (secara langsung atau melalui kode sebaris/templat) simbol, jenis, atau makro dari port vcpkg lainnya.
- Menginstal file konfigurasi CMake / pkg-config yang memanggil
find_dependency()/Requires:pada port vcpkg lainnya.
Skenario yang diizinkan (tetapi masih tidak dianjurkan):
- Alat bantu khusus untuk host (eksekutabel) yang digunakan pada waktu pembuatan yang outputnya dikonsumsi tetapi tidak dihubungkan langsung oleh port dependen, asalkan mereka menggabungkan dependensi secara privat atau hanya mengandalkan pustaka runtime sistem yang banyak digunakan.
- Pustaka bawaan yang sepenuhnya mandiri yang secara statis menautkan semua dependensi OSS DAN tidak mengekspos simbol atau jenisnya melalui header yang diinstal atau antarmuka yang diekspor (konsumen tidak dapat mengamati atau bergantung pada ABI transitif).
- Paket data saja, firmware, atau aset yang tidak ditautkan ke dalam kode pengguna.
Contoh terlarang:
- Paket
libfooyang sudah terpasang menginstallib/libfoo.libserta header termasuk<zlib.h>dan telah dikompilasi dengan versi tertentuzlib; konsumen kemudian menautkan terhadaplibfoodengan ekspektasi kompatibilitas. - SDK bawaan yang menginstal panggilan
find_dependency(OpenSSL)file paket CMake saat biner dikompilasi terhadap rilis OpenSSL yang lebih lama.
Mitigasi / alternatif:
- Berikan build dari sumber menggunakan skrip upstream atau tambahkan pembungkus CMake tipis.
- Minta upstream untuk menerbitkan rilis berbasis sumber atau instruksi build yang dapat direplikasi; tautkan isu/PR upstream dalam komentar di
portfile.cmakeatauvcpkg.json. - Gunakan port overlay atau registri privat untuk bawaan khusus organisasi yang tidak dapat memenuhi aturan ini.
Pengelolaan Versi
Ikuti konvensi umum untuk bidang "version"
Saat membuat port baru, ikuti konvensi penerapan versi yang digunakan oleh pembuat paket. Saat memperbarui port, terus gunakan konvensi yang sama kecuali pihak hulu menyatakan berbeda. Untuk penjelasan lengkap tentang konvensi kami, lihat dokumentasi penerapan versi kami.
Jika upstream belum menerbitkan rilis dalam beberapa saat, jangan ubah skema penerapan versi port menjadi version-date untuk mendapatkan perubahan terbaru. Komit ini dapat mencakup perubahan yang belum siap untuk produksi. Sebagai gantinya, minta repositori upstream untuk menerbitkan rilis baru.
Memperbarui bidang "port-version" dalam file manifes dari port yang dimodifikasi
vcpkg menggunakan bidang ini untuk menentukan apakah port tertentu sudah kedaluarsa dan harus diubah setiap kali perilaku port berubah.
Konvensi kami adalah menggunakan bidang "port-version" untuk perubahan pada port yang tidak mengubah versi upstream, dan untuk mengatur ulang "port-version" kembali ke nol ketika pembaruan ke versi upstream dibuat.
Misalnya:
- Versi paket Zlib saat ini adalah
1.2.1, tanpa adanya"port-version"yang eksplisit (setara dengan"port-version"dari0). - Anda telah menemukan bahwa file hak cipta yang salah telah disebarkan, dan memperbaikinya di portfile.
- Anda harus memperbarui bidang
"port-version"dalam file manifes ke1.
Lihat dokumentasi penerapan versi untuk informasi selengkapnya.
Perbarui file versi di versions/ pada port yang dimodifikasi
vcpkg menggunakan sekumpulan file metadata untuk mendukung fitur penerapan versinya. File-file ini terletak di lokasi berikut:
-
${VCPKG_ROOT}/versions/baseline.json, (file ini umum untuk semua port) dan -
${VCPKG_ROOT}/versions/${first-letter-of-portname}-/${portname}.json(satu per port).
Misalnya, untuk zlib file yang relevan adalah:
${VCPKG_ROOT}/versions/baseline.json${VCPKG_ROOT}/versions/z-/zlib.json
Kami mengharapkan bahwa setiap kali Anda memperbarui port, Anda juga memperbarui file versinya.
Metode yang direkomendasikan untuk memperbarui file-file ini adalah menjalankan perintah x-add-version, misalnya:
vcpkg x-add-version zlib
Jika Anda memperbarui beberapa port secara bersamaan, sebagai gantinya Anda dapat menjalankan:
vcpkg x-add-version --all
untuk memperbarui berkas untuk semua port yang dimodifikasi sekaligus.
Untuk informasi selengkapnya, lihat artikel referensi Penerapan Versi dan Registri.
Memperbarui
vcpkg adalah solusi pengemasan, bukan pemilik utama komponen yang kami sebarkan. Kita perlu menerapkan patch dalam beberapa kasus untuk meningkatkan kompatibilitas komponen dengan platform, atau kompatibilitas komponen satu sama lain.
- Kami ingin menghindari patch yang:
- upstream tidak setuju dengan
- menyebabkan kerentanan atau kerusakan sistem
- kami tidak dapat mempertahankan selama pembaruan versi upstream
- cukup besar untuk menyebabkan keterikatan lisensi dengan repositori vcpkg itu sendiri
Memberitahu pemilik hulu untuk patch yang relevan.
Jika patch mungkin berguna bagi upstream, upstream harus diberi tahu tentang konten patch. (Patch yang menerapkan perilaku khusus vcpkg yang tidak terkait dengan hulu, seperti memisahkan (devendoring) dependensi, tidak memerlukan pemberitahuan.)
Untuk menghindari situasi di mana upstream tidak setuju dengan patch, kami akan menunggu setidaknya 30 hari untuk menerapkan patch tersebut.
Kami akan melewati periode tunggu ini jika kami memiliki keyakinan tinggi bahwa perubahan tersebut benar. Contoh patch dengan tingkat keyakinan tinggi mencakup, tetapi tidak terbatas pada:
- Penerimaan oleh upstream sebagai patch (misalnya, memasukkan kembali perubahan tertentu dari permintaan pull upstream yang telah digabungkan).
- Menambahkan
#includeyang hilang. - Perbaikan kode produk kecil dan jelas (misalnya, menginisialisasi variabel yang tidak diinisialisasi).
- Menonaktifkan komponen build yang tidak relevan dalam vcpkg seperti pengujian atau contoh.
Lebih memilih opsi daripada menambal
Lebih baik mengatur opsi dalam panggilan ke vcpkg_configure_xyz() daripada menambal pengaturan secara langsung.
Opsi umum yang memungkinkan Anda menghindari patching:
- [MSBUILD] pengaturan
<PropertyGroup>yang ada di dalam file proyek dapat diubah melalui parameter/p: - [CMAKE] Panggilan ke
find_package(XYz)dalam skrip CMake dapat dinonaktifkan melalui-DCMAKE_DISABLE_FIND_PACKAGE_XYz=ON - [CMAKE] Variabel cache (dinyatakan sebagai
set(VAR "value" CACHE STRING "Documentation")atauoption(VAR "Documentation" "Default Value")) dapat digantikan dengan meneruskan nilai baru di baris perintah sebagai-DVAR:STRING=Foo. Salah satu pengecualian penting adalah jika parameterFORCEditeruskan keset(). Untuk informasi selengkapnya, lihat dokumentasi CMakeset
Lebih suka mengunduh patch yang disetujui daripada memeriksanya ke port
Jika file patch yang disetujui atau digabungkan dapat diperoleh dari hulu, port harus mencoba mengunduhnya dan menerapkannya alih-alih memilikinya sebagai bagian dari file port. Proses ini lebih disukai karena:
- Mengonfirmasi bahwa upstream telah menerima perubahan patch
- Menyederhanakan proses peninjauan dengan memindahkan tanggung jawab ke tahap awal
- Mengurangi ukuran repositori vcpkg untuk pengguna yang tidak menggunakan patch
- Menghindari konflik lisensi dengan repositori vcpkg
Patch harus diunduh dari titik akhir yang stabil untuk menghindari konflik SHA.
Saat mengunduh file patch dari pull request atau commit dari GitHub dan GitLab, parameter ?full_index=1 harus ditambahkan ke URL unduhan.
Contoh:
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
Lebih suka menambal daripada mengganti nilai VCPKG_<VARIABLE>
Beberapa variabel yang diawali dengan VCPKG_<VARIABLE> memiliki CMAKE_<VARIABLE>yang setara.
Namun, tidak semuanya diteruskan ke build paket internal (lihat implementasi: Toolchain Windows).
Pertimbangkan contoh berikut:
set(VCPKG_C_FLAGS "-O2 ${VCPKG_C_FLAGS}")
set(VCPKG_CXX_FLAGS "-O2 ${VCPKG_CXX_FLAGS}")
Menggunakan toolchain bawaan vcpkg, ini berfungsi, karena nilai VCPKG_<LANG>_FLAGS diteruskan ke variabel CMAKE_LANG_FLAGS yang sesuai. Namun, toolchain kustom yang tidak mengetahui variabel vcpkgtidak akan meneruskannya.
Karena itu, lebih disarankan untuk menambal buildsystem secara langsung saat mengkonfigurasi CMAKE_<LANG>_FLAGS.
Meminimalkan pembaruan
Saat membuat perubahan pada pustaka, upayakan untuk meminimalkan selisih akhir. Ini berarti Anda tidak boleh memformat ulang kode sumber hulu saat membuat perubahan yang memengaruhi wilayah. Saat menonaktifkan kondisi, lebih baik menambahkan AND FALSE atau && 0 ke kondisi daripada menghapus setiap baris kondisi. Jika wilayah besar perlu dinonaktifkan, lebih mudah dan cepat untuk menambahkan if(0) atau #if 0 di sekitarnya alih-alih menghapus setiap baris dalam patch.
Jangan tambahkan patch jika port sudah usang dan memperbarui port ke versi yang dirilis yang lebih baru akan menyelesaikan masalah yang sama. vcpkg lebih suka memperbarui port daripada menambal versi yang sudah kedaluarsa.
Ini membantu menjaga ukuran repositori vcpkg tetap kecil serta meningkatkan kemungkinan patch akan berlaku untuk versi kode di masa depan.
Jangan menerapkan fitur dalam patch
Tujuan patching dalam vcpkg adalah untuk memungkinkan kompatibilitas dengan kompilator, pustaka, dan platform. Ini bukan untuk menerapkan fitur baru sebagai pengganti mengikuti prosedur Open Source yang benar (mengirimkan Issue/PR/dll).
Jangan membuat pengujian/dokumen/contoh secara default
Saat mengirimkan port baru, periksa opsi apa pun seperti BUILD_TESTS atau WITH_TESTS atau POCO_ENABLE_SAMPLES dan pastikan biner tambahan dinonaktifkan. Ini meminimalkan waktu build dan dependensi untuk pengguna rata-rata.
Secara opsional, Anda dapat menambahkan fitur test yang memungkinkan pembuatan pengujian, namun ini seharusnya tidak ada dalam daftar Default-Features.
Aktifkan pengguna pustaka yang ada untuk beralih ke vcpkg
Jangan tambahkan CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
Kecuali penulis pustaka sudah menggunakannya, kita tidak boleh menggunakan fungsionalitas CMake ini karena berinteraksi dengan buruk dengan templat C++ dan merusak fitur pengkompilasi tertentu. Pustaka yang tidak menyediakan file .def dan tidak menggunakan deklarasi __declspec() tidak mendukung build bersama untuk Windows dan harus ditandai seperti itu:
if(VCPKG_TARGET_IS_WINDOWS)
vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
endif()
Jangan ganti nama biner di luar nama yang diberikan oleh upstream
Ini berarti bahwa jika pustaka upstream memiliki nama yang berbeda dalam rilis dan debug (libx versus libxd), maka pustaka debug tidak boleh diganti namanya menjadi libx. Sebaliknya, jika pustaka upstream memiliki nama yang sama baik dalam versi rilis maupun debug, kita tidak perlu memperkenalkan nama baru.
Peringatan penting:
- Varian statis dan bersama sering kali harus diganti namanya menjadi skema umum. Ini memungkinkan konsumen untuk menggunakan nama umum dan tidak tahu tentang tautan hilir. Ini aman karena kami hanya menyediakan satu saja pada satu waktu.
Jika pustaka menghasilkan file integrasi CMake (foo-config.cmake), penggantian nama harus dilakukan melalui patching build CMake itu sendiri alih-alih hanya memanggil file(RENAME) pada arsip output/LIB.
Terakhir, file DLL di Windows tidak boleh diganti namanya pasca-build karena merusak LIB yang dihasilkan.
Manifest
Kami memerlukan agar file manifes diformat. Gunakan perintah berikut untuk memformat semua file manifes:
> vcpkg format-manifest --all
Kembar Tiga
Saat ini kami tidak menerima permintaan untuk menambahkan triplet non-komunitas. Promosi dari komunitas ke status triplet penuh terutama didasarkan pada anggaran untuk perangkat keras yang digunakan untuk menguji triplet tersebut dan akan dipengaruhi oleh metrik yang dikirimkan oleh vcpkg untuk memaksimalkan kemungkinan bahwa apa yang sebenarnya digunakan oleh orang-orang sepenuhnya diuji.
Kami akan menambahkan triplet komunitas jika:
- Ditunjukkan bahwa orang benar-benar akan menggunakan trio komunitas itu; dan
- kita tidak tahu bahwa trio tersebut rusak.
Misalnya, kami tidak menambahkan triplet di https://github.com/microsoft/vcpkg/pull/29034 karena penulis hanya mencoba "menyelesaikan rangkaian" daripada menunjukkan bahwa mereka akan benar-benar menggunakan hal seperti itu, dan kami tidak menambahkan linux-dynamic sampai solusi patchelf untuk membuat hasil yang dapat direlokasi dibuat.
Catatan implementasi yang berguna
Portfiles dijalankan dalam Mode Skrip
Meskipun portfile.cmakedan CMakeLists.txtberbagi sintaks umum dan konstruksi bahasa CMake inti (alias "Perintah Skrip"), portfiles berjalan dalam "Mode Skrip", sedangkan file CMakeLists.txt berjalan dalam "Mode Proyek". Perbedaan terpenting antara kedua mode ini adalah bahwa "Mode Skrip" tidak memiliki konsep "Toolchain", "Language" dan "Target". Perilaku apa pun, termasuk perintah pembuatan skrip, yang bergantung pada konstruksi ini (misalnya CMAKE_CXX_COMPILER, CMAKE_EXECUTABLE_SUFFIX, CMAKE_SYSTEM_NAME) tidak akan benar.
Portfiles memiliki akses langsung ke variabel yang diatur dalam file triplet, tetapi CMakeLists.txttidak memiliki akses tersebut (meskipun sering terdapat penerjemahan yang berlangsung -- VCPKG_LIBRARY_LINKAGE dibandingkan dengan BUILD_SHARED_LIBS).
Portfiles dan build Project yang dipanggil oleh portfiles dijalankan dalam proses yang berbeda. Konseptual:
+----------------------------+ +------------------------------------+
| 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) |
+----------------------------+ +------------------------------------+
Untuk menentukan host dalam portfile, variabel CMake standar baik-baik saja (CMAKE_HOST_WIN32).
Untuk menentukan target dalam portfile, variabel triplet vcpkg harus digunakan (VCPKG_CMAKE_SYSTEM_NAME).
Lihat juga dokumentasi triplet kami untuk daftar lengkap pengaturan yang tersedia.