Compartilhar via


Introdução ao controle de versão

Usando versões com manifestos

Vamos começar com a criação de um projeto CMake simples que depende de fmt e zlib.

Crie uma pasta com os seguintes arquivos:

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)

E agora construímos e executamos nosso projeto com o CMake:

  1. Crie o diretório de compilação para o projeto.

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

    PS D:\versions-test\build> cmake --build .
    [2/2] Linking CXX executable main.exe
    
  4. Execute-o!

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

Dê uma olhada na saída:

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

Em vez de usar os portfiles no , vcpkg está fazendo check-out dos arquivos para cada versão no ports/buildtrees/versioning/versions/. Os arquivos em ports/ ainda são usados ao executar vcpkg no modo clássico.

Observação

A saída do vcpkg durante a configuração do CMake só está disponível ao usar a versão 3.18 do CMake ou mais recente. Se você estiver usando um CMake mais antigo, poderá verificar o vcpkg-manifest-install.log arquivo no diretório de compilação.

Leia nossa postagem no blog de anúncio de manifestos para saber como usar manifestos com o MSBuild.

Alterações manifestas

Se você tiver usado manifestos antes, notará que há algumas novas propriedades JSON. Vamos rever essas alterações:

version

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

Esta é a declaração de versão do seu projeto. Anteriormente, você só podia declarar versões para seus projetos usando a version-string propriedade. Agora que o versionamento chegou, vcpkg está ciente de alguns novos esquemas de versionamento.

Esquema de versão Descrição
version Numéricos separados por pontos: 1.0.0.5.
version-semver Versões semânticas compatíveis: 1.2.0 e 1.2.0-rc.
version-date Datas no YYYY-MM-DD formato: 2021-01-01
version-string Cadeias de caracteres arbitrárias: vista, candy.

version>=

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

Essa propriedade é usada para expressar restrições de versão mínimas, ela é permitida apenas como parte das "dependencies" declarações. Em nosso exemplo, definimos uma restrição explícita na versão 7.1.3#1 do fmt.

vcpkg tem permissão para atualizar essa restrição se uma dependência transitiva exigir uma versão mais recente. Por exemplo, se zlib fosse declarar uma dependência da fmt versão 7.1.4 , o vcpkg seria instalado 7.1.4 .

vcpkg usa uma abordagem de versão mínima, em nosso exemplo, mesmo fmt se a versão fosse lançada, vcpkg ainda instalaria a versão, pois essa é a versão 8.0.07.1.3#1 mínima que satisfaz a restrição. As vantagens dessa abordagem são que você não obtém atualizações de dependência inesperadas quando atualiza o vcpkg e obtém compilações reproduzíveis (em termos de versão usada), desde que use o mesmo manifesto.

Se você quiser atualizar suas dependências, poderá aumentar a restrição de versão mínima ou usar uma linha de base mais recente.

builtin-baseline

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

Este campo declara a linha de base de controle de versão para todas as portas. A definição de uma linha de base é necessária para habilitar o controle de versão, caso contrário, você obterá as versões atuais no ports/ diretório. Você pode executar 'git rev-parse HEAD' para obter a confirmação atual de vcpkg e defini-la como a linha de base interna. Consulte a documentação para "builtin-baseline" obter mais informações.

Em nosso exemplo, não declaramos uma restrição de versão para zlib; em vez disso, a versão é retirada da linha de base. Internamente, vcpkg vai procurar em compromisso 3426db05b996481ca31e95fff3734cf23e0f51bc para descobrir qual versão do zlib era a mais recente naquele momento (no nosso caso foi 1.2.11#9).

Durante a resolução de versão, as versões de linha de base são tratadas como restrições mínimas de versão. Se você declarar uma restrição explícita menor que uma versão de linha de base, a restrição explícita será atualizada para a versão de linha de base.

Por exemplo, se modificarmos nossas dependências assim:

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

Observação

O valor 1.2.11#7 representa version , port version 71.2.11.

Como a linha de base introduz uma restrição de versão mínima para at 1.2.11#9 e uma versão superior satisfaz a restrição de versão mínima para , vcpkg tem permissão para zlib1.2.11#7atualizá-la.

As linhas de base também são um mecanismo conveniente para atualizar várias versões ao mesmo tempo, por exemplo, se você quiser depender de várias boost bibliotecas, é mais conveniente definir o baseline once do que declarar uma restrição de versão em cada pacote.

Mas e se você quiser fixar uma versão mais antiga do que a linha de base?

overrides

Como as linhas de base estabelecem um piso de versão para todos os pacotes e as restrições explícitas são atualizadas quando são inferiores à linha de base, precisamos de outro mecanismo para fazer downgrade das versões além da linha de base.

O mecanismo que vcpkg prevê para esse cenário é overrides. Quando uma substituição é declarada em um pacote, vcpkg ignorará todas as outras restrições de versão declaradas diretamente no manifesto ou de dependências transitivas. Em suma, vai obrigar vcpkg a usar a versão exata declarada, overrides ponto final.

Vamos modificar nosso exemplo mais uma vez, desta vez para forçar vcpkg a usar a versão 6.0.0 do 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"
        }
    ]
}

Reconstrua nosso projeto:

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

E corra!

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

Observe como o fmt está agora na versão 6.0.0 exatamente como queríamos.

Versões e portas personalizadas

A última coisa a discutir é como as portas de sobreposição interagem com a resolução de controle de versão. A resposta é: não.

Entrando em mais detalhes, quando você fornece uma sobreposição para uma porta, vcpkg sempre usará a porta de sobreposição sem se importar com a versão contida nela. As razões são duas: (1) é consistente com o comportamento existente das portas de sobreposição de mascarar completamente a porta existente, e (2) as portas de sobreposição não fornecem (e não se espera que forneçam) informações suficientes para alimentar o recurso de controle de versão do vcpkg.

Se você quiser ter personalização de porta flexível junto com o controle de versão, você deve considerar fazer seu próprio registro personalizado.

Leitura adicional

Se você estiver interessado em se aprofundar nos detalhes de como o controle de versão funciona, recomendamos que você leia nossos conceitos de referência e controle de versão de versão.