Недавно я потратил некоторое время на работу с CMake и vcpkg. Мне не нравится типичный подход к управлению vcpkg и его установленными пакетами отдельно от моих проектов CMake, поэтому я написал несколько сценариев CMake для обработки vcpkg в процессе сборки CMake.
Сценарий CMake для установки vcpkg в первую очередь является обращением к ExternalProject_Add.
# ./vcpkg_utilities.cmake (part 1)
include(ExternalProject)
function(get_vcpkg)
ExternalProject_Add(vcpkg
GIT_REPOSITORY https://github.com/microsoft/vcpkg.git
CONFIGURE_COMMAND ""
INSTALL_COMMAND ""
UPDATE_COMMAND ""
BUILD_COMMAND "<SOURCE_DIR>/bootstrap-vcpkg.sh"
)
ExternalProject_Get_Property(vcpkg SOURCE_DIR)
set(VCPKG_DIR ${SOURCE_DIR} PARENT_SCOPE)
set(VCPKG_DEPENDENCIES "vcpkg" PARENT_SCOPE)
endfunction()
Сценарий для установки пакета vcpkg требует настраиваемой команды и цели.
# ./vcpkg_utilities.cmake (part 2)
function(vcpkg_install PACKAGE_NAME)
add_custom_command(
OUTPUT ${VCPKG_DIR}/packages/${PACKAGE_NAME}_x64-linux/BUILD_INFO
COMMAND ${VCPKG_DIR}/vcpkg install ${PACKAGE_NAME}:x64-linux
WORKING_DIRECTORY ${VCPKG_DIR}
DEPENDS vcpkg
)
add_custom_target(get${PACKAGE_NAME}
ALL
DEPENDS ${VCPKG_DIR}/packages/${PACKAGE_NAME}_x64-linux/BUILD_INFO
)
list(APPEND VCPKG_DEPENDENCIES "get${PACKAGE_NAME}")
set(VCPKG_DEPENDENCIES ${VCPKG_DEPENDENCIES} PARENT_SCOPE)
endfunction()
Для правильной привязки основного проекта к vcpkg (через файл цепочки инструментов) требуется vcpkg чтобы быть доступным при настройке основного проекта, поэтому основной проект настроен как ExternalProject.
# /CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
project(top LANGUAGES CXX)
include(vcpkg_utilities)
get_vcpkg()
vcpkg_install(nlohmann_json)
include(ExternalProject)
set_property(DIRECTORY PROPERTY EP_BASE main_projectname)
ExternalProject_Add(main_projectname
DEPENDS ${VCPKG_DEPENDENCIES}
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/src
INSTALL_COMMAND ""
CMAKE_ARGS --no-warn-unused-cli;
-DCMAKE_TOOLCHAIN_FILE=${VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake
)
Используя эту структуру, CMake будет управлять установкой как vcpkg, так и пакетов, поддерживаемых им.
Обратите внимание, что это точечное решение. У меня есть более общий шаблон для этого в моем Github , который охватывает Windows и Linux и позволяет использовать отдельно поддерживаемый экземпляр vcpkg.