Guía del mantenedor
En este documento se muestra un conjunto de directivas que debe aplicar al agregar o actualizar una receta de puerto. Está pensado para servir el papel del Manual de Directivas de Debian, las Directrices del Mantenedor de Homebrew y el Libro de recetas de fórmulas de Homebrew.
Objetivos generales de diseño del registro
Los puertos de la línea base actual deben instalarse simultáneamente
Queremos poder mostrar a los usuarios de nivel inferior de las bibliotecas en el registro mantenido que la combinación de bibliotecas en cualquier línea base determinada que publicamos se ha probado para trabajar conjuntamente en al menos algunas configuraciones. Permitir que los puertos se excluyan entre sí interrumpen la capacidad de probar estas configuraciones, ya que el número de compilaciones necesarias para estas pruebas crecería como 2^number_of_such_cases
. Además, la instalación de dependencias adicionales siempre se considera "segura": no hay forma de que un puerto o un usuario final aserten que una dependencia no está instalada en sus requisitos.
Si desea representar esta situación alternativa para los usuarios, considere la posibilidad de describir cómo alguien puede crear un puerto de superposición que implemente el formulario alternativo con un comentario en lugar portfile.cmake
de intentar agregar puertos adicionales nunca integrados en la integración continua del registro mantenido. Por ejemplo, consulte glad@0.1.36.
Antes de la introducción de registros, aceptamos varios puertos no probados como alternativas, como boringssl
, que podrían facilitar la creación de puertos de superposición. Esto ya no se acepta porque los registros permiten publicar estos puertos no probados sin modificar el registro mantenido.
Estructura de pr
Realización de solicitudes de incorporación de cambios independientes por puerto
Siempre que sea posible, separe los cambios en varias solicitudes de incorporación de cambios. Esto hace que sean significativamente más fáciles de revisar y evitar que se produzcan problemas con un conjunto de cambios que contengan todos los demás cambios.
Evitar cambios triviales en archivos sin modificar
Por ejemplo, evite cambiar el formato o cambiar el nombre de las variables en los archivos de puerto que, de lo contrario, no tengan ninguna razón para modificarse para el problema en cuestión. Sin embargo, si necesita modificar el archivo para el propósito principal de la solicitud de incorporación de cambios (actualización de la biblioteca), obviamente se aprecian cambios beneficiosos como corregir errores tipográficos.
Comprobación de nombres en otros repositorios
Los nombres de puerto deben intentar no ser ambiguos sobre qué paquete instala el puerto. Lo ideal es que la búsqueda del nombre del puerto en un motor de búsqueda le lleve rápidamente al proyecto correspondiente. Un buen servicio para comprobar muchos nombres de paquete en varios repositorios a la vez es Repology.
Los proyectos con nombres cortos o con nombre después de palabras comunes pueden requerir desambiguación, especialmente cuando no hay proyectos con una fuerte asociación con la palabra dada. Por ejemplo, un puerto con el nombre ip
no es aceptable, ya que es probable que varios proyectos se denominarían de forma similar.
Algunos ejemplos de buenos desambiguadores son:
- Nombre de usuario o organización del propietario del repositorio:
google-cloud-cpp
. - El nombre de un conjunto de bibliotecas del proyecto forma parte de:
boost-dll
.
Los prefijos y sufijos comunes usados por C++ y los proyectos de código abierto no son ambigüadores válidos, algunos ejemplos incluyen, entre otros:
cpp
,free
,lib
,open
,- numbers
Por ejemplo, al comparar los siguientes nombres de puerto: ip-cpp
libip
y y ip5
quitar los desambiguadores no válidos, todos se reducen al mismo tallo (ip
) y, por tanto, se consideran que tienen el mismo nombre.
Se hace una excepción a esta guía para los nombres que están fuertemente asociados a un solo proyecto. Por ejemplo, libpng
, openssl
y zlib
.
Uso de solicitudes de incorporación de cambios de borrador de GitHub
Las solicitudes de incorporación de cambios de GitHub Draft son una excelente manera de obtener comentarios de CI o humanos sobre el trabajo que aún no está listo para combinarse. La mayoría de las nuevas solicitudes de incorporación de cambios deben abrirse como borradores y convertirse en solicitudes de incorporación de cambios normales una vez que la CI pasa.
Para obtener más información sobre las solicitudes de incorporación de cambios de GitHub Draft, consulte Introducción al borrador de solicitudes de incorporación de cambios.
Portfiles
Evitar funciones auxiliares en desuso
En este momento, los siguientes asistentes están en desuso:
vcpkg_extract_source_archive_ex()
debe reemplazarse por la sobrecarga admitida devcpkg_extract_source_archive()
(porARCHIVE
)- La sobrecarga en desuso de
vcpkg_extract_source_archive()
sinARCHIVE
debe reemplazarse por la sobrecarga admitida porARCHIVE
. vcpkg_apply_patches()
debe reemplazarse por losPATCHES
argumentos de los asistentes de "extracción" (por ejemplo,vcpkg_from_github()
)vcpkg_build_msbuild()
debe reemplazarse porvcpkg_install_msbuild()
vcpkg_copy_tool_dependencies()
debe reemplazarse porvcpkg_copy_tools()
vcpkg_configure_cmake
debe reemplazarse después devcpkg_cmake_configure()
quitarPREFER_NINJA
vcpkg_build_cmake
debe reemplazarse porvcpkg_cmake_build()
vcpkg_install_cmake
debe reemplazarse porvcpkg_cmake_install()
vcpkg_fixup_cmake_targets
debe reemplazarse porvcpkg_cmake_config_fixup
Algunas de las funciones auxiliares de reemplazo están en "puertos de herramientas" para permitir que los consumidores anclen su comportamiento en versiones específicas, para permitir el bloqueo del comportamiento de los asistentes en una versión determinada. Los puertos de herramientas deben agregarse al puerto "dependencies"
, de la siguiente manera:
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
Evitar comentarios excesivos en archivos de puerto
Idealmente, los archivos de puerto deben ser cortos, sencillos y tan declarativos como sea posible.
Quite los comentarios de las planchas reutilizables introducidos por el create
comando antes de enviar una solicitud de incorporación de cambios.
Los puertos no deben ser dependientes de la ruta de acceso
Los puertos no deben cambiar su comportamiento en función de los puertos que ya están instalados en un formulario que cambiaría el contenido que instala ese puerto. Por ejemplo, dado:
> vcpkg install a
> vcpkg install b
> vcpkg remove a
y
> vcpkg install b
los archivos instalados por b
deben ser los mismos, independientemente de la influencia de la instalación anterior de a
. Esto significa que los puertos no deben intentar detectar si otro puerto proporciona algo en el árbol instalado antes de realizar alguna acción. A continuación se describe una causa específica y común del comportamiento "dependiente de la ruta de acceso" en "Al definir características, controlar explícitamente las dependencias".
Regla de atribución de puerto única
En todo el sistema vcpkg, no se espera que un usuario use dos puertos simultáneamente para proporcionar el mismo archivo. Si un puerto intenta instalar un archivo ya proporcionado por otro archivo, se producirá un error en la instalación. Si un puerto quiere usar un nombre muy común para un encabezado, por ejemplo, debe colocar esos encabezados en un subdirectorio en lugar de en include
.
Esta propiedad se comprueba periódicamente mediante ejecuciones de integración continua que intentan instalar todos los puertos del Registro, lo que producirá un error si FILE_CONFLICTS
dos puertos proporcionan el mismo archivo.
Adición de exportaciones de CMake en un espacio de nombres no oficial
Un diseño básico ideal de vcpkg es no crear "bloqueo" para los usuarios. En el sistema de compilación, no debe haber ninguna diferencia entre dependiendo de una biblioteca del sistema y en función de una biblioteca de vcpkg. Para ello, evitamos agregar exportaciones o destinos de CMake a las bibliotecas existentes con "el nombre obvio", para permitir que las subidas agreguen sus propias exportaciones oficiales de CMake sin entrar en conflicto con vcpkg.
Para ello, las configuraciones de CMake que exporta el puerto, que no están en la biblioteca ascendente, deben tener unofficial-
como prefijo. Los destinos adicionales deben estar en el unofficial::<port>::
espacio de nombres.
Esto significa que el usuario debería ver lo siguiente:
find_package(unofficial-<port> CONFIG)
como la manera de obtener en el paquete unique-to-vcpkgunofficial::<port>::<target>
como destino exportado desde ese puerto.
Ejemplos:
brotli
crea elunofficial-brotli
paquete, lo que genera el destinounofficial::brotli::brotli
.
Instalación del archivo de copyright
Cada puerto tiene que proporcionar un archivo denominado copyright
en la carpeta ${CURRENT_PACKAGES_DIR}/share/${PORT}
. Si el contenido de licencia de un paquete está disponible en sus archivos de origen, este archivo se debe crear mediante una llamada a vcpkg_install_copyright()
. vcpkg_install_copyright
también agrupa varios archivos de copyright si es necesario.
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")
Un método anterior para crear manualmente este archivo es con el comando integrado de file
CMake. Esto no se recomienda en favor de vcpkg_install_copyright
en los nuevos puertos, pero todavía está permitido.
file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
Si el contenido de la licencia en los archivos de origen ascendentes no está en formato de texto (por ejemplo, un archivo PDF), copyright
debe contener una explicación sobre cómo un usuario puede encontrar los requisitos de licencia. Si es posible, también debe incluir un vínculo a los archivos de origen originales que indican esto, por lo que los usuarios pueden comprobar si está actualizado.
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
]])
Restricciones de versión en puertos
Por lo general, se deben evitar restricciones de versión dentro de los puertos, ya que pueden dificultar la evolución independiente de los proyectos. Agregar estas restricciones solo se permite cuando hay una justificación bien documentada, como la incompatibilidad probada con versiones anteriores específicas. Estas restricciones no deben usarse simplemente para mantener la paridad con proyectos independientes.
Características
No usar características para implementar alternativas
Las características deben tratarse como funcionalidad de adición. Si port[featureA]
instala e port[featureB]
instala , port[featureA,featureB]
debe instalarse. Además, si un segundo puerto depende [featureA]
de y un tercer puerto depende [featureB]
de , la instalación de los puertos segundo y tercero debe tener sus dependencias satisfechos.
Las bibliotecas de esta situación deben elegir una de las opciones disponibles, tal como se expresa en vcpkg, y los usuarios que quieran una configuración diferente deben usar puertos de superposición en este momento.
Los ejemplos existentes que no aceptaríamos hoy conservamos por motivos de compatibilidad con versiones anteriores:
libgit2
,libzip
,open62541
todas tienen características para seleccionar un back-end TLS o criptográfico.curl
tiene diferentes opciones de back-end criptográfico, pero permite seleccionar entre ellos en tiempo de ejecución, lo que significa que se mantiene la red de tenet anterior.darknet
tieneopencv2
,opencv3
características para controlar qué versión de opencv se va a usar para sus dependencias.
Una característica puede interactuar con la versión preliminar o la funcionalidad beta
A pesar de lo anterior, si hay una rama en versión preliminar o similar en la que la funcionalidad de vista previa tiene una alta probabilidad de no interrumpir la funcionalidad que no es de versión preliminar (por ejemplo, sin eliminaciones de API), una característica es aceptable para modelar esta configuración.
Ejemplos:
- Los SDK de Azure (con el formato
azure-Xxx
) tienen unapublic-preview
característica. imgui
tiene unaexperimental-docking
característica que interactúa con su rama de acoplamiento de vista previa que usa una confirmación de combinación asociada a cada una de sus versiones numeradas públicas.
Las características predeterminadas no deben agregar API
Las características predeterminadas están diseñadas para garantizar que se instale una compilación razonablemente funcional de una biblioteca para los clientes que no saben que lo usan. Si no saben que usan una biblioteca, no pueden saber enumerar las características. Por ejemplo, libarchive
expone características que habilitan algoritmos de compresión en una interfaz genérica existente; si se compila sin ninguna de estas características, es posible que la biblioteca no tenga ninguna utilidad.
Uno debe considerar cuidadosamente si una característica debe estar activada de forma predeterminada, ya que deshabilitar las características predeterminadas es compleja.
La deshabilitación de una característica predeterminada como consumidor "transitivo" requiere:
- Todos los clientes deshabilitan explícitamente las características predeterminadas a través
"default-features": false
de o incluyen[core]
en la lista de características de la línea de comandos. - Asignar un nombre a la dependencia transitiva en la
vcpkg install
línea de comandos o como una dependencia directa en el manifiesto de nivel superior
En el registro mantenido de vcpkg, si la característica agrega API adicionales, ejecutables u otros archivos binarios, debe estar desactivada de forma predeterminada. En caso de duda, no marque una característica como predeterminada.
No usar características para controlar alternativas en interfaces publicadas
Si un consumidor de un puerto depende solo de la funcionalidad básica de ese puerto, con una alta probabilidad de que no se descomponan activando la característica. Esto es aún más importante cuando el consumidor no controla directamente la alternativa, sino mediante la configuración del compilador como /std:c++17
/ -std=c++17
.
Los ejemplos existentes que no aceptaríamos hoy conservamos por motivos de compatibilidad con versiones anteriores:
redis-plus-plus[cxx17]
controla un polyfill, pero no hornea la configuración en el árbol instalado.ace[wchar]
cambia todas las API para aceptarconst wchar_t*
en lugar deconst char*
.
Una característica puede reemplazar polyfills por alias siempre que el reemplazo esté horneado en el árbol instalado.
A pesar de lo anterior, los puertos pueden quitar polyfills con una característica, siempre y cuando:
- Al activar la característica, se cambian los polyfills a alias de la entidad polirrellenada.
- El estado del polyfill se hornea en los encabezados instalados, de modo que es poco probable que los errores de tiempo de ejecución "imposibles" de ABI no coincidan.
- Es posible que un consumidor del puerto escriba código que funcione en ambos modos, por ejemplo mediante una definición de tipo que sea polirrellenada o no.
Ejemplo:
abseil[cxx17]
cambiaabsl::string_view
a un reemplazo ostd::string_view
; la revisión implementa el requisito de baking.
Soluciones recomendadas
Si es fundamental exponer las alternativas subyacentes, se recomienda proporcionar mensajes en tiempo de compilación para indicar al usuario cómo copiar el puerto en una superposición privada:
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")
Técnicas de compilación
No usar dependencias proporcionadas
No use copias incrustadas de bibliotecas. Todas las dependencias deben dividirse y empaquetarse por separado para que se puedan actualizar y mantener.
Preferir el uso de CMake
Cuando haya varios sistemas de compilación disponibles, prefiera usar CMake.
Además, cuando proceda, puede ser más fácil y fácil de mantener para volver a escribir sistemas de compilación alternativos en CMake mediante file(GLOB)
directivas.
Ejemplos: abseil
Elegir archivos binarios estáticos o compartidos
Al compilar bibliotecas de CMake, vcpkg_cmake_configure()
pasará el valor correcto para BUILD_SHARED_LIBS
en función de la variante solicitada por el usuario.
Puede calcular parámetros de configuración alternativos mediante 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}
)
Si una biblioteca no ofrece opciones de configuración para seleccionar la variante de compilación, la compilación debe revisarse. Al aplicar revisiones a una compilación, siempre debe intentar maximizar la capacidad de mantenimiento futura del puerto. Normalmente esto significa minimizar el número de líneas que deben tocarse para corregir el problema a mano.
Ejemplo: Aplicación de revisiones a una biblioteca de CMake para evitar la creación de variantes no deseadas
Por ejemplo, al aplicar revisiones a una biblioteca basada en CMake, puede ser suficiente agregar EXCLUDE_FROM_ALL
a destinos no deseados y encapsular la install(TARGETS ...)
llamada en un if(BUILD_SHARED_LIBS)
. Esto será más corto que ajustar o eliminar cada línea que mencione la variante no deseada.
Para un proyecto CMakeLists.txt
con el siguiente contenido:
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)
Solo es necesario aplicar revisiones a la install(TARGETS)
línea.
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)
Al definir características, controle explícitamente las dependencias.
Al definir una característica que captura una dependencia opcional, asegúrese de que la dependencia no se usará accidentalmente cuando la característica no esté habilitada explícitamente.
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}
)
El fragmento de código siguiente que usa vcpkg_check_features()
es equivalente.
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
en el fragmento de código distingue mayúsculas de minúsculas. Para obtener más información, consulte la CMAKE_DISABLE_FIND_PACKAGE_<PackageName>
documentación y CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>
.
Colocar bibliotecas en conflicto en un manual-link
directorio
Una lib se considera en conflicto si realiza alguna de las acciones siguientes:
- Definir
main
- Definición de malloc
- Definir símbolos que también se declaran en otras bibliotecas
Las bibliotecas en conflicto suelen ser por diseño y no se consideran defectos. Dado que algunos sistemas de compilación se vinculan con todo en el directorio lib, estos deben moverse a un subdirectorio denominado manual-link
.
Control de versiones
Siga las convenciones comunes para el "version"
campo.
Al crear un puerto, siga la convención de control de versiones que usa el autor del paquete. Al actualizar el puerto, siga usando la misma convención a menos que la cadena ascendente indique lo contrario. Para obtener una explicación completa de nuestras convenciones, consulte nuestra documentación de control de versiones.
Si la cadena ascendente no ha publicado una versión en un tiempo, no cambie el esquema de control de versiones del puerto a version-date
para obtener los cambios más recientes. Estas confirmaciones pueden incluir cambios que no están listos para producción. En su lugar, pida al repositorio ascendente que publique una nueva versión.
Actualizar el "port-version"
campo en el archivo de manifiesto de los puertos modificados
vcpkg usa este campo para determinar si un puerto determinado está obsoleto y se debe cambiar cada vez que cambia el comportamiento del puerto.
Nuestra convención consiste en usar el "port-version"
campo para los cambios en el puerto que no cambian la versión ascendente y restablecer el "port-version"
valor de atrás a cero cuando se realiza una actualización a la versión ascendente.
Por ejemplo:
- La versión del paquete de Zlib es actualmente
1.2.1
, sin explícita"port-version"
(equivalente a un"port-version"
de0
). - Ha descubierto que se ha implementado el archivo de copyright incorrecto y lo ha corregido en el archivo portfile.
- Debe actualizar el
"port-version"
campo del archivo de manifiesto a1
.
Consulte la documentación de control de versiones para obtener más información.
Actualizar los archivos de versión de versions/
cualquier puerto modificado
vcpkg usa un conjunto de archivos de metadatos para alimentar su característica de control de versiones. Estos archivos se encuentran en las siguientes ubicaciones:
${VCPKG_ROOT}/versions/baseline.json
, (este archivo es común a todos los puertos) y${VCPKG_ROOT}/versions/${first-letter-of-portname}-/${portname}.json
(uno por puerto).
Por ejemplo, para zlib
los archivos pertinentes son:
${VCPKG_ROOT}/versions/baseline.json
${VCPKG_ROOT}/versions/z-/zlib.json
Esperamos que cada vez que actualice un puerto, también actualice sus archivos de versión.
El método recomendado para actualizar estos archivos es ejecutar el x-add-version
comando, por ejemplo:
vcpkg x-add-version zlib
Si va a actualizar varios puertos al mismo tiempo, puede ejecutar:
vcpkg x-add-version --all
para actualizar los archivos de todos los puertos modificados a la vez.
Nota:
Estos comandos requieren que haya confirmado los cambios en los puertos antes de ejecutarlos. El motivo es que el SHA de Git del directorio de puertos es necesario en estos archivos de versión. Pero no se preocupe, el x-add-version
comando le avisará si tiene cambios locales que no se han confirmado.
Para obtener más información, consulte referencia de control de versiones y Creación de registros.
Aplicación de revisiones
vcpkg es una solución de empaquetado, no los propietarios finales de los componentes que implementamos. En algunos casos, es necesario aplicar revisiones para mejorar la compatibilidad de los componentes con plataformas o la compatibilidad de los componentes entre sí.
- Queremos evitar revisiones que:
- upstream no estaría de acuerdo con
- causar vulnerabilidades o bloqueos
- somos incapaz de mantener en las actualizaciones de versiones ascendentes
- son lo suficientemente grandes como para provocar el entrelazamiento de licencias con el propio repositorio vcpkg.
Notificar a los propietarios ascendentes las revisiones pertinentes de nivel superior
Si una revisión podría ser útil en la cadena ascendente, debe recibir una notificación del contenido de la revisión. (Las revisiones que aplican un comportamiento específico de vcpkg que no están relacionados con la cadena ascendente, como la desvención de una dependencia, no requieren notificación).
Para evitar situaciones en las que la cadena ascendente no está de acuerdo con la revisión, esperaremos al menos 30 días para aplicar dichas revisiones.
Omitiremos este período de espera si tenemos alta confianza de que el cambio es correcto. Entre los ejemplos de revisiones de confianza alta se incluyen, entre otros:
- La aceptación de upstream como revisión (por ejemplo, la devolución de un cambio específico de una solicitud de incorporación de cambios se ha combinado).
- Agregar elementos que faltan
#include
. - Correcciones de código de producto pequeñas y obvias (por ejemplo, inicializando una variable sin inicializar).
- Deshabilitación de componentes irrelevantes en vcpkg de la compilación, como pruebas o ejemplos.
Preferir opciones sobre la aplicación de revisiones
Es preferible establecer opciones en una llamada a para aplicar revisiones directamente a vcpkg_configure_xyz()
la configuración.
Opciones comunes que permiten evitar la aplicación de revisiones:
- [MSBUILD]
<PropertyGroup>
La configuración dentro del archivo del proyecto se puede invalidar a través/p:
de parámetros - [CMAKE] Las llamadas a
find_package(XYz)
en scripts de CMake se pueden deshabilitar a través de-DCMAKE_DISABLE_FIND_PACKAGE_XYz=ON
- [CMAKE] Las variables de caché (declaradas como
set(VAR "value" CACHE STRING "Documentation")
ooption(VAR "Documentation" "Default Value")
) se pueden invalidar simplemente pasandolas en la línea de comandos como-DVAR:STRING=Foo
. Una excepción notable es si elFORCE
parámetro se pasa aset()
. Para obtener más información, consulte la documentación de CMakeset
.
Preferir la descarga de revisiones aprobadas para comprobarlas en el puerto
Si se puede obtener un archivo de revisión aprobado o combinado de la cadena ascendente, los puertos deben intentar descargarlos y aplicarlos en lugar de tenerlos como parte de los archivos de puerto. Este proceso se prefiere porque:
- Confirma que la cadena ascendente ha aceptado los cambios de revisión
- Simplifica el proceso de revisión cambiando las responsabilidades ascendentes
- Reduce el tamaño del repositorio vcpkg para los usuarios que no usan la revisión.
- Evita conflictos de licencias con el repositorio vcpkg.
Las revisiones deben descargarse desde un punto de conexión estable para evitar conflictos de SHA.
Al descargar archivos de revisión desde una solicitud de incorporación de cambios o confirmar desde GitHub y GitLab, el ?full_index=1
parámetro debe anexarse a la dirección URL de descarga.
Ejemplos:
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
Preferir la aplicación de revisiones invalidando VCPKG_<VARIABLE>
valores
Algunas variables con VCPKG_<VARIABLE>
prefijo tienen un equivalente CMAKE_<VARIABLE>
.
Sin embargo, no todos ellos se pasan a la compilación del paquete interno (consulte implementación: Cadena de herramientas de Windows).
Considere el ejemplo siguiente:
set(VCPKG_C_FLAGS "-O2 ${VCPKG_C_FLAGS}")
set(VCPKG_CXX_FLAGS "-O2 ${VCPKG_CXX_FLAGS}")
El uso vcpkg
de las cadenas de herramientas integradas funciona, ya que el valor de VCPKG_<LANG>_FLAGS
se reenvía a la variable adecuada CMAKE_LANG_FLAGS
. Sin embargo, una cadena de herramientas personalizada que no conoce las vcpkg
variables no las reenvía.
Por este motivo, es preferible aplicar revisiones al sistema de compilación directamente al establecer CMAKE_<LANG>_FLAGS
.
Minimizar las revisiones
Al realizar cambios en una biblioteca, intente minimizar la diferencia final. Esto significa que no debe volver a formatear el código fuente ascendente al realizar cambios que afecten a una región. Al deshabilitar un condicional, es mejor agregar o AND FALSE
&& 0
a la condición que eliminar cada línea del condicional. Si es necesario deshabilitar una región grande, es más corto agregar o if(0)
#if 0
alrededor de la región en lugar de eliminar todas las líneas de la revisión.
No agregue revisiones si el puerto está obsoleto y la actualización del puerto a una versión más reciente publicada solucionaría el mismo problema. vcpkg prefiere actualizar los puertos a través de la aplicación de revisiones a versiones obsoletas.
Esto ayuda a mantener el tamaño del repositorio vcpkg inactivo, así como mejora la probabilidad de que la revisión se aplique a futuras versiones de código.
No implementar características en revisiones
El propósito de aplicar revisiones en vcpkg es habilitar la compatibilidad con compiladores, bibliotecas y plataformas. No es implementar nuevas características en lugar de seguir el procedimiento de código abierto adecuado (enviar un problema/PR/etc.).
No compile pruebas, documentos o ejemplos de forma predeterminada
Al enviar un puerto nuevo, compruebe si hay opciones como BUILD_TESTS
o WITH_TESTS
y POCO_ENABLE_SAMPLES
asegúrese de que los archivos binarios adicionales están deshabilitados. Esto minimiza los tiempos de compilación y las dependencias del usuario medio.
Opcionalmente, puede agregar una test
característica que permita compilar las pruebas, pero esto no debe estar en la Default-Features
lista.
Permitir que los usuarios existentes de la biblioteca cambien a vcpkg
No agregar CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
A menos que el autor de la biblioteca ya lo use, no deberíamos usar esta funcionalidad de CMake porque interactúa mal con las plantillas de C++ y interrumpe determinadas características del compilador. Las bibliotecas que no proporcionan un archivo .def y no usan declaraciones __declspec() simplemente no admiten compilaciones compartidas para Windows y deben marcarse como tal con vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
.
No cambie el nombre de los archivos binarios fuera de los nombres proporcionados por la cadena ascendente.
Esto significa que si la biblioteca ascendente tiene nombres diferentes en la versión y depuración (libx frente a libxd), la biblioteca de depuración no debe cambiarse a libx
. Viceversa, si la biblioteca ascendente tiene el mismo nombre en la versión y depuración, no deberíamos introducir un nuevo nombre.
Advertencia importante:
- Las variantes estáticas y compartidas a menudo deben cambiarse a un esquema común. Esto permite a los consumidores usar un nombre común e ignorar la vinculación de bajada. Esto es seguro porque solo hacemos que uno a la vez esté disponible.
Si una biblioteca genera archivos de integración de CMake (foo-config.cmake
), el cambio de nombre debe realizarse mediante la aplicación de revisiones a la compilación de CMake en lugar de simplemente llamar a file(RENAME)
en los archivos o LIB de salida.
Por último, los archivos DLL en Windows nunca se deben cambiar de nombre después de la compilación porque interrumpe los LIB generados.
Manifiestos
Es necesario dar formato al archivo de manifiesto. Use el siguiente comando para dar formato a todos los archivos de manifiesto:
> vcpkg format-manifest --all
Trillizos
No aceptamos solicitudes para agregar tripletas no comunitarias en este momento. La promoción de la comunidad al estado de triplet completo se basa principalmente en el presupuesto para que el hardware pruebe estos tripletes y se basará en las métricas enviadas por vcpkg para maximizar la probabilidad de que las personas usen realmente se prueben completamente.
Agregaremos tripletas de la comunidad si:
- Se demuestra que las personas usarán realmente ese triplete comunitario; y
- no sabemos que este triplete está roto.
Por ejemplo, no agregamos un triplete en porque el autor estaba intentando "completar el conjunto" en https://github.com/microsoft/vcpkg/pull/29034 lugar de indicar que realmente usarían tal cosa y no agregamos linux-dynamic hasta que se creó la solución patchelf para que los resultados se vuelvan a colocar.
Notas útiles de implementación
Los archivos de puerto se ejecutan en modo de script
Aunque portfile.cmake
's y CMakeLists.txt
's comparten una sintaxis común y construcciones principales del lenguaje CMake (también conocido como "Comandos de scripting"), los archivos de puerto se ejecutan en "Modo de script", mientras que CMakeLists.txt
los archivos se ejecutan en "Modo de proyecto". La diferencia más importante entre estos dos modos es que "Modo de script" no tiene los conceptos de "Cadena de herramientas", "Language" y "Target". Los comportamientos, incluidos los comandos de scripting, que dependen de estas construcciones (por ejemplo CMAKE_CXX_COMPILER
, , CMAKE_EXECUTABLE_SUFFIX
, CMAKE_SYSTEM_NAME
) no serán correctos.
Los archivos port tienen acceso directo a las variables establecidas en el archivo triplet, pero CMakeLists.txt
no (aunque a menudo hay una traducción que sucede, VCPKG_LIBRARY_LINKAGE
frente BUILD_SHARED_LIBS
a ).
Los archivos de puerto y las compilaciones de Project invocadas por los archivos port se ejecutan en distintos procesos. Conceptualmente:
+----------------------------+ +------------------------------------+
| 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) |
+----------------------------+ +------------------------------------+
Para determinar el host en un archivo de puerto, las variables estándar de CMake están bien (CMAKE_HOST_WIN32
).
Para determinar el destino en un archivo port, se deben usar las variables triplet vcpkg (VCPKG_CMAKE_SYSTEM_NAME
).
Consulte también nuestra documentación triple para obtener una enumeración completa de las posibles opciones de configuración.