Поделиться через


Руководство по поддержке

В этом документе перечислены набор политик, которые следует применять при добавлении или обновлении рецепта порта. Она предназначена для работы с руководством по политике Debian, рекомендациями по обслуживанию Homebrew и книгой Формулы Homebrew.

Структура PR

Создание отдельных запросов на вытягивание на порт

Каждый раз, когда это возможно, разделите изменения на несколько PR. Это делает их значительно проще просматривать и предотвращать проблемы с одним набором изменений от удержания каждого другого изменения.

Избегайте тривиальных изменений в нетронутых файлах

Например, избегайте переформатирования или переименования переменных в портфайлах, которые в противном случае не могут быть изменены для проблемы. Однако если вам нужно изменить файл для основной цели PR (обновление библиотеки), то, очевидно, полезные изменения, такие как исправление опечаток, ценятся!

Проверка имен с другими репозиториями

Хорошая служба, чтобы проверка многие одновременно является рефологией. Если добавляемая библиотека может быть спутана с другой, рассмотрите возможность переименования, чтобы сделать ее ясной. Мы предпочитаем, когда имена длиннее и (или) вряд ли конфликтуют с любым будущим использованием того же имени. Если порт ссылается на библиотеку на GitHub, рекомендуется префиксировать имя организации, если есть вероятность путаницы.

Использование GitHub Черновик PR

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.

Добавление экспорта CMake в неофициальное пространство имен

Основной идеал разработки vcpkg заключается в том, чтобы не создавать "блокировку" для клиентов. В системе сборки не должно быть разницы в зависимости от библиотеки из системы и в зависимости от библиотеки из vcpkg. В этом случае мы избегаем добавления экспорта или целевых объектов CMake в существующие библиотеки с "очевидным именем", чтобы позволить вышестоящий добавлять собственные официальные экспорты CMake без конфликтов с vcpkg.

Для этого все конфигурации CMake, экспортируемые портом, которые не находятся в библиотеке вышестоящий, должны иметь unofficial- в качестве префикса. Любые дополнительные целевые объекты должны находиться в unofficial::<port>:: пространстве имен.

Это означает, что пользователь должен видеть следующее:

  • find_package(unofficial-<port> CONFIG) как способ получить в пакете unique-to-vcpkg
  • unofficial::<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, libzipopen62541 все имеют функции для выбора серверной части TLS или шифрования. curl имеет различные параметры серверной части шифрования, но позволяет выбирать между ними во время выполнения, то есть указанный выше набор поддерживается.
  • darknetopencv3имеет opencv2функции для управления версией opencv, используемой для его зависимостей.

Функция может заниматься предварительной версией или бета-версией функциональных возможностей

Несмотря на приведенный выше вариант, если есть ветвь предварительной версии или аналогичная функция предварительной версии, которая имеет высокую вероятность не нарушать функциональные возможности, отличные от предварительной версии (например, без удаления API), то эта функция может быть приемлемой для моделирования этого параметра.

Примеры:

  • Пакеты SDK Azure (формы azure-Xxx) имеют функцию public-preview .
  • imguiexperimental-docking имеет функцию, которая включает в себя свою ветвь предварительной док-станции, которая использует фиксацию слияния, присоединенную к каждому из их общедоступных нумерованных выпусков.

Функции по умолчанию должны включать поведение, а не API

Если потребитель зависит непосредственно от библиотеки, он может легко перечислить все необходимые функции (library[feature1,feature2]). Однако если потребитель не знает , что использует библиотеку, они не могут вывести список этих функций. Если эта скрытая библиотека похожа на libarchive то, где функции добавляют дополнительные алгоритмы сжатия (и таким образом поведение) в существующий универсальный интерфейс, функции по умолчанию предлагают способ обеспечить создание достаточно функциональной транзитивной библиотеки, даже если конечный потребитель не называет его напрямую.

Если функция добавляет дополнительные API (или исполняемые файлы или двоичные файлы библиотеки) и не изменяет поведение существующих API, по умолчанию его следует отключить. Это связано с тем, что любой потребитель, который может использовать эти API, может легко требовать его через прямую ссылку.

Если сомневается, не помечайте функцию по умолчанию.

Не используйте функции для управления альтернативами в опубликованных интерфейсах

Если потребитель порта зависит только от основных функциональных возможностей этого порта, с высокой вероятностью они не должны быть нарушены, включив функцию. Это еще более важно, если альтернатива не контролируется потребителем напрямую, а параметрами компилятора, такими как /std:c++17 / -std=c++17.

Существующие примеры, которые мы не будем принимать сегодня для обратной совместимости:

  • redis-plus-plus[cxx17] управляет полизаполнения, но не запекается параметр в установленном дереве.
  • ace[wchar] изменяет все ИНТЕРФЕЙСы API, которые принимают const wchar_t* , а не const char*.

Функция может заменить полизаполнения псевдонимами, если замена запекается в установленном дереве

Несмотря на приведенные выше, порты могут удалять полизаполнения с помощью функции, если:

  1. Включение функции изменяет полизаполнения на псевдонимы сущности polyfilled
  2. Состояние полизаполнения запекается в установленные заголовки, таким образом, что ошибки среды выполнения ABI не совпадают с ошибками среды выполнения,вряд ли
  3. Потребитель порта может написать код, который работает в обоих режимах, например с помощью типа, который является полизаполнения или нет

Пример:

  • 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() будет передаваться соответствующий параметр BUILD_SHARED_LIBSдля библиотек, которые не уважают эту переменную, можно включить:VCPKG_LIBRARY_LINKAGE

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}
)

При определении функций явным образом управляйте зависимостями

При определении функции, которая фиксирует необязательную зависимость, убедитесь, что зависимость не будет использоваться случайно, если эта функция не включена явным образом.

set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB ON)
set(CMAKE_REQUIRE_FIND_PACKAGE_ZLIB OFF)
if ("zlib" IN_LIST FEATURES)
  set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB OFF)
  set(CMAKE_REQUIRE_FIND_PACKAGE_ZLIB ON)
endif()

vcpkg_cmake_configure(
  SOURCE_PATH ${SOURCE_PATH}
  OPTIONS
    -DCMAKE_DISABLE_FIND_PACKAGE_ZLIB=${CMAKE_DISABLE_FIND_PACKAGE_ZLIB}
    -DCMAKE_REQUIRE_FIND_PACKAGE_ZLIB=${CMAKE_REQUIRE_FIND_PACKAGE_ZLIB}
)

Приведенный ниже vcpkg_check_features() фрагмент кода эквивалентен.

vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
  FEATURES
    "zlib"    CMAKE_REQUIRE_FIND_PACKAGE_ZLIB
  INVERTED_FEATURES
    "zlib"    CMAKE_DISABLE_FIND_PACKAGE_ZLIB
)

vcpkg_cmake_configure(
    SOURCE_PATH ${SOURCE_PATH}
    OPTIONS
      ${FEATURE_OPTIONS}
)

ZLIB В фрагменте кода учитывается регистр. Дополнительные сведения см. в CMAKE_DISABLE_FIND_PACKAGE_<PackageName> документации и CMAKE_REQUIRE_FIND_PACKAGE_<PackageName> документации.

Lib считается конфликтующим, если он выполняет одно из следующих действий:

  • Определить main
  • Определение malloc
  • Определение символов, которые также объявлены в других библиотеках

Конфликтующие libs обычно по дизайну и не считаются дефектом. Так как некоторые системы сборки ссылаются на все в каталоге lib, они должны быть перемещены в подкаталог с именем manual-link.

Манифесты и файлы CONTROL

При добавлении нового порта используйте новый синтаксис манифеста для определения порта; При изменении существующего порта можно также изменить манифесты. Это можно сделать, выполнив vcpkg format-manifest команду, которая преобразует существующие файлы CONTROL в файлы манифеста. Не преобразуйте файлы CONTROL, которые не были изменены.

Управление версиями

Следуйте общим соглашениям для "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 — это решение упаковки, а не конечные владельцы развернутых компонентов. В некоторых случаях необходимо применять исправления для улучшения совместимости компонентов с платформами или совместимости компонентов друг с другом.

  • Мы хотим избежать исправлений, которые:
    • вышестоящий не согласится с
    • вызвать уязвимости или сбои
    • Мы не можем поддерживать обновления версий вышестоящий
    • достаточно большой, чтобы вызвать запутанность лицензий с самим репозиторием vcpkg

Уведомление владельцев вышестоящий для вышестоящий соответствующих исправлений

Если исправление может оказаться полезным вышестоящий, вышестоящий должны быть уведомлены о содержимом исправления. (Исправления, которые применяют поведение vcpkg, не связанное с вышестоящий, например девендорирование зависимости, не требуют уведомления.)

Чтобы избежать ситуаций, когда вышестоящий не согласен с исправлением, мы подождем не менее 30 дней, чтобы применить такие исправления.

Мы пропустим этот период ожидания, если у нас есть высокая уверенность в том, что изменение правильно. Примеры исправлений высокой достоверности включают в себя, но не ограничиваются следующими:

  • Принятие upstream в качестве исправления (например, резервное копирование определенного изменения из запроса на вытягивание вышестоящий объединено).
  • Добавление отсутствующих #includes.
  • Небольшие и очевидные исправления кода продукта (например, инициализация неинициализированной переменной).
  • Отключение компонентов сборки, таких как тесты или примеры, неуместные в 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()в . Дополнительные сведения см. в документации по CMake set

Предпочесть переопределение значений исправлений 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 в условие, чем удалить каждую строку условного.

Не добавляйте исправления, если порт устарел и обновляет порт до более новой выпущенной версии, решит ту же проблему. 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_SUFFIXCMAKE_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).

См. также нашу тройную документацию по полному перечислению возможных параметров.