使用 CMakeExternalProject_Add 构建 mongo-cxx-driver

2023-12-06

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

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作为其中之一给出CMAKE_ARGS for mongo-cxx-driver。我对此表示怀疑,我相信这可能是罪魁祸首。有了它我得到以下错误:

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 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 最终在中寻找 libbson-1.0${OTS_DEPDENDENCIES_DIR}/include那不存在。如果只是,我可以告诉 cmake,“嘿,不要运行这个find_package“我可以给你一条路INCLUDE_DIR, LIBRARIES and DEFINITIONS myself.

如果我删除此选项,则会收到以下错误:

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 但无法弄清楚它的安装位置。


初步评论

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

  • 使用不同的目录SOURCE_DIR and 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用于多配置发电机

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

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()

在这篇文章中,您可以了解如何构建您的项目:cmake项目中使用第三方库的正确方法

允许编译 mongocxx“test.cpp”的工作项目

下面是内容CMakeLists.txt and test.cpp允许构建一个名为<build-dir>/Test-build/test_mongocxx :

  • 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;
        }
    }
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 CMakeExternalProject_Add 构建 mongo-cxx-driver 的相关文章

随机推荐