使用CMake ExternalProject_Add构建mongo-cxx-driver [英] Building mongo-cxx-driver using CMake ExternalProject_Add

查看:231
本文介绍了使用CMake ExternalProject_Add构建mongo-cxx-driver的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在基于CMake的项目中构建 mongo-cxx-driver .该项目应该在Windows,macOS和ubuntu容器中构建,并且我想确保我在所有这些平台上的软件都将使用相同的驱动程序版本,因此我无法负担通过 apt-get安装驱动程序及其依赖项 brew 等.所以我剩下一个选择: ExternalProject_Add .但是鉴于如何设置 libmongoc ,我很难做到这一点.以下是我目前拥有的CMake模块.

I am trying to build mongo-cxx-driver in a CMake based project. This project is supposed to build on Windows, macOS and in an ubuntu container and I want to ensure that my software on all these platforms will use the same driver version so I cannot afford installing the driver and its dependencies via apt-get, brew etc. So I am left with one option: ExternalProject_Add. But I am having difficulty making that work given how libmongoc is setup. Below is the CMake module I currently have.

include(ExternalProject)

set(libmongoc_CMAKE_ARGS
    "-DCMAKE_BUILD_TYPE:STRIING=${CMAKE_BUILD_TYPE}"
    "-DENABLE_TESTS:BOOL=OFF"
    "-DENABLE_STATIC:BOOL=OFF"
    "-DENABLE_EXAMPLES:BOOL=OFF"
    "-DENABLE_EXTRA_ALIGNMENT:BOOL=OFF"
)

set(mongocxx_CMAKE_ARGS
    "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
    "-DCMAKE_BUILD_TYPE:STRIING=${CMAKE_BUILD_TYPE}"
    "-DBUILD_SHARED_LIBS:BOOL=ON"
    "-DENABLE_TESTS:BOOL=OFF"
    "-DENABLE_EXAMPLES:BOOL=OFF"
    "-DBSONCXX_POLY_USE_BOOST:BOOL=ON"
    "-DBSONCXX_POLY_USE_MNMLSTC:BOOL=OFF"
    "-Dlibbson-1.0_DIR:PATH=${OTS_DEPDENDENCIES_DIR}/libmongoc/src/libbson"
)

if (NOT TARGET libmongoc)
    ExternalProject_Add(
        libmongoc
        GIT_REPOSITORY  "https://github.com/mongodb/mongo-c-driver.git"
        GIT_TAG         "1.12.0"
        SOURCE_DIR      "${OTS_DEPDENDENCIES_DIR}/libmongoc"
        BINARY_DIR      "${OTS_DEPDENDENCIES_DIR}/libmongoc"
        CMAKE_ARGS      "${libmongoc_CMAKE_ARGS}"
        INSTALL_COMMAND ""
    )
endif()

if (NOT TARGET mongocxx)
    ExternalProject_Add(
        mongocxx
        GIT_REPOSITORY  "https://github.com/mongodb/mongo-cxx-driver.git"
        GIT_TAG         "r3.3.1"
        SOURCE_DIR      "${OTS_DEPDENDENCIES_DIR}/mongocxx"
        BINARY_DIR      "${OTS_DEPDENDENCIES_DIR}/mongocxx"
        CMAKE_ARGS      "${mongocxx_CMAKE_ARGS}"
        INSTALL_COMMAND ""
        DEPENDS         libmongoc
    )
endif()

请注意CMAKE选项 libbson-1.0_DIR 作为 mongo-cxx-driver CMAKE_ARGS 之一.我对此表示怀疑,我相信可能是罪魁祸首.有了它,我得到以下错误:

Note the CMAKE option libbson-1.0_DIR given as one of the CMAKE_ARGS for mongo-cxx-driver. I am skeptic about it and I believe that may be the culprit. With it I get the following error:

CMake Error at ${OTS_DEPENDENCIES_DIR}/libmongoc/src/libbson/libbson-1.0-config.cmake:30 (message):
    File or directory
    ${OTS_DEPENDENCIES_DIR}/include/libbson-1.0
    referenced by variable BSON_INCLUDE_DIRS does not exist !
Call Stack (most recent call first):
    ${OTS_DEPENDENCIES_DIR}/libmongoc/src/libbson/libbson-1.0-config.cmake:46 (set_and_check)
    src/bsoncxx/CMakeLists.txt:81 (find_package)

哪种方式有意义,因为 src/bsoncxx/CMakeLists.txt:81 读取:

which kind of makes sense because src/bsoncxx/CMakeLists.txt:81 reads:

get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
set_and_check (BSON_INCLUDE_DIRS "${PACKAGE_PREFIX_DIR}/include/libbson-1.0")

这使得CMake最终在不存在的 $ {OTS_DEPDENDENCIES_DIR}/include 中寻找libbson-1.0.如果可以的话,我可以告诉cmake,嘿,不要运行此 find_package ".我可以为您提供 INCLUDE_DIR LIBRARIES DEFINITIONS 我自己.

which makes CMake end up looking for libbson-1.0 in ${OTS_DEPDENDENCIES_DIR}/include that does not exist. If only, I could tell cmake, "hey don't run this find_package" I can give you the path to INCLUDE_DIR, LIBRARIES and DEFINITIONS myself.

如果删除此选项,则会出现以下错误:

If I remove this option, I get the following error:

CMake Error at src/bsoncxx/CMakeLists.txt:81 (find_package):
By not providing "Findlibbson-1.0.cmake" in CMAKE_MODULE_PATH this project
has asked CMake to find a package configuration file provided by
"libbson-1.0", but CMake did not find one.

Could not find a package configuration file provided by "libbson-1.0"
(requested version 1.10.0) with any of the following names:

libbson-1.0Config.cmake
libbson-1.0-config.cmake

Add the installation prefix of "libbson-1.0" to CMAKE_PREFIX_PATH or set
"libbson-1.0_DIR" to a directory containing one of the above files.  If
"libbson-1.0" provides a separate development package or SDK, be sure it
has been installed.

这也不是很奇怪,因为CMake试图找到find_package libbson-1.0,但无法确定它的安装位置.

which is not very odd either because CMake tries to find_package libbson-1.0 but cannot figure out where it is installed.

推荐答案

初步说明

在查看详细信息时,以下是一些初步评论:

preliminary remarks

While looking at the details, here are few preliminary comments:

  • SOURCE_DIR BINARY_DIR
  • 使用不同的目录
  • 代替 CMAKE_ARG ,而是选择 CMAKE_CACHE_ARGS
  • libbson-1.0_DIR 不应设置为源目录,而应设置为包含 config-file 包的构建目录(下面的链接可提供更多信息)有关此概念的详细信息)
  • 确保始终指定CMake参数的类型( -DCMAKE_CXX_COMPILER:PATH = $ {CMAKE_CXX_COMPILER} 而不是 -DCMAKE_CXX_COMPILER = $ {CMAKE_CXX_COMPILER} )
  • >
  • 请勿为多配置生成器设置 CMAKE_BUILD_TYPE
  • Use different directory for SOURCE_DIR and BINARY_DIR
  • Instead of CMAKE_ARG, prefer CMAKE_CACHE_ARGS
  • libbson-1.0_DIR should NOT be set to a source directory, instead if should be set to a build directory containing a config-file package (link below provide more details about this concept)
  • Make sure to always specify the type of CMake argument (-DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER} instead of -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER})
  • Do not set CMAKE_BUILD_TYPE for multi-configuration generator

关于最后一点,这意味着您应该执行以下操作:

Regarding this last point, this means that you should do the following:

set(EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS)
if(NOT DEFINED CMAKE_CONFIGURATION_TYPES)
  list(APPEND EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS
    -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
    )
endif()

在这篇文章中,您可以学习如何构建项目:

In this post, you can learn how you could structure your project: Correct way to use third-party libraries in cmake project

下面是 CMakeLists.txt test.cpp 的内容,允许构建名为< build-dir>/Test-build/test_mongocxx的可执行文件:

Below is the content of CMakeLists.txt and test.cpp allowing to build an executable named <build-dir>/Test-build/test_mongocxx :

  • CMakeLists.txt:

  • CMakeLists.txt:

cmake_minimum_required(VERSION 3.12)

set(CMAKE_CXX_STANDARD 11) 

project(Test)

option(${PROJECT_NAME}_SUPERBUILD "Build ${PROJECT_NAME} and the projects it depends on." ON)

if(${PROJECT_NAME}_SUPERBUILD)

    include(ExternalProject)

    set(common_cmake_cache_args
        -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER}
    )
    if(NOT DEFINED CMAKE_CONFIGURATION_TYPES)
        list(APPEND common_cmake_cache_args
            -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
        )
    endif()

    ExternalProject_Add(libmongoc
        GIT_REPOSITORY  "https://github.com/mongodb/mongo-c-driver.git"
        GIT_TAG         "1.12.0"
        GIT_PROGRESS    1
        GIT_SHALLOW     1
        SOURCE_DIR      "${CMAKE_BINARY_DIR}/libmongoc"
        BINARY_DIR      "${CMAKE_BINARY_DIR}/libmongoc-build"
        INSTALL_DIR     "${CMAKE_BINARY_DIR}/libmongoc-install"
        CMAKE_CACHE_ARGS
            ${common_cmake_cache_args}
            -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/libmongoc-install
            -DENABLE_TESTS:BOOL=OFF
            -DENABLE_STATIC:BOOL=OFF
            -DENABLE_EXAMPLES:BOOL=OFF
            -DENABLE_EXTRA_ALIGNMENT:BOOL=OFF
        #INSTALL_COMMAND ""
    )
    set(libmongoc-1.0_DIR "${CMAKE_BINARY_DIR}/libmongoc-install/lib/cmake/libmongoc-1.0/")
    set(libbson-1.0_DIR "${CMAKE_BINARY_DIR}/libmongoc-install/lib/cmake/libbson-1.0/")

    ExternalProject_Add(libmongocxx
        GIT_REPOSITORY  "https://github.com/mongodb/mongo-cxx-driver.git"
        GIT_TAG         "r3.3.1"
        GIT_PROGRESS    1
        GIT_SHALLOW     1
        SOURCE_DIR      "${CMAKE_BINARY_DIR}/libmongocxx"
        BINARY_DIR      "${CMAKE_BINARY_DIR}/libmongocxx-build"
        INSTALL_DIR     "${CMAKE_BINARY_DIR}/libmongocxx-install"
        CMAKE_CACHE_ARGS
            ${common_cmake_cache_args}
            -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/libmongocxx-install
            -DBUILD_SHARED_LIBS:BOOL=ON
            -DENABLE_TESTS:BOOL=OFF
            -DENABLE_EXAMPLES:BOOL=OFF
            -DBSONCXX_POLY_USE_BOOST:BOOL=OFF
            -DBSONCXX_POLY_USE_MNMLSTC:BOOL=ON
            -DBSONCXX_POLY_USE_STD:BOOL=OFF
            -Dlibmongoc-1.0_DIR:PATH=${libmongoc-1.0_DIR}
            -Dlibbson-1.0_DIR:PATH=${libbson-1.0_DIR}
        DEPENDS
            libmongoc
    )
    set(libmongocxx_DIR "${CMAKE_BINARY_DIR}/libmongocxx-install/lib/cmake/libmongocxx-3.3.1/")
    set(libbsoncxx_DIR "${CMAKE_BINARY_DIR}/libmongocxx-install//lib/cmake/libbsoncxx-3.3.1/")


    function(ExternalProject_AlwaysConfigure proj)
      # This custom external project step forces the configure and later
      # steps to run.
      _ep_get_step_stampfile(${proj} "configure" stampfile)
      ExternalProject_Add_Step(${proj} forceconfigure
        COMMAND ${CMAKE_COMMAND} -E remove ${stampfile}
        COMMENT "Forcing configure step for '${proj}'"
        DEPENDEES build
        ALWAYS 1
        )
    endfunction()

    ExternalProject_Add(${PROJECT_NAME}
        SOURCE_DIR "${CMAKE_SOURCE_DIR}"
        BINARY_DIR "${CMAKE_BINARY_DIR}/${PROJECT_NAME}-build"
        DOWNLOAD_COMMAND ""
        UPDATE_COMMAND ""
        CMAKE_CACHE_ARGS
            ${common_cmake_cache_args}
            -D${PROJECT_NAME}_SUPERBUILD:BOOL=OFF
            -Dlibbsoncxx_DIR:PATH=${libbsoncxx_DIR}
            -Dlibmongocxx_DIR:PATH=${libmongocxx_DIR}
        INSTALL_COMMAND ""
        DEPENDS
            libmongocxx
    )
    ExternalProject_AlwaysConfigure(${PROJECT_NAME})
    return()
endif()

message(STATUS "Configuring inner-build")

find_package(libmongocxx REQUIRED)

add_executable(test_mongocxx test.cpp)
target_link_libraries(test_mongocxx PUBLIC ${LIBMONGOCXX_LIBRARIES})
target_include_directories(test_mongocxx PUBLIC ${LIBMONGOCXX_INCLUDE_DIRS})
target_compile_definitions(test_mongocxx PUBLIC ${LIBMONGOCXX_DEFINITIONS})

  • test.cpp(复制自 https://mongodb.github.io/mongo-cxx-driver/mongocxx-v3/installation/#step-6-test-your-installation ):

    #include <iostream>
    
    #include <bsoncxx/builder/stream/document.hpp>
    #include <bsoncxx/json.hpp>
    
    #include <mongocxx/client.hpp>
    #include <mongocxx/instance.hpp>
    
    int main(int, char**) {
        mongocxx::instance inst{};
        mongocxx::client conn{mongocxx::uri{}};
    
        bsoncxx::builder::stream::document document{};
    
        auto collection = conn["testdb"]["testcollection"];
        document << "hello" << "world";
    
        collection.insert_one(document.view());
        auto cursor = collection.find({});
    
        for (auto&& doc : cursor) {
            std::cout << bsoncxx::to_json(doc) << std::endl;
        }
    }
    

  • 这篇关于使用CMake ExternalProject_Add构建mongo-cxx-driver的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆