Compartir a través de


Introducción al control de versiones

Uso de versiones con manifiestos

Comencemos con la creación de un proyecto de CMake simple que depende de fmt y zlib.

Cree una carpeta con los siguientes archivos:

vcpkg.json

{
    "name": "versions-test",
    "version": "1.0.0",
    "dependencies": [
        {
            "name": "fmt",
            "version>=": "7.1.3#1"
        }, 
        "zlib"
    ],
    "builtin-baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc"
}

main.cpp

#include <fmt/core.h>
#include <zlib.h>

int main()
{
    fmt::print("fmt version is {}\n"
               "zlib version is {}\n", 
               FMT_VERSION, ZLIB_VERSION);
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.18)

project(versionstest CXX)

add_executable(main main.cpp)

find_package(ZLIB REQUIRED)
find_package(fmt CONFIG REQUIRED)
target_link_libraries(main PRIVATE ZLIB::ZLIB fmt::fmt)

Y ahora compilamos y ejecutamos nuestro proyecto con CMake:

  1. Cree el directorio de compilación para el proyecto.

    PS D:\versions-test> mkdir build
    PS D:\versions-test> cd build
    
  2. Configure CMake.

    PS D:\versions-test\build> cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake ..
    -- Running vcpkg install
    Detecting compiler hash for triplet x86-windows...
    The following packages will be built and installed:
        fmt[core]:x64-windows -> 7.1.3#1 -- D:\Work\viromer\vcpkg\buildtrees\versioning\versions\fmt\4f8427eb0bd40da1856d4e67bde39a4fda689d72
        vcpkg-cmake[core]:x64-windows -> 2021-02-26 -- D:\Work\viromer\vcpkg\buildtrees\versioning\versions\vcpkg-cmake\51896aa8073adb5c8450daa423d03eedf0dfc61f
        vcpkg-cmake-config[core]:x64-windows -> 2021-02-26 -- D:\Work\viromer\vcpkg\buildtrees\versioning\versions\vcpkg-cmake-config\d255b3d566a8861dcc99a958240463e678528066
        zlib[core]:x64-windows -> 1.2.11#9 -- D:\Work\viromer\vcpkg\buildtrees\versioning\versions\zlib\827111046e37c98153d9d82bb6fa4183b6d728e4
    ...
    
  3. Compile el proyecto.

    PS D:\versions-test\build> cmake --build .
    [2/2] Linking CXX executable main.exe
    
  4. Ejecute la aplicación.

    PS D:\versions-test\build> ./main.exe
    fmt version is 70103
    zlib version is 1.2.11
    

Eche un vistazo a la salida:

fmt[core]:x86-windows -> 7.1.3#1 -- D:\vcpkg\buildtrees\versioning\versions\fmt\4f8427eb0bd40da1856d4e67bde39a4fda689d72
...
zlib[core]:x86-windows -> 1.2.11#9 -- D:\vcpkg\buildtrees\versioning\versions\zlib\827111046e37c98153d9d82bb6fa4183b6d728e4

En lugar de usar los archivos portfiles en ports/, vcpkg está desprotegiéndose los archivos de cada versión de buildtrees/versioning/versions/. Los archivos de ports/ se siguen usando al ejecutar vcpkg en modo clásico.

Nota:

La salida de vcpkg mientras configura CMake solo está disponible cuando se usa la versión 3.18 de CMake o una versión más reciente. Si usa una CMake anterior, puede comprobar el archivo en el vcpkg-manifest-install.log directorio de compilación en su lugar.

Lea nuestra entrada de blog de anuncio de manifiestos para obtener información sobre cómo usar manifiestos con MSBuild.

Cambios de manifiesto

Si ha usado manifiestos antes de observar que hay algunas propiedades JSON nuevas. Revisemos estos cambios:

version

{
    "name": "versions-test",
    "version": "1.0.0"
}

Esta es la declaración de versión del proyecto. Anteriormente, solo podía declarar versiones para los proyectos mediante la version-string propiedad . Ahora que el control de versiones ha llegado, vcpkg es consciente de algunos esquemas de control de versiones nuevos.

Esquema de versión Descripción
version Valores numéricos separados por puntos: 1.0.0.5.
version-semver Versiones semánticas compatibles: 1.2.0 y 1.2.0-rc.
version-date Fechas en YYYY-MM-DD formato: 2021-01-01
version-string Cadenas arbitrarias: vista, candy.

version>=

{
    "dependencies": [
        { "name": "fmt", "version>=": "7.1.3" },
        "zlib"
    ]
}

Esta propiedad se usa para expresar restricciones de versión mínimas, solo se permite como parte de las "dependencies" declaraciones. En nuestro ejemplo, establecemos una restricción explícita en la versión 7.1.3#1 de fmt.

vcpkg puede actualizar esta restricción si una dependencia transitiva requiere una versión más reciente. Por ejemplo, si zlib se declarara una dependencia en la fmt versión 7.1.4 , vcpkg se instalaría 7.1.4 en su lugar.

vcpkg usa un enfoque de versión mínima, en nuestro ejemplo, incluso si fmt se publicara la versión 8.0.0 , vcpkg seguiría instalando la versión 7.1.3#1 , ya que es la versión mínima que satisface la restricción. Las ventajas de este enfoque son que no obtiene actualizaciones de dependencia inesperadas al actualizar vcpkg y obtiene compilaciones reproducibles (en términos de versión usadas) siempre que use el mismo manifiesto.

Si desea actualizar las dependencias, puede aumentar la restricción de versión mínima o usar una línea base más reciente.

builtin-baseline

{ "builtin-baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc" }

Este campo declara la línea base de control de versiones para todos los puertos. Es necesario establecer una línea base para habilitar el control de versiones; de lo contrario, obtendrá las versiones actuales en el ports/ directorio. Puede ejecutar "git rev-parse HEAD" para obtener la confirmación actual de vcpkg y establecerla como la línea base integrada. Consulte la "builtin-baseline" documentación para obtener más información.

En nuestro ejemplo, no declaramos una restricción de versión para zlib; en su lugar, la versión se toma de la línea base. Internamente, vcpkg buscará la confirmación 3426db05b996481ca31e95fff3734cf23e0f51bc para averiguar de qué versión de zlib era la más reciente en ese momento (en nuestro caso era 1.2.11#9).

Durante la resolución de versiones, las versiones de línea base se tratan como restricciones de versión mínimas. Si declara una restricción explícita inferior a una versión de línea base, la restricción explícita se actualizará a la versión de línea base.

Por ejemplo, si modificamos nuestras dependencias de la siguiente manera:

{ "dependencies": [
    {
        "name": "fmt",
        "version>=": "7.1.3#1"
    },
    {
        "name": "zlib",
        "version>=": "1.2.11#7"
    }
] }

Nota:

El valor 1.2.11#7 representa la versión 1.2.11, la versión del 7puerto .

Dado que la línea base introduce una restricción de versión mínima para zlib en 1.2.11#9 y una versión superior cumple la restricción de versión mínima para 1.2.11#7, vcpkg puede actualizarla.

Las líneas base también son un mecanismo práctico para actualizar varias versiones a la vez, por ejemplo, si desea depender de varias boost bibliotecas, es más conveniente establecer la baseline vez que declarar una restricción de versión en cada paquete.

¿Pero qué ocurre si desea anclar una versión anterior a la línea base?

overrides

Dado que las líneas base establecen un piso de versión para todos los paquetes y las restricciones explícitas se actualizan cuando son inferiores a la línea base, necesitamos otro mecanismo para degradar las versiones más allá de la línea base.

El mecanismo vcpkg proporciona para ese escenario es overrides. Cuando se declara una invalidación en un paquete, vcpkg omitirá todas las demás restricciones de versión declaradas directamente en el manifiesto o desde dependencias transitivas. En resumen, overrides obligará a vcpkg a usar la versión exacta declarada, período.

Vamos a modificar nuestro ejemplo una vez más, esta vez para forzar a vcpkg a usar la versión 6.0.0 de fmt.

{
    "name": "versions-test",
    "version": "1.0.0",
    "dependencies": [
        {
            "name": "fmt",
            "version>=": "7.1.3#1"
        },
        {
            "name": "zlib",
            "version>=": "1.2.11#7"
        }
    ],
    "builtin-baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc",
    "overrides": [
        {
            "name": "fmt",
            "version": "6.0.0"
        }
    ]
}

Recompile nuestro proyecto:

PS D:\versions-test\build> rm ./CMakeCache.txt
PS D:\versions-test\build> rm -r ./vcpkg_installed
PS D:\versions-test\build> cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake ..
-- Running vcpkg install
Detecting compiler hash for triplet x86-windows...
The following packages will be built and installed:
    fmt[core]:x86-windows -> 6.0.0 -- D:\vcpkg\buildtrees\versioning\versions\fmt\d99b6a35e1406ba6b6e09d719bebd086f83ed5f3
    zlib[core]:x86-windows -> 1.2.11#9 -- D:\vcpkg\buildtrees\versioning\versions\zlib\827111046e37c98153d9d82bb6fa4183b6d728e4
...
PS D:\versions-test\build> cmake --build .
[2/2] Linking CXX executable main.exe

¡Y ejecútelo!

PS D:\versions-test\build> .\main.exe
fmt version is 60000
zlib version is 1.2.11

Observe cómo fmt ahora está en la versión 6.0.0 como queríamos.

Versiones y puertos personalizados

Lo último que se debe analizar es cómo interactúan los puertos de superposición con la resolución de control de versiones. La respuesta es: no lo hacen.

Al proporcionar una superposición para un puerto, vcpkg siempre usará el puerto de superposición sin tener en cuenta la versión contenida en él. Las razones son dos veces: (1) es coherente con el comportamiento existente de los puertos de superposición de enmascarar completamente el puerto existente y (2) los puertos de superposición no (y no se espera que) proporcionen suficiente información para alimentar la característica de control de versiones de vcpkg.

Si desea tener personalización de puerto flexible junto con el control de versiones, debe considerar la posibilidad de crear su propio registro personalizado.

Información adicional

Si está interesado en profundizar en los detalles de cómo funciona el control de versiones, le recomendamos que lea nuestros conceptos de Referencia de control de versiones y Control de versiones.