Руководство по поддержке
В этом документе перечислены набор политик, которые следует применять при добавлении или обновлении рецепта порта. Она предназначена для работы с руководством по политике Debian, рекомендациями по обслуживанию Homebrew и книгой Формулы Homebrew.
Общие цели проектирования реестра
Порты в текущей базовой базе должны быть установлены одновременно
Мы хотим показать подчиненных пользователей библиотек в курированном реестре, что сочетание библиотек в любом базовом плане, которое мы публикуем, было проверено для совместной работы по крайней мере в некоторых конфигурациях. Разрешение портов исключить друг друга из-за возможности тестирования таких конфигураций, так как число сборок, необходимых для таких тестов, будет увеличиваться.2^number_of_such_cases
Кроме того, установка дополнительных зависимостей всегда считается безопасной: для порта или конечного пользователя нет способа утверждать, что зависимость не установлена в своих требованиях.
Если вы хотите представить такую альтернативную ситуацию для пользователей, рассмотрите возможность описания того, как кто-то может создать порт наложения, реализующий альтернативную форму, portfile.cmake
а не пытаться добавить дополнительные порты, никогда не встроенные в курированный реестр непрерывной интеграции. Например, см . раздел glad@0.1.36.
Перед введением реестров мы приняли несколько не проверенных портов как альтернативных вариантов, таких как boringssl
, которые могут упростить разработку портов наложения. Это больше не принимается, так как реестры разрешают публикацию этих непроверенных портов без изменения курированного реестра.
Структура PR
Создание отдельных запросов на вытягивание на порт
Каждый раз, когда это возможно, разделите изменения на несколько PR. Это делает их значительно проще просматривать и предотвращать проблемы с одним набором изменений от удержания каждого другого изменения.
Избегайте тривиальных изменений в нетронутых файлах
Например, избегайте переформатирования или переименования переменных в портфайлах, которые в противном случае не могут быть изменены для проблемы. Однако если вам нужно изменить файл для основной цели PR (обновление библиотеки), то, очевидно, полезные изменения, такие как исправление опечаток, ценятся!
Проверка имен с другими репозиториями
Имена портов должны быть однозначными о том, какой пакет устанавливает порт. В идеале поиск имени порта в поисковой системе должен быстро привести вас к соответствующему проекту. Хорошая служба для проверки нескольких имен пакетов в нескольких репозиториях одновременно — repology.
Проекты с короткими именами или именами после распространенных слов могут требовать диамбигуации, особенно если нет проектов с строгой связью с заданным словом. Например, порт с именем ip
недопустим, так как, скорее всего, несколько проектов будут называться аналогичным образом.
Примеры хороших дивамбигуаторов:
- Имя пользователя или организация владельца репозитория:
google-cloud-cpp
- Имя набора библиотек, в который проект входит:
boost-dll
Распространенные префиксы и суффиксы, используемые C++ и открытый код проектами, являются недопустимыми дизамбигаторами, некоторые примеры включают в себя, но не ограничиваются следующими:
cpp
,free
,lib
,open
,- телефонных номеров
Например, при сравнении следующих имен портов: ip-cpp
libip
и ip5
при удалении недопустимых дивамбигуаторов все они сокращаются до одного и того же стебля (ip
) и, следовательно, считаются одинаковыми.
Исключение из этого руководства делается для имен, которые строго связаны с одним проектом. Например: libpng
, openssl
и zlib
.
Использование черновиков PR GitHub
GitHub Draft PR — отличный способ получить ci или человеческие отзывы о работе, которая еще не готова к слиянию. Большинство новых PR должны быть открыты как черновики и преобразованы в обычные PR после передачи CI.
Дополнительные сведения о GitHub Draft PR см. в статье "Введение черновиков запросов на вытягивание".
Портфайлы
Избегайте устаревших вспомогательных функций
В настоящее время не рекомендуется использовать следующие вспомогательные средства:
vcpkg_extract_source_archive_ex()
следует заменить поддерживаемой перегрузкойvcpkg_extract_source_archive()
(сARCHIVE
)- Нерекомендуемая перегрузка
vcpkg_extract_source_archive()
безARCHIVE
нее должна быть заменена поддерживаемой перегрузкойARCHIVE
. vcpkg_apply_patches()
следует заменитьPATCHES
аргументами вспомогательные средства извлечения (например,vcpkg_from_github()
vcpkg_build_msbuild()
должно быть замененоvcpkg_install_msbuild()
vcpkg_copy_tool_dependencies()
должно быть замененоvcpkg_copy_tools()
vcpkg_configure_cmake
следует заменитьvcpkg_cmake_configure()
после удаленияPREFER_NINJA
vcpkg_build_cmake
должно быть замененоvcpkg_cmake_build()
vcpkg_install_cmake
должно быть замененоvcpkg_cmake_install()
vcpkg_fixup_cmake_targets
должно быть замененоvcpkg_cmake_config_fixup
Некоторые вспомогательные функции замены находятся в "портах инструментов", чтобы разрешить потребителям закреплять свое поведение в определенных версиях, чтобы разрешить блокировку поведения вспомогательных в определенной версии. Порты инструментов необходимо добавить в порт "dependencies"
, как показано ниже.
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
Избегайте чрезмерных комментариев в портфайлах
В идеале портфайлы должны быть короткими, простыми и как можно более декларативными.
Удалите все комментарии к плите, представленные create
командой перед отправкой PR.
Порты не должны быть зависимыми от пути
Порты не должны изменять их поведение в зависимости от того, какие порты уже установлены в форме, которая изменит содержимое, которое устанавливает порт. Например, если:
> vcpkg install a
> vcpkg install b
> vcpkg remove a
и
> vcpkg install b
файлы, установленные по b
одной и той же, независимо от влияния предыдущей a
установки. Это означает, что порты не должны пытаться определить, предоставляется ли что-то в установленном дереве другим портом перед выполнением некоторых действий. Конкретная и распространенная причина такого поведения, зависящей от пути, описана ниже в разделе "При определении функций явно контролировать зависимости".
Уникальное правило атрибуции портов
В всей системе vcpkg не предполагается, что пользователь будет использовать два порта одновременно, может предоставить один и тот же файл. Если порт пытается установить файл, уже предоставленный другим файлом, установка завершится ошибкой. Если порт хочет использовать чрезвычайно распространенное имя заголовка, например, он должен поместить эти заголовки в подкаталог, а не в include
.
Это свойство регулярно проверяется непрерывной интеграцией, которая пытается установить все порты в реестре, что приведет к сбою FILE_CONFLICTS
, если два порта предоставляют один и тот же файл.
Добавление экспорта CMake в неофициальное пространство имен
Основной идеал разработки vcpkg заключается в том, чтобы не создавать блокировку для пользователей. В системе сборки не должно быть разницы в зависимости от библиотеки из системы и в зависимости от библиотеки из vcpkg. В этом случае мы избегаем добавления экспорта или целевых объектов CMake в существующие библиотеки с "очевидным именем", чтобы разрешить upstreams добавлять собственные официальные экспорты CMake, не конфликтуя с vcpkg.
Для этого все конфигурации CMake, экспортируемые портом, которые не находятся в вышестоящей библиотеке, должны иметь unofficial-
в качестве префикса. Любые дополнительные целевые объекты должны находиться в unofficial::<port>::
пространстве имен.
Это означает, что пользователь должен видеть следующее:
find_package(unofficial-<port> CONFIG)
как способ получить в пакете unique-to-vcpkgunofficial::<port>::<target>
в качестве экспортированного целевого объекта из этого порта.
Примеры:
brotli
создает пакет, создавая целевойunofficial-brotli
объектunofficial::brotli::brotli
.
Установка файла авторских прав
Каждый порт должен предоставить файл с именем copyright
в папке ${CURRENT_PACKAGES_DIR}/share/${PORT}
. Если содержимое лицензии пакета доступно в исходных файлах, этот файл должен быть создан вызовом vcpkg_install_copyright()
. vcpkg_install_copyright
при необходимости пакетирует несколько файлов авторских прав.
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")
Старый метод для создания этого файла вручную используется со встроенной file
командой CMake. Это не рекомендуется использовать vcpkg_install_copyright
в новых портах, но по-прежнему разрешено.
file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
Если содержимое лицензии в вышестоящих исходных файлах не находится в текстовой форме (например, PDF-файл), copyright
должно содержать пояснение о том, как пользователь может найти требования к лицензии. Если это возможно, он также должен включать ссылку на исходные исходные файлы, указывающие на это, чтобы пользователи могли проверить актуальность.
file(WRITE "${CURRENT_PACKAGES_DIR}/share/${PORT}/copyright" [[As of 2023-07-25, according to
https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Public-Documents/README.md#end-user-license-agreement
this software is bound by the "SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT" PDF located at
https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Public-Documents/ADL%20SDK%20EULA.pdf
]])
Ограничения версий в портах
Ограничения версий в портах, как правило, следует избегать, так как они могут препятствовать независимой эволюции проектов. Добавление таких ограничений допускается только в том случае, если имеется хорошо документируемое обоснование, например проверенная несовместимость с конкретными более ранними версиями. Эти ограничения не следует использовать только для поддержания паритета с независимыми проектами.
Функции
Не используйте функции для реализации альтернативных вариантов
Функции должны рассматриваться как аддитивные функции. При port[featureA]
установке и port[featureB]
установке port[featureA,featureB]
необходимо установить. Кроме того, если второй порт зависит от [featureA]
третьего порта [featureB]
, установка второго и третьего портов должна быть удовлетворена.
Библиотеки в этой ситуации должны выбрать один из доступных вариантов, выраженных в vcpkg, и пользователи, которым требуется другой параметр, должны использовать порты наложения в это время.
Существующие примеры, которые мы не будем принимать сегодня для обратной совместимости:
libgit2
,libzip
open62541
все имеют функции для выбора серверной части TLS или шифрования.curl
имеет различные параметры серверной части шифрования, но позволяет выбирать между ними во время выполнения, то есть указанный выше набор поддерживается.darknet
opencv3
имеетopencv2
функции для управления версией opencv, используемой для его зависимостей.
Функция может заниматься предварительной версией или бета-версией функциональных возможностей
Несмотря на приведенный выше вариант, если есть ветвь предварительной версии или аналогичная функция предварительной версии, которая имеет высокую вероятность не нарушать функциональные возможности, отличные от предварительной версии (например, без удаления API), то эта функция может быть приемлемой для моделирования этого параметра.
Примеры:
- Пакеты SDK Azure (формы
azure-Xxx
) имеют функциюpublic-preview
. imgui
experimental-docking
имеет функцию, которая включает в себя свою ветвь предварительной док-станции, которая использует фиксацию слияния, присоединенную к каждому из их общедоступных нумерованных выпусков.
Функции по умолчанию не должны добавлять API
Функции по умолчанию предназначены для обеспечения того, чтобы достаточно функциональная сборка библиотеки была установлена для клиентов, которые не знают, что они используют его. Если они не знают, что они используют библиотеку, они не могут знать, чтобы перечислить функции. Например, libarchive
предоставляет функции, позволяющие алгоритмам сжатия использовать существующий универсальный интерфейс; если он создан без каких-либо таких функций, библиотека может не иметь служебной программы.
Следует тщательно учесть, должна ли функция быть включена по умолчанию, так как отключение функций по умолчанию является сложным.
Для отключения функции по умолчанию в качестве транзитивного потребителя требуется:
- Все клиенты явно отключая функции по умолчанию через
"default-features": false
или в том числе[core]
в списке компонентов в командной строке. - Именование транзитивной зависимости от
vcpkg install
командной строки или в виде прямой зависимости в манифесте верхнего уровня
Если компонент добавляет дополнительные API, исполняемые файлы или другие двоичные файлы vcpkg, он должен быть отключен по умолчанию. Если сомневается, не помечайте функцию по умолчанию.
Не используйте функции для управления альтернативами в опубликованных интерфейсах
Если потребитель порта зависит только от основных функциональных возможностей этого порта, с высокой вероятностью они не должны быть нарушены, включив функцию. Это еще более важно, если альтернатива не контролируется потребителем напрямую, а параметрами компилятора, такими как /std:c++17
/ -std=c++17
.
Существующие примеры, которые мы не будем принимать сегодня для обратной совместимости:
redis-plus-plus[cxx17]
управляет полизаполнения, но не запекается параметр в установленном дереве.ace[wchar]
изменяет все ИНТЕРФЕЙСы API, которые принимаютconst wchar_t*
, а неconst char*
.
Функция может заменить полизаполнения псевдонимами, если замена запекается в установленном дереве
Несмотря на приведенные выше, порты могут удалять полизаполнения с помощью функции, если:
- Включение функции изменяет полизаполнения на псевдонимы сущности polyfilled
- Состояние полизаполнения запекается в установленные заголовки, таким образом, что ошибки среды выполнения ABI не совпадают с ошибками среды выполнения,вряд ли
- Потребитель порта может написать код, который работает в обоих режимах, например с помощью типа, который является полизаполнения или нет
Пример:
abseil[cxx17]
изменениеabsl::string_view
замены илиstd::string_view
; исправление реализует требование выпечки.
Рекомендуемые решения
Если крайне важно предоставить базовые альтернативные варианты, рекомендуется предоставлять сообщения во время сборки, чтобы указать пользователю, как скопировать порт в частную наложение:
set(USING_DOG 0)
message(STATUS "This version of LibContoso uses the Kittens backend. To use the Dog backend instead, create an overlay port of this with USING_DOG set to 1 and the `kittens` dependency replaced with `dog`.")
message(STATUS "This recipe is at ${CMAKE_CURRENT_LIST_DIR}")
message(STATUS "See the overlay ports documentation at https://github.com/microsoft/vcpkg/blob/master/docs/specifications/ports-overlay.md")
Методы сборки
Не используйте поставщики зависимостей
Не используйте внедренные копии библиотек. Все зависимости должны быть разделены и упаковываются отдельно, чтобы их можно было обновлять и поддерживать.
Предпочитать использование CMake
Если доступны несколько систем сборки, предпочитайте использовать CMake.
Кроме того, при необходимости можно упростить и повысить поддержку для перезаписи альтернативных систем сборки в CMake с помощью file(GLOB)
директив.
Примеры: abseil
Выбор статических или общих двоичных файлов
При создании библиотек vcpkg_cmake_configure()
CMake будет передаваться правильное значение BUILD_SHARED_LIBS
на основе запрошенного варианта пользователя.
Можно вычислить альтернативные параметры настройки с помощью string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" ...)
.
# portfile.cmake
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" KEYSTONE_BUILD_STATIC)
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" KEYSTONE_BUILD_SHARED)
vcpkg_cmake_configure(
SOURCE_PATH ${SOURCE_PATH}
OPTIONS
-DKEYSTONE_BUILD_STATIC=${KEYSTONE_BUILD_STATIC}
-DKEYSTONE_BUILD_SHARED=${KEYSTONE_BUILD_SHARED}
)
Если библиотека не предлагает параметры настройки для выбора варианта сборки, сборка должна быть исправлена. При исправлении сборки всегда следует пытаться максимально повысить поддержку порта в будущем. Как правило, это означает минимизацию количества строк, которые необходимо коснуться, чтобы устранить проблему.
Пример. Исправление библиотеки CMake, чтобы избежать создания нежелательных вариантов
Например, при исправлении библиотеки на основе CMake может потребоваться добавить в нежелательные целевые объекты и упаковать EXCLUDE_FROM_ALL
install(TARGETS ...)
вызов в объект if(BUILD_SHARED_LIBS)
. Это будет короче, чем упаковка или удаление каждой строки, которая упоминает нежелательный вариант.
Для проекта CMakeLists.txt
со следующим содержимым:
add_library(contoso SHARED contoso.c)
add_library(contoso_static STATIC contoso.c)
install(TARGETS contoso contoso_static EXPORT ContosoTargets)
install(EXPORT ContosoTargets
FILE ContosoTargets
NAMESPACE contoso::
DESTINATION share/contoso)
install(TARGETS)
Необходимо исправить только строку.
add_library(contoso SHARED contoso.c)
add_library(contoso_static STATIC contoso.c)
if(BUILD_SHARED_LIBS)
set_target_properties(contoso_static PROPERTIES EXCLUDE_FROM_ALL 1)
install(TARGETS contoso EXPORT ContosoTargets)
else()
set_target_properties(contoso PROPERTIES EXCLUDE_FROM_ALL 1)
install(TARGETS contoso_static EXPORT ContosoTargets)
endif()
install(EXPORT ContosoTargets
FILE ContosoTargets
NAMESPACE contoso::
DESTINATION share/contoso)
При определении функций явным образом управляйте зависимостями
При определении функции, которая фиксирует необязательную зависимость, убедитесь, что зависимость не будет использоваться случайно, если эта функция не включена явным образом.
set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB ON)
set(CMAKE_REQUIRE_FIND_PACKAGE_ZLIB OFF)
if ("zlib" IN_LIST FEATURES)
set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB OFF)
set(CMAKE_REQUIRE_FIND_PACKAGE_ZLIB ON)
endif()
vcpkg_cmake_configure(
SOURCE_PATH ${SOURCE_PATH}
OPTIONS
-DCMAKE_DISABLE_FIND_PACKAGE_ZLIB=${CMAKE_DISABLE_FIND_PACKAGE_ZLIB}
-DCMAKE_REQUIRE_FIND_PACKAGE_ZLIB=${CMAKE_REQUIRE_FIND_PACKAGE_ZLIB}
)
Приведенный ниже vcpkg_check_features()
фрагмент кода эквивалентен.
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
FEATURES
"zlib" CMAKE_REQUIRE_FIND_PACKAGE_ZLIB
INVERTED_FEATURES
"zlib" CMAKE_DISABLE_FIND_PACKAGE_ZLIB
)
vcpkg_cmake_configure(
SOURCE_PATH ${SOURCE_PATH}
OPTIONS
${FEATURE_OPTIONS}
)
ZLIB
В фрагменте кода учитывается регистр. Дополнительные сведения см. в CMAKE_DISABLE_FIND_PACKAGE_<PackageName>
документации и CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>
документации.
Размещение конфликтующих libs в каталоге manual-link
Lib считается конфликтующим, если он выполняет одно из следующих действий:
- Определять
main
- Определение malloc
- Определение символов, которые также объявлены в других библиотеках
Конфликтующие libs обычно по дизайну и не считаются дефектом. Так как некоторые системы сборки ссылаются на все в каталоге lib, они должны быть перемещены в подкаталог с именем manual-link
.
Управление версиями
Следуйте общим соглашениям для "version"
поля
При создании нового порта следуйте соглашению о настройке версий, используемому автором пакета. При обновлении порта продолжайте использовать то же соглашение, если не указано в противном случае. Полное описание наших соглашений см. в нашей документации по управление версиями.
Если вышестоящий выпуск не опубликовал в некоторое время, не изменяйте схему управления версиями порта, version-date
чтобы получить последние изменения. Эти фиксации могут включать изменения, которые не готовы к рабочей среде. Вместо этого попросите вышестоящий репозиторий опубликовать новый выпуск.
"port-version"
Обновление поля в файле манифеста любых измененных портов
vcpkg использует это поле для определения того, является ли данный порт устаревшим и следует изменять при изменении поведения порта.
Наша конвенция заключается в том, чтобы использовать "port-version"
поле для изменений в порте, который не изменяет вышестоящую версию, и сбросить "port-version"
обратно до нуля при внесении обновления в вышестоящую версию.
Пример:
- В настоящее время
1.2.1
версия пакета Zlib не является явной"port-version"
(эквивалентной"port-version"
ей0
). - Вы обнаружили, что развернут неправильный файл авторских прав и исправлен в портфайле.
- Поле в файле манифеста следует обновить
"port-version"
до1
.
Дополнительные сведения см. в документации по использованию версий.
Обновление файлов версий в versions/
любых измененных портах
vcpkg использует набор файлов метаданных для управления версиями. Эти файлы находятся в следующих расположениях:
${VCPKG_ROOT}/versions/baseline.json
, (этот файл является общим для всех портов) и${VCPKG_ROOT}/versions/${first-letter-of-portname}-/${portname}.json
(по одному на порт).
Например, для zlib
соответствующих файлов:
${VCPKG_ROOT}/versions/baseline.json
${VCPKG_ROOT}/versions/z-/zlib.json
Мы ожидаем, что каждый раз при обновлении порта вы также обновляете файлы версий.
Рекомендуемый способ обновления этих файлов — выполнить x-add-version
команду, например:
vcpkg x-add-version zlib
При одновременном обновлении нескольких портов можно выполнить следующее:
vcpkg x-add-version --all
для обновления файлов для всех измененных портов одновременно.
Примечание.
Для выполнения этих команд необходимо зафиксировать изменения портов. Причина заключается в том, что Git SHA каталога портов требуется в этих файлах версий. Но не беспокойтесь, команда предупредит вас, x-add-version
если у вас есть локальные изменения, которые не были зафиксированы.
Дополнительные сведения см. в справочнике по управление версиями и создании реестров.
Исправление
vcpkg — это решение упаковки, а не конечные владельцы развернутых компонентов. В некоторых случаях необходимо применять исправления для улучшения совместимости компонентов с платформами или совместимости компонентов друг с другом.
- Мы хотим избежать исправлений, которые:
- upstream не согласен с
- вызвать уязвимости или сбои
- Мы не можем поддерживать обновления вышестоящей версии
- достаточно большой, чтобы вызвать запутанность лицензий с самим репозиторием vcpkg
Уведомление владельцев вышестоящего потока для соответствующих исправлений
Если исправление может оказаться полезным в вышестоящей части, вышестоящей части должно быть уведомлено о содержимом исправления. (Исправления, которые применяют поведение vcpkg, не связанное с upstream, например девендорирование зависимости, не требуют уведомления.)
Чтобы избежать ситуаций, когда вышестоящий поток не согласен с исправлением, мы подождем по крайней мере 30 дней, чтобы применить такие исправления.
Мы пропустим этот период ожидания, если у нас есть высокая уверенность в том, что изменение правильно. Примеры исправлений высокой достоверности включают в себя, но не ограничиваются следующими:
- Принятие upstream в качестве исправления (например, резервное копирование определенного изменения из вышестоящего запроса на вытягивание объединено).
- Добавление отсутствующих
#include
s. - Небольшие и очевидные исправления кода продукта (например, инициализация неинициализированной переменной).
- Отключение компонентов сборки, таких как тесты или примеры, неуместные в vcpkg.
Предпочитать варианты по сравнению с исправлением
Предпочтительнее задать параметры в вызове для vcpkg_configure_xyz()
исправления параметров напрямую.
Распространенные варианты, позволяющие избежать исправления:
- [MSBUILD]
<PropertyGroup>
Параметры внутри файла проекта можно переопределить с помощью/p:
параметров - [CMAKE]
find_package(XYz)
Вызовы в скриптах CMake можно отключить с помощью-DCMAKE_DISABLE_FIND_PACKAGE_XYz=ON
- [CMAKE] Переменные кэша (объявленные как
set(VAR "value" CACHE STRING "Documentation")
илиoption(VAR "Documentation" "Default Value")
) можно переопределить, просто передав их в командной строке как-DVAR:STRING=Foo
. Одно из важных исключений заключается в том, чтоFORCE
параметр передаетсяset()
в . Дополнительные сведения см. в документации по CMakeset
Предпочесть скачивание утвержденных исправлений при проверке на порт
Если утвержденный или объединенный файл исправлений можно получить из вышестоящей части, порты должны попытаться скачать их и применить их вместо того, чтобы они были в составе файлов портов. Этот процесс предпочтичен, так как он:
- Подтверждает, что вышестоящий поток принял изменения исправлений
- Упрощение процесса проверки путем смены находящегося вышестоящего потока
- Уменьшает размер репозитория vcpkg для пользователей, которые не используют исправление
- Избегает конфликтов лицензий с репозиторием vcpkg
Исправления следует скачать из стабильной конечной точки, чтобы избежать конфликтов SHA.
При скачивании файлов исправлений из запроса на вытягивание или фиксацию из GitHub и GitLab ?full_index=1
параметр должен быть добавлен в URL-адрес скачивания.
Примеры:
https://github.com/google/farmhash/pull/40.diff?full_index=1
https://github.com/linux-audit/audit-userspace/commit/f8e9bc5914d715cdacb2edc938ab339d5094d017.patch?full_index=1
https://gitlab.kitware.com/paraview/paraview/-/merge_requests/6375.diff?full_index=1
Предпочесть переопределение значений исправлений VCPKG_<VARIABLE>
Некоторые переменные, префиксированные с VCPKG_<VARIABLE>
эквивалентом CMAKE_<VARIABLE>
.
Однако не все из них передаются во внутреннюю сборку пакета (см. реализацию: цепочку инструментов Windows).
Рассмотрим следующий пример:
set(VCPKG_C_FLAGS "-O2 ${VCPKG_C_FLAGS}")
set(VCPKG_CXX_FLAGS "-O2 ${VCPKG_CXX_FLAGS}")
Используя vcpkg
встроенную цепочку инструментов, это работает, так как значение VCPKG_<LANG>_FLAGS
пересылается в соответствующую CMAKE_LANG_FLAGS
переменную. Но пользовательский цепочка инструментов, которая не знает о vcpkg
переменных, не перенаправит их.
Из-за этого предпочтительнее исправить систему сборки непосредственно при настройке CMAKE_<LANG>_FLAGS
.
Минимизация исправлений
При внесении изменений в библиотеку старайтесь свести к минимуму окончательный дифф. Это означает, что при внесении изменений, влияющих на регион, не следует переформатировать вышестоящий исходный код. При отключении условного условия лучше добавить AND FALSE
или && 0
в условие, чем удалить каждую строку условного. Если большой регион необходимо отключить, то он короче, чтобы добавить if(0)
или #if 0
вокруг региона вместо удаления каждой строки в исправлении.
Не добавляйте исправления, если порт устарел и обновляет порт до более новой выпущенной версии, решит ту же проблему. vcpkg предпочитает обновлять порты при исправлении устаревших версий.
Это помогает сохранить размер репозитория vcpkg, а также повысить вероятность того, что исправление будет применяться к будущим версиям кода.
Не реализуйте функции в исправлениях
Целью исправления в vcpkg является обеспечение совместимости с компиляторами, библиотеками и платформами. Не следует реализовывать новые функции в соответствии с правильной процедурой Open Source (отправка проблемы/PR/т. д.).
По умолчанию не создавайте тесты и документы и примеры
При отправке нового порта проверьте все параметры, например BUILD_TESTS
или WITH_TESTS
или POCO_ENABLE_SAMPLES
убедитесь, что дополнительные двоичные файлы отключены. Это сводит к минимуму время сборки и зависимости для среднего пользователя.
При необходимости можно добавить test
функцию, которая позволяет создавать тесты, однако это не должно быть в списке Default-Features
.
Разрешить существующим пользователям библиотеки переключиться на vcpkg
Не добавляйте CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
Если автор библиотеки уже не использует его, мы не должны использовать эту функцию CMake, так как она плохо взаимодействует с шаблонами C++ и нарушает определенные функции компилятора. Библиотеки, которые не предоставляют файл .def и не используют объявления __declspec() просто не поддерживают общие сборки для Windows и должны быть помечены как такие vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
.
Не переименовывать двоичные файлы за пределами имен, заданных вышестоящими файлами
Это означает, что если в вышестоящей библиотеке есть разные имена в выпуске и отладке (libx и libxd), то библиотека отладки не должна быть переименована в libx
. Наоборот, если в вышестоящей библиотеке есть то же имя в выпуске и отладке, мы не должны вводить новое имя.
Важное предостережение:
- Статические и общие варианты часто следует переименовать в общую схему. Это позволяет потребителям использовать общее имя и игнорировать подчиненную компоновку. Это безопасно, так как мы делаем только один раз доступным.
Если библиотека создает файлы интеграции CMake (foo-config.cmake
), переименование необходимо сделать путем исправления самой сборки CMake, а не просто вызывать file(RENAME)
выходные архивы или ЛИБ.
Наконец, файлы DLL в Windows никогда не следует переименовать после сборки, так как они разбиваются на созданные ЛИБ.
Манифесты
Нам требуется отформатировать файл манифеста. Используйте следующую команду для форматирования всех файлов манифеста:
> vcpkg format-manifest --all
Тройня
В настоящее время мы не принимаем запросы на добавление не-сообщества триплет. Продвижение от сообщества до полного тройного состояния в основном основано на бюджете оборудования для тестирования таких тройных и будет управляться метриками, отправленными vcpkg, чтобы максимально повысить вероятность того, что люди на самом деле используют полностью протестированы.
Если мы добавим триплеты сообщества:
- Показано, что люди на самом деле будут использовать это сообщество тройной; и
- Мы не знаем, что такой тройной сломается.
Например, мы не добавили тройной вход https://github.com/microsoft/vcpkg/pull/29034 , так как автор просто пытается "завершить набор", а не указывает, что они на самом деле будут использовать такую вещь, и мы не добавили linux-dynamic до тех пор, пока решение patchelf не будет создано решение patchelf, чтобы сделать результаты перемещаемыми.
Полезные заметки о реализации
Портфайлы выполняются в режиме скрипта
Хотя portfile.cmake
"s и CMakeLists.txt
's" используют общий синтаксис и основные конструкции языка CMake (ака "Команды сценариев"), портфайлы выполняются в режиме скрипта, в то время как CMakeLists.txt
файлы выполняются в режиме проекта. Самое важное различие между этими двумя режимами заключается в том, что "Режим скрипта" не имеет концепций "Цепочка инструментов", "Язык" и "Целевой". Любое поведение, включая команды сценариев, которые зависят от этих конструкций (напримерCMAKE_CXX_COMPILER
, CMAKE_EXECUTABLE_SUFFIX
CMAKE_SYSTEM_NAME
) не будут правильными.
Портфайлы имеют прямой доступ к переменным, заданным в триплетном файле, но CMakeLists.txt
не (хотя часто происходит перевод VCPKG_LIBRARY_LINKAGE
— и ).BUILD_SHARED_LIBS
Портфайлы и сборки Project, вызываемые портфайлами, выполняются в разных процессах. Концептуально:
+----------------------------+ +------------------------------------+
| CMake.exe | | CMake.exe |
+----------------------------+ +------------------------------------+
| Triplet file | ====> | Toolchain file |
| (x64-windows.cmake) | | (scripts/buildsystems/vcpkg.cmake) |
+----------------------------+ +------------------------------------+
| Portfile | ====> | CMakeLists.txt |
| (ports/foo/portfile.cmake) | | (buildtrees/../CMakeLists.txt) |
+----------------------------+ +------------------------------------+
Чтобы определить узел в портфайле, стандартные переменные CMake хорошо (CMAKE_HOST_WIN32
).
Чтобы определить целевой объект в портфайле, следует использовать переменные vcpkg triplet (VCPKG_CMAKE_SYSTEM_NAME
).
См. также нашу тройную документацию по полному перечислению возможных параметров.