【问题标题】:Configure and Install required packages for a project为项目配置和安装所需的包
【发布时间】:2020-06-28 13:46:52
【问题描述】:

来自其他包管理器,我希望能够在项目中执行以下操作:

  • 配置所需的库(在配置文件中,例如 CMakelists.txt 或 nuget 的 packages.config

  • 安装/升级所有必需的库

vcpkg 和 CMake 似乎无法做到这一点:

我设法设置了 vcpkg 和 CMakefile (linux):

# in ternimal
vcpkg install <package>
# CMakeLists.txt
find_package(nlohmann_json CONFIG REQUIRED)

target_link_libraries(<app> <package>)

然而,这需要手动安装所有必需的库 (vcpkg install &lt;package&gt;)。

我如何列出所需的包并让 vcpkg 或 CMake 根据需要管理它们(例如,如果它们丢失,则自动安装它们)?

【问题讨论】:

    标签: c++ cmake vcpkg


    【解决方案1】:

    我在我的项目中使用 ExternalProject_Add 做了类似的事情。

    代码将类似于以下模式(我已将我的依赖项替换为您的)

      find_package(nlohmann_json CONFIG) # make package not REQUIRED to avoid error...
    
      if(NOT NLOHMANN_JSON_FOUND)  # or whatever variable indicating _FOUND
        ...
        # here ExternalProject_Add from https://github.com/nlohmann/json.git
        # using specific tag...
        ...
        ExternalProject_Get_Property(... INSTALL_DIR)
    
        # create imported target here similar to nlohmann_json, as if we found it
        ...
    
      else()
        # We've found lib already installed... will use it...
        ...
    
      endif()
    

    另一个选项可以使用FetchContent,但我还没有尝试过。

    【讨论】:

      【解决方案2】:

      我最近花了一些时间使用 CMake 和 vcpkg。我不喜欢将 vcpkg 及其安装包与我的 CMake 项目分开管理的典型方法,因此我编写了一些 CMake 脚本来在 CMake 构建过程中处理 vcpkg。

      安装 vcpkg 的 CMake 脚本主要是调用 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 及其维护的包的安装。

      请注意,这是一个点解决方案。我在 my Github 中有一个更通用的模板,涵盖 Windows 和 Linux,并允许使用单独维护的 vcpkg 实例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-14
        • 1970-01-01
        • 2013-04-05
        • 2018-05-25
        • 2012-01-10
        • 2015-08-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多