Skip to content

vcpkg示例

创建一个简单的CMake项目

先创建一个简单的项目。

main.cpp

cpp
//
// Created by root on 23-8-22.
//

#include <iostream>

int main()
{
    std::cout<<"hello world"<<std::endl;
    return EXIT_SUCCESS;
}

CMakeLists.txt

cmake
cmake_minimum_required(VERSION 3.23)
project(vcpkg_learn)

set(CMAKE_CXX_STANDARD 14)

add_executable(vcpkg_learn main.cpp)

加载项目:

bash
# 进入项目根目录
cd vcpkg_learn

# 加载
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=ninja -G Ninja -S . -B ./cmake-build-debug

如下:

bash
[root@localhost vcpkg_learn]# ls
CMakeLists.txt  main.cpp
[root@localhost vcpkg_learn]# cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=ninja -G Ninja -S . -B ./cmake-build-debug
-- The C compiler identification is GNU 11.2.1
-- The CXX compiler identification is GNU 11.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/rh/devtoolset-11/root/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/rh/devtoolset-11/root/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (0.4s)
-- Generating done (0.0s)
-- Build files have been written to: /root/vcpkg_learn/cmake-build-debug

编译代码:

bash
cmake --build ./cmake-build-debug --target vcpkg_learn -j $(nproc)

执行:

bash
./vcpkg_learn

可以看到程序正确执行。

使用vcpkg

我不想像其他博客一样全局安装vcpkg,我希望将其集成在项目中。

将项目初始化为一个git仓库:

bash
git init

添加vcpkg作为git子模块:

bash
git submodule add https://github.com/Microsoft/vcpkg.git

修改CMakeLists.txt,其内容如下:

cmake
cmake_minimum_required(VERSION 3.23)

set(CMAKE_CXX_STANDARD 14)

if(NOT DEFINED URL_BASE)
    set(URL_BASE "github.com")
endif()

list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)

set(VERSION "3.4.0")
set(VERSION_SUFFIX "")

# vcpkg init
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
    find_package(Git REQUIRED)
    execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive -- vcpkg WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
    # 将vcpkg集成到cmake项目中,等同于在加载项目时的 -DCMAKE_TOOLCHAIN_FILE=<vcpkg_dir>/scripts/buildsystems/vcpkg.cmake
    set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake"
            CACHE STRING "Vcpkg toolchain file")
endif()

project(vcpkg_learn)

add_executable(vcpkg_learn main.cpp)

加载项目:

bash
# 进入项目根目录
cd vcpkg_learn

# 加载
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=ninja -G Ninja -S . -B ./cmake-build-debug

安装vcpkg:

bash
# 进入项目根目录
cd vcpkg_learn

cd vcpkg && ./bootstrap-vcpkg.sh

完成后在目录中可以看到vcpkg的可执行文件。

安装一个库

搜索cryptopp:

bash
[root@localhost vcpkg]# ./vcpkg search cryptopp
cryptopp                 8.8.0            Crypto++ is a free C++ class library of cryptographic schemes.
cryptopp[pem-pack]                        Crypto++ with PEM pack
The result may be outdated. Run `git pull` to get the latest results.
If your port is not listed, please open an issue at and/or consider making a pull request.    -  https://github.com/Microsoft/vcpkg/issues

安装cryptopp:

bash
[root@localhost vcpkg]# ./vcpkg install cryptopp
Computing installation plan...
The following packages will be built and installed:
    cryptopp:x64-linux -> 8.8.0
  * vcpkg-cmake:x64-linux -> 2023-05-04
  * vcpkg-cmake-config:x64-linux -> 2022-02-06#1
Additional packages (*) will be modified to complete this operation.
Detecting compiler hash for triplet x64-linux...
Restored 0 package(s) from /root/.cache/vcpkg/archives in 15.2 us. Use --debug to see more details.
Installing 1/3 vcpkg-cmake:x64-linux...
Building vcpkg-cmake:x64-linux...
-- Installing: /root/vcpkg_learn/vcpkg/packages/vcpkg-cmake_x64-linux/share/vcpkg-cmake/vcpkg_cmake_configure.cmake
-- Installing: /root/vcpkg_learn/vcpkg/packages/vcpkg-cmake_x64-linux/share/vcpkg-cmake/vcpkg_cmake_build.cmake
-- Installing: /root/vcpkg_learn/vcpkg/packages/vcpkg-cmake_x64-linux/share/vcpkg-cmake/vcpkg_cmake_install.cmake
-- Installing: /root/vcpkg_learn/vcpkg/packages/vcpkg-cmake_x64-linux/share/vcpkg-cmake/vcpkg-port-config.cmake
-- Installing: /root/vcpkg_learn/vcpkg/packages/vcpkg-cmake_x64-linux/share/vcpkg-cmake/copyright
-- Performing post-build validation
Stored binaries in 1 destinations in 3.45 ms.
Elapsed time to handle vcpkg-cmake:x64-linux: 17.2 ms
Installing 2/3 vcpkg-cmake-config:x64-linux...
Building vcpkg-cmake-config:x64-linux...
-- Installing: /root/vcpkg_learn/vcpkg/packages/vcpkg-cmake-config_x64-linux/share/vcpkg-cmake-config/vcpkg_cmake_config_fixup.cmake
-- Installing: /root/vcpkg_learn/vcpkg/packages/vcpkg-cmake-config_x64-linux/share/vcpkg-cmake-config/vcpkg-port-config.cmake
-- Installing: /root/vcpkg_learn/vcpkg/packages/vcpkg-cmake-config_x64-linux/share/vcpkg-cmake-config/copyright
-- Performing post-build validation
Stored binaries in 1 destinations in 2.62 ms.
Elapsed time to handle vcpkg-cmake-config:x64-linux: 15.9 ms
Installing 3/3 cryptopp:x64-linux...
Building cryptopp:x64-linux...
-- Downloading https://github.com/abdes/cryptopp-cmake/archive/f857b775bcb4ff24e4993d85cce811587f8b0616.tar.gz -> abdes-cryptopp-cmake-f857b775bcb4ff24e4993d85cce811587f8b0616.tar.gz...
-- Extracting source /root/vcpkg_learn/vcpkg/downloads/abdes-cryptopp-cmake-f857b775bcb4ff24e4993d85cce811587f8b0616.tar.gz
-- Applying patch fix-git-branch.patch
-- Using source at /root/vcpkg_learn/vcpkg/buildtrees/cryptopp/src/587f8b0616-6acbde05eb.clean
-- Downloading https://github.com/weidai11/cryptopp/archive/4d0cad5401d1a2c998b314bc89288c9620d3021d.tar.gz -> weidai11-cryptopp-4d0cad5401d1a2c998b314bc89288c9620d3021d.tar.gz...
-- Extracting source /root/vcpkg_learn/vcpkg/downloads/weidai11-cryptopp-4d0cad5401d1a2c998b314bc89288c9620d3021d.tar.gz
-- Applying patch patch.patch
-- Using source at /root/vcpkg_learn/vcpkg/buildtrees/cryptopp/src/9620d3021d-0989fd3960.clean
-- Found external ninja('1.10.2').
-- Configuring x64-linux
-- Building x64-linux-dbg
-- Building x64-linux-rel
-- Fixing pkgconfig file: /root/vcpkg_learn/vcpkg/packages/cryptopp_x64-linux/lib/pkgconfig/cryptopp.pc
-- Fixing pkgconfig file: /root/vcpkg_learn/vcpkg/packages/cryptopp_x64-linux/debug/lib/pkgconfig/cryptopp.pc
-- Performing post-build validation
Stored binaries in 1 destinations in 2.2 s.
Elapsed time to handle cryptopp:x64-linux: 1.2 min
Total install time: 1.2 min
cryptopp provides CMake targets:

    # this is heuristically generated, and may not be correct
    find_package(cryptopp CONFIG REQUIRED)
    target_link_libraries(main PRIVATE cryptopp::cryptopp)

可以看到,依赖库安装在了项目目录的vcpkg/packages/里面。

列出已经安装的开源库:

bash
[root@localhost vcpkg]# ./vcpkg list
cryptopp:x64-linux                                8.8.0               Crypto++ is a free C++ class library of cryptogr...
vcpkg-cmake-config:x64-linux                      2022-02-06#1        
vcpkg-cmake:x64-linux                             2023-05-04

使用cryptopp,修改CMakeLists.txt

cmake
cmake_minimum_required(VERSION 3.23)

set(CMAKE_CXX_STANDARD 14)

if(NOT DEFINED URL_BASE)
    set(URL_BASE "github.com")
endif()

list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)

set(VERSION "3.4.0")
set(VERSION_SUFFIX "")

# vcpkg init
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
    find_package(Git REQUIRED)
    execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive -- vcpkg WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
    set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake"
            CACHE STRING "Vcpkg toolchain file")
endif()

project(vcpkg_learn)

find_package(cryptopp CONFIG REQUIRED)
add_executable(vcpkg_learn main.cpp)
target_link_libraries(vcpkg_learn PRIVATE cryptopp::cryptopp)

加载项目:

bash
# 进入项目根目录
cd vcpkg_learn

# 加载
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=ninja -G Ninja -S . -B ./cmake-build-debug

是可以加载通过的。

接下来修改代码,main.cpp

cpp
//
// Created by root on 23-8-22.
//

#include <iostream>
#include <cryptopp/eccrypto.h>
#include <cryptopp/osrng.h>
#include <cryptopp/hex.h>
#include <cryptopp/oids.h>

void printPrivateKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey);

void printPublicKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey);

int main() {
    CryptoPP::AutoSeededRandomPool rng;

    // 生成ECDSA密钥对
    CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey privateKey;
    privateKey.Initialize(rng, CryptoPP::ASN1::secp256r1());

    CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey publicKey;
    privateKey.MakePublicKey(publicKey);

    // 输出密钥对
    printPrivateKey(privateKey);
    printPublicKey(publicKey);

    return 0;
}

void printPrivateKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PrivateKey &privateKey) {
    std::string privateKeyStr;

    CryptoPP::HexEncoder privateKeyEncoder(new CryptoPP::StringSink(privateKeyStr));
    privateKey.Save(privateKeyEncoder);
    privateKeyEncoder.MessageEnd();

    std::cout << "Private Key (hex): 0x" << privateKeyStr << std::endl;
}

void printPublicKey(const CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey &publicKey) {
    std::string publicKeyStr;

    CryptoPP::HexEncoder publicKeyEncoder(new CryptoPP::StringSink(publicKeyStr));
    publicKey.Save(publicKeyEncoder);
    publicKeyEncoder.MessageEnd();

    std::cout << "Public Key (hex): 0x" << publicKeyStr << std::endl;
}

加载项目:

bash
# 进入项目根目录
cd vcpkg_learn

# 加载
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=ninja -G Ninja -S . -B ./cmake-build-debug

编译代码:

bash
cmake --build ./cmake-build-debug --target vcpkg_learn -j $(nproc)

执行:

bash
./vcpkg_learn

执行结果:

bash
Private Key (hex): 0x3041020100301306072A8648CE3D020106082A8648CE3D030107042730250201010420B3548E997C3FF239C8348CFED8CD49F9845C12DBB87ADBCD886F6C9653EECCEA
Public Key (hex): 0x3059301306072A8648CE3D020106082A8648CE3D03010703420004D948F253F02CD9EEF933842DF824989EC82EBAD3FAB1EB783660A00704E80EF5CBDAF1E959FAFA800724263E4B0D6F975B646C01B4DDAFAB01AA7F3A9280300A

使用vcpkg清单 - vcpkg.json

类似于NodeJS的package.json、python的requirements.txt、maven的pom.xml、golang的go.mod等,vcpkg也提供了一个文件vcpkg.json用于声明项目依赖。

目前vcpkg似乎还不支持初始化一个空的vcpkg.json或者根据当前项目自动生成vcpkg.json。

文档:https://learn.microsoft.com/en-us/vcpkg/reference/vcpkg-json

在项目根目录下创建vcpkg.json

json
{
  "name": "vcpkgexample",
  "version-string": "0.0.1",
  "description": "vcpkg example",
  "dependencies": [
  	{
      "name": "vcpkg-cmake",
      "host": true
    },
    {
      "name": "vcpkg-cmake-config",
      "host": true
    },
    "cryptopp"
  ]
}

这样一来,在cmake加载项目的时候,就会自动下载依赖,并编译为我们所用。

到目前为止,项目可在GitHub中下载:Fu-XDU/vcpkg-example at 332a29

CMake FetchContent使用

如果有一个库使用vcpkg搜不到,要怎么依赖呢?可以使用CMake FetchContent去自动下载依赖。

CMake FetchContent不再是vcpkg的内容,移步文章:CMake FetchContent使用 - 小木槌