5

I installed the mongocxx driver, as shown by http://mongodb.github.io/mongo-cxx-driver/mongocxx-v3/installation/ and when I test driver everything looks fine, but if change a little code I get error while loading shared libraries: libbsoncxx.so._noabi: cannot open shared object file: No such file or directory.

Code:

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)

if(POLICY CMP0025)
    cmake_policy(SET CMP0025 NEW)
endif()

project(test_mongodb LANGUAGES C CXX)

if(NOT DEFINED CMAKE_CXX_STANDARD)
    set(CMAKE_CXX_STANDARD 11)
endif()

set(CMAKE_PREFIX_PATH CMAKE_PREFIX_PATH "~/opt/mongo-cxx-driver/install")
set(CMAKE_CXX_EXTENSIONS OFF)

if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
endif()


add_executable(test_mongodb main.cpp)

find_package(libmongocxx REQUIRED)

target_include_directories(test_mongodb
        PRIVATE ${LIBMONGOCXX_INCLUDE_DIRS}
        )

target_link_libraries(test_mongodb
        PRIVATE ${LIBMONGOCXX_LIBRARIES}
        )

target_compile_definitions(test_mongodb
        PRIVATE ${LIBMONGOCXX_DEFINITIONS}
        )

add_custom_target(run
        COMMAND test_mongodb
        DEPENDS test_mongodb
        WORKING_DIRECTORY ${CMAKE_PROJECT_DIR}
        )

list(FIND LIBMONGOCXX_DEFINITIONS "BSONCXX_STATIC" LIST_IDX)
if (${LIST_IDX} GREATER -1)
    message(FATAL_ERROR "Expected BSONCXX_STATIC to not be defined")
endif()
list(FIND LIBMONGOCXX_DEFINITIONS "MONGOCXX_STATIC" LIST_IDX)
if (${LIST_IDX} GREATER -1)
    message(FATAL_ERROR "Expected MONGOCXX_STATIC to not be defined")
endif()

main.cpp

#include <iostream>

#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>

#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/cursor.hpp>


int main(int argc, char* argv[]) {
    using bsoncxx::builder::basic::kvp;
    using bsoncxx::builder::basic::make_document;

    mongocxx::instance inst;

    try {
        const auto uri = mongocxx::uri{(argc >= 2) ? argv[1] : mongocxx::uri::k_default_uri};

        auto client = mongocxx::client{uri};
        auto admin = client["admin"];
        auto result = admin.run_command(make_document(kvp("isMaster", 1)));
        std::cout << bsoncxx::to_json(result) << std::endl;

        return EXIT_SUCCESS;
    } catch (const std::exception& xcp) {
        std::cout << "connection failed: " << xcp.what() << std::endl;
        return EXIT_FAILURE;
    }
}

If I remove auto result = admin.run_command(make_document(kvp("isMaster", 1))); from code i get error while loading shared libraries: libbsoncxx.so._noabi, if not works fine. Any idea why it behaves like that ?

Ubuntu 18.04 cc 7.3.0, c++ 7.3.0, CMake 3.11.3

Adam
  • 61
  • 1
  • 3
  • Not sure what the drive-by downvote was for, this seems like a fine question. Please see my answer below. – acm Jul 02 '18 at 17:57
  • I added some more thoughts below. I think you have runpath issues. – acm Jul 04 '18 at 15:29

3 Answers3

0

You are entering the CMake find subsystem at too low a level: the Mongo C++ driver provides integration with the CMake find_package subsystem which does much of this work for you. You should simply be able to say find_package(libmongocxx REQUIRED) and then use the pre-populated variables LIBMONGOCXX_{INCLUDE_DIRS,LIBRARIES,DEFINITIONS}.

Please see the top level examples/projects directory in the source code for many example projects that show how to integrate with {mongo,bson}cxx via both CMake's find_package and pkgconfig.

I think, given the usage that you are aiming for above, you should start with the directory examples/projects/mongocxx/cmake/shared.

acm
  • 12,183
  • 5
  • 39
  • 68
  • When I integrate, as the example projects show, there is still the same problem.I don't know why it works fine when I use in my code `collection.find({});` without it I get: **error while loading shared libraries: libbsoncxx.so._noabi**. – Adam Jul 02 '18 at 18:33
  • Can you update the code above with what you are currently doing? – acm Jul 02 '18 at 20:53
  • Well, I can see quite clearly that you haven't added `BSONCXX_LIBRARIES` to the `target_link_libraries` of `mongo_test`. Did you try that? You can also drop all the stuff about `MONGOCXX_STATIC`, which is just test code to help validate the example. – acm Jul 03 '18 at 13:17
  • I have not added `BSONCXX_LIBRARIES` to `target_link_libraries`, because the example shows that it is not needed, but I also tested with it. – Adam Jul 03 '18 at 13:55
  • I have built a static mongocxx driver and it works well, but it is not the solution that I would like. – Adam Jul 03 '18 at 15:28
  • It seems to me that the situation with your shared libraries is oddly backwards: when you *do* reference bsoncxx symbols in your code it works, but when you *don't* reference them, it doesn't. I wonder if when you don't reference `bsoncxx` your app doesn't get a `DT_NEEDED` entry, and you are relying on `mongocxx` finding it, but when you reference it, you do. Somehow, your application has the right runpath, but libmongocxx does not. I recommend going back to shared, and using `readelf` to explore the rpath settings and DT_NEEDED entries for all the participants: your app, the libs, etc. – acm Jul 04 '18 at 15:26
0

When I used the readelf, I received:

File: libmongocxx.so

(NEEDED) Shared library: [libbsoncxx.so._noabi]
(NEEDED) Shared library: [libmongoc-1.0.so.0]
(NEEDED) Shared library: [libbson-1.0.so.0]
(NEEDED) Shared library: [libstdc++.so.6]
(NEEDED) Shared library: [libgcc_s.so.1]
(NEEDED) Shared library: [libc.so.6]
(SONAME) Library soname: [libmongocxx.so._noabi]
(RUNPATH) Library runpath: [/home/adam/opt/mongo-c-driver/install/lib]

File: test_mongodb ( with error )
(NEEDED) Shared library: [libmongocxx.so._noabi]
(NEEDED) Shared library: [libstdc++.so.6]
(NEEDED) Shared library: [libc.so.6]
(RUNPATH) Library runpath: [/home/adam/opt/mongo-cxx-driver/install/lib]

File: test_mongodb ( without error )
(NEEDED) Shared library: [libmongocxx.so._noabi]
(NEEDED) Shared library: [libbsoncxx.so._noabi]
(NEEDED) Shared library: [libstdc++.so.6]
(NEEDED) Shared library: [libgcc_s.so.1]
(NEEDED) Shared library: [libc.so.6]
(RUNPATH) Library runpath: [/home/adam/opt/mongo-cxx-driver/install/lib]
Adam
  • 61
  • 1
  • 3
  • And, that explains everything. In the without error case, your binary has `NEEDED` entries for both libraries, and an `RPATH` into the `mongocxx/install` directory, so both libraries are found at runtime. In the case with an error, you only depend on `mongocxx`. However, the `mongocxx` library doesn't have its own installation directory in `RPATH`, so it can't find `bsoncxx`, which it needs. You should investigate why the C++ driver libraries are being built without their own installation directory set in their `RPATH`. – acm Jul 06 '18 at 12:37
0

https://www.cnblogs.com/pluse/p/5491300.html reson for erros is about the library link.Just relink the library like below will reslove the problem


    sudo ln -s /usr/local/lib/libmogocxx.so.3.4.0 libmongocxx.so._noabi
    sudo ln -s /usr/local/lib/libmongocxx.so._noabi /usr/local/lib/libmongocxx.so