配置和安装项目所需的软件包

时间:2020-06-19 18:27:05

标签: c++ cmake vcpkg

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

  • 配置所需的库(在配置文件中,例如class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val navController = findNavController(R.id.nav_host_fragment) val pendingIntent = navController.createDeepLink() .setGraph(R.navigation.main_graph) .setDestination(R.id.fragment_blue) .setArguments(bundleOf("foo" to 1, "bar" to 2, "zar" to 3)) .createPendingIntent() createNotificationChannel() // outside of the scope of this answer val builder = NotificationCompat.Builder(this, "my_channel") .setContentTitle("title") .setContentText("content text") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setContentIntent(pendingIntent) .setSmallIcon(R.drawable.android) .setAutoCancel(true) .setChannelId("channelId") with(NotificationManagerCompat.from(this)) { notify(100, builder.build()) } } } 或nuget的CMakelists.txt

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

对于vcpkg和CMake,这似乎是不可能的:

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

packages.config
# in ternimal
vcpkg install <package>

但是,这需要手动安装所有必需的库(# CMakeLists.txt find_package(nlohmann_json CONFIG REQUIRED) target_link_libraries(<app> <package>) )。

如何列出所需的软件包,并按要求对vcpkg或CMake进行管理(例如,如果缺少它们,则自动安装)?

2 个答案:

答案 0 :(得分:0)

我在项目中使用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,但我还没有尝试过。

答案 1 :(得分:0)

我最近花了一些时间来处理CMake和vcpkg。我不喜欢与CMake项目分开管理vcpkg及其安装的软件包的典型方法,因此我写了一些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实例。