Bagikan melalui


Panduan pemeliharaan

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 SHA512 dalam fungsi pembantu vcpkg.
  • Parameter REF dalam fungsi pembantu vcpkg, ketika nilainya adalah string heksadesimal.
  • Objek git-tree dalam file database versi.
  • Objek sha512 dalam scripts/vcpkg-tools.json file.
  • 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:

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:

  • brotli membuat paket unofficial-brotli, menghasilkan target unofficial::brotli::brotli.

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, open62541 semua memiliki fitur untuk memilih TLS atau backend kripto. curl memiliki opsi backend kripto yang berbeda tetapi memungkinkan pemilihan di antara mereka pada runtime, yang berarti tenet di atas dipertahankan.
  • darknet memiliki fitur opencv2, 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 fitur public-preview.
  • imgui memiliki fitur experimental-docking yang 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": false atau 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 menerima const wchar_t* daripada const 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:

  1. Mengaktifkan fitur ini mengubah polyfill menjadi alias dari entitas yang dipolyfill.
  2. Status polyfill ditanamkan dalam header yang diinstal, sehingga kesalahan runtime "tidak mungkin" akibat ketidakcocokan ABI tidak mungkin terjadi.
  3. Dimungkinkan bagi konsumen port untuk menulis kode yang berfungsi di kedua mode, misalnya dengan menggunakan typedef yang diisi polifil atau tidak

Contoh:

  • abseil[cxx17] mengganti absl::string_view dengan penggantian atau std::string_view; patch menerapkan persyaratan pemanggangan.

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>.

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:

  1. Pasang biner yang sudah dibangun sebelumnya daripada membangun dari sumber, dan
  2. Biner tersebut memiliki dependensi yang disediakan oleh port lain dalam registri yang sudah dikurasi, atau memerlukannya saat runtime, dan
  3. 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, .dylib atau 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 libfoo yang sudah terpasang menginstal lib/libfoo.lib serta header termasuk <zlib.h> dan telah dikompilasi dengan versi tertentu zlib; konsumen kemudian menautkan terhadap libfoo dengan 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.cmake atau vcpkg.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" dari 0).
  • Anda telah menemukan bahwa file hak cipta yang salah telah disebarkan, dan memperbaikinya di portfile.
  • Anda harus memperbarui bidang "port-version" dalam file manifes ke 1.

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 #include yang 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") atau option(VAR "Documentation" "Default Value")) dapat digantikan dengan meneruskan nilai baru di baris perintah sebagai -DVAR:STRING=Foo. Salah satu pengecualian penting adalah jika parameter FORCE diteruskan ke set(). Untuk informasi selengkapnya, lihat dokumentasi CMake set

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=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

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.