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 menjelaskan kebijakan, pedoman, dan praktik terbaik yang harus diikuti saat memberikan kontribusi ke vcpkg.
Ini dimaksudkan untuk melayani peran yang sama dengan:
Tujuan desain registri yang dikurasi
Port harus diinstal secara bersamaan
Port yang termasuk dalam registri yang dikurasi harus berhasil dibangun bersamaan dengan semua port lain dalam registri. Seluruh kombinasi port diuji secara teratur oleh CI otomatis vcpkg.
Port tidak boleh melakukan salah satu hal berikut:
- Pasang file yang berkonflik dengan port lain.
- Pasang simbol dan definisi yang dimiliki oleh paket lain.
- Uji keberadaan atau tidak adanya port lain. Kecuali untuk mendeklarasikan dependensi.
Pengecualian dibuat untuk:
- Port yang menggantikan port lain dalam kapasitas resmi. Proyek penerus.
- Port di mana tidak ada pertindihan platform. Misalnya, pengganti khusus Windows untuk proyek Linux yang tidak mendukung Windows.
- Port yang mendahului kebijakan ini dan memiliki jumlah pengguna dan kontributor yang sangat signifikan.
Port yang tidak sesuai dengan kebijakan ini tidak dapat diterima ke dalam registri yang dikumpulkan.
Petunjuk / Saran
Jika port Anda tidak dapat disertakan dalam registri yang dikumpulkan, pertimbangkan untuk menerbitkan registri kustom atau menggunakan port overlay.
Port harus diuji dalam setidaknya satu triplet resmi
Semua port dalam registri yang terkurasi harus diuji di CI untuk setidaknya satu triplet resmi.
Pengecualian dibuat untuk:
- Keadaan sementara, seperti:
- Port tidak dapat dibangun tanpa pembaruan infrastruktur CI.
- Pembangunan port terhenti karena perubahan yang memutus dalam dependensi hulu baru-baru ini, dan ada pekerjaan yang sedang berlangsung untuk menyelesaikan situasi ini.
- Port yang mendahului kebijakan ini dan memiliki jumlah pengguna dan kontributor yang sangat signifikan.
Port baru yang tidak dapat diuji dalam setidaknya satu triplet resmi tidak akan diterima dalam registri yang dikurasi. Port yang sudah ada yang tidak lagi sesuai dengan kebijakan ini dan tidak dikecualikan sementara dihapus dari registri.
Petunjuk / Saran
Jika port Anda tidak dapat disertakan dalam registri yang dikumpulkan, pertimbangkan untuk menerbitkan registri kustom atau menggunakan port overlay.
Proyek yang dipaketkan harus stabil dan dikelola secara aktif
Proyek yang dikemas dalam registri yang terkurasi harus dalam pemeliharaan aktif. Port untuk proyek yang tidak aktif dapat dihapus dari daftar.
Proyek dianggap tidak aktif jika:
- Para pemeliharanya telah menyatakan proyek telah ditinggalkan.
- Ini diarsipkan, atau tidak lagi menerima kontribusi.
- Pengurus tidak responsif atau tidak dapat dijangkau.
- Tidak ada perubahan berarti yang telah dilakukan dalam waktu yang lama.
Pengecualian dibuat untuk proyek dasar yang dianggap matang dan stabil dan tidak sering menerima perubahan.
Misalnya: zlib.
Proyek yang sudah dikemas harus sudah matang
Proyek yang dikemas dalam registri yang dikurasi harus matang dan ditujukan untuk digunakan oleh pengguna vcpkg. Proyek yang ditujukan untuk penggunaan pribadi harus diterbitkan ke registri kustom.
Proyek dianggap cukup matang untuk registri yang dikumpulkan, jika salah satu pernyataan ini benar:
- Proyek ini memiliki rilis yang setidaknya berusia enam bulan.
- Proyek ini menunjukkan setidaknya enam bulan pengembangan publik aktif.
- Proyek ini adalah komponen resmi dari proyek lain yang memenuhi persyaratan sebelumnya. Misalnya, pustaka Boost atau komponen Qt baru.
- Proyek ini menunjukkan kematangan yang setara dengan persyaratan sebelumnya dalam beberapa kapasitas lain.
Beberapa indikator ketidakmampuan proyek adalah:
- Proyek tidak muncul di mesin pencari.
- Proyek ini sering berganti nama.
- Berkonflik dengan pustaka lain.
Petunjuk / Saran
Jika port Anda tidak dapat disertakan dalam registri yang dikumpulkan, pertimbangkan untuk menerbitkan registri kustom atau menggunakan port overlay.
Struktur PR
Membuat permintaan pull terpisah per port
Permintaan penarikan (PR) yang lebih kecil lebih mudah untuk ditinjau. Permintaan pull harus membuat perubahan pada satu port. Ini juga mengurangi waktu tunggu untuk hasil Integrasi Berkelanjutan (CI).
Membatasi PR ke satu port mungkin tidak dimungkinkan dalam beberapa kasus. Misalnya, saat mengubah port mengharuskan konsumen hilir diperbarui atau di-patch.
Hindari perubahan sepele dalam file yang tidak tersentuh
Jangan membuat perubahan sepele pada port yang tidak dimodifikasi, seperti: memformat ulang, mengganti nama variabel, atau memperbaiki kesalahan ketik. Setiap perubahan yang tidak memengaruhi output penginstalan port dianggap sepele. Perubahan sepele dapat mengonsumsi waktu komputasi yang seharusnya digunakan untuk hal lain.
Gunakan nama port yang khas
Nama port harus menunjukkan isinya.
Mencari nama port di mesin pencari atau browser paket khusus, seperti Repologi, harus mengarah ke proyek yang sesuai.
Port dengan nama pendek atau dinamai sesuai kata-kata umum memerlukan disambiguasi. Ini hanya berlaku untuk nama port dalam registri yang dikurasi, nama proyek paket dan kontennya tidak wajib mematuhi kebijakan ini.
Pengecualian dibuat untuk port yang mengemas proyek dengan asosiasi yang kuat terkait dengan nama port tersebut. Misalnya: libpng, openssl, atau zlib.
Agar sesuai dengan kebijakan ini, port baru dengan nama ambigu dapat menggunakan awalan, seperti:
- Pemilik, nama pengguna, atau organisasi repositori. Contoh:
google-cloud-cpp. Untuk port proyek GitHub, pemilik GitHub adalah awalan<github owner>-<repository name>yang tidak ambigu yang dapat diterima . - Nama suite tempat paket berada:
boost-dll. Hanya jika paket adalah komponen resmi dari rangkaian tersebut.
Contoh: Nama port ambigu
Port dengan nama ip dianggap ambigu karena:
- nama terlalu pendek,
- nama adalah kata yang umum, dan
- nama ini tidak sangat terkait dengan proyek tunggal apa pun.
Untuk menentukan apakah nama ambigu, hapus awalan dan akhiran umum berikut yang digunakan oleh C++ dan proyek sumber terbuka dari nama port:
cppfreelibopen- simbol angka
Misalnya: ip-cpp, libip, dan ip5 ambigu karena berkurang hingga menjadi akar yang sama ip.
Batasi penggantian nama port
Untuk menghindari kebingungan bagi pengguna, port tidak dapat diganti namanya hingga setelah satu tahun mengganti nama terakhir mereka.
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
Tim vcpkg dapat menutup permintaan pull (PR) yang tidak memiliki aktivitas selama lebih dari 60 hari.
Untuk permintaan pull dalam status yang dapat ditinjau, hitung mundur dimulai dari terakhir kali penjaga vcpkg membuat permintaan perubahan, atau meminta klarifikasi. Jika tidak ada aktivitas yang dilakukan oleh kontributor dalam waktu 60 hari, PR dianggap basi dan dapat ditutup atas kebijakan tim.
PR dalam keadaan dapat ditinjau saat:
- Tidak memiliki pemeriksaan PR yang gagal, atau kontributor meminta bantuan atau membenarkan alasan kegagalan tersebut.
- Tidak ada perubahan atau klarifikasi yang diminta yang tertunda dari pemelihara vcpkg.
- Tidak memiliki konflik penggabungan.
PR yang tidak aktif selama lebih dari 60 hari dan tidak dalam kondisi dapat ditinjau mungkin ditutup tanpa ditinjau.
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.
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.
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.