Uploaded image for project: 'C++ Driver'
  1. C++ Driver
  2. CXX-2116

Document rpath for non-standard install location

    • Type: Icon: Improvement Improvement
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 3.7.0, 3.7.0-beta1
    • Affects Version/s: None
    • Component/s: Documentation
    • Labels:
      None

      I have been tinkering around with building a "superbuild" CMake project that downloads and builds the mongo-cxx driver for inclusion into a project.

      To do this, I used the ExternalProject_Add and then manually linked the libmongocxx.so shared object to the final executable/library.

      Here's what the CMakeLists.txt roughly looks like:

      # Find mongoc, bson, and mongocxx library for use as MongoDB connector/driver.
      ExternalProject_Add(libmongoc
        GIT_REPOSITORY https://github.com/mongodb/mongo-c-driver.git
        GIT_TAG 1.17.0
        GIT_PROGRESS 1
        GIT_SHALLOW 1
        UPDATE_COMMAND "" # Prevents a rebuild on every make.
        SOURCE_DIR "${CMAKE_BINARY_DIR}/libmongoc"
        BINARY_DIR "${CMAKE_BINARY_DIR}/libmongoc-build"
        INSTALL_DIR "${CMAKE_BINARY_DIR}/libmongoc-install"
        CMAKE_CACHE_ARGS
        -DCMAKE_BUILD_TYPE:STRING=Release
        -DCMAKE_INSTALL_PREFIX:PATH="${CMAKE_BINARY_DIR}/libmongoc-install;${CMAKE_BINARY_DIR}/libmongocxx-install"
        -DENABLE_TESTS:BOOL=OFF
        -DENABLE_STATIC:BOOL=OFF
        -DENABLE_EXAMPLES:BOOL=OFF
        -DENABLE_EXTRA_ALIGNMENT:BOOL=OFF)ExternalProject_Add(libmongocxx
        GIT_REPOSITORY  "https://github.com/mongodb/mongo-cxx-driver.git"
        GIT_TAG r3.6.0
        GIT_PROGRESS 1
        GIT_SHALLOW 1
        UPDATE_COMMAND "" # Prevents a rebuild on every make.
        SOURCE_DIR "${CMAKE_BINARY_DIR}/libmongocxx"
        BINARY_DIR "${CMAKE_BINARY_DIR}/libmongocxx-build"
        INSTALL_DIR "${CMAKE_BINARY_DIR}/libmongocxx-install"
        CMAKE_CACHE_ARGS
        -DCMAKE_BUILD_TYPE:STRING=Release
        -DCMAKE_PREFIX_PATH:PATH=${CMAKE_BINARY_DIR}/libmongoc-install
        -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/libmongocxx-install
        -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
        DEPENDS libmongoc)
      
      # START NOTE
      set(_LIBMONGOCXX_LIBRARIES
        "${CMAKE_BINARY_DIR}/libmongocxx-install/lib/libmongocxx.so")
      # END NOTE
      
      set(_LIBMONGOCXX_INCLUDE_DIRS
        "${CMAKE_BINARY_DIR}/libmongocxx-install/include/bsoncxx/v_noabi/"
        "${CMAKE_BINARY_DIR}/libmongocxx-install/include/mongocxx/v_noabi/")
      message(STATUS "Using mongocxx r3.6.0")
      
      add_executable(hello_world "src/hello_world.cc")
      target_link_libraries(hello_world
        ${_LIBMONGOCXX_LIBRARIES})
      target_include_directories(hello_world
        PUBLIC
        "${_LIBMONGOCXX_INCLUDE_DIRS}")

       

      This configuration builds the hello_world application correctly, but when I go to execute the application, the following error occurs:

      error while loading shared libraries: libbsoncxx.so._noabi: cannot open shared object file: No such file or directory

       When running ldd on the installed libmongocxx.so, it turns out, libbsoncxx.so._noabi is not found.

       

      linux-vdso.so.1 (0x00007ffdd7524000) 
      libmongoc-1.0.so.0 => /home/jpai/Documents/HelloWorld/cmake/build/libmongoc-install/lib/libmongoc-1.0.so.0 (0x00007fc9e3d39000) 
      libbsoncxx.so._noabi => not found 
      libbson-1.0.so.0 => /home/jpai/Documents/HelloWorld/cmake/build/libmongoc-install/lib/libbson-1.0.so.0 (0x00007fc9e3afb000) 
      libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fc9e3772000) 
      libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc9e355a000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc9e3169000) libssl.so.1.1 => /usr/lib/x86_64-linux-gnu/libssl.so.1.1 (0x00007fc9e2edc000) 
      libcrypto.so.1.1 => /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 (0x00007fc9e2a11000) 
      librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fc9e2809000) libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007fc9e25ee000) 
      libz.so.1 => /usr/local/lib/libz.so.1 (0x00007fc9e23d1000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc9e21b2000) 
      libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc9e1e14000) /lib64/ld-linux-x86-64.so.2 (0x00007fc9e428f000) 
      libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc9e1c10000)

       

      One way to work around it is to set the LD_LIBRARY_PATH to the same directory as libmongocxx.so (and libbsoncxx.so). But this isn't really a good solution since, this would mean the application must have specific environment settings just to get the application to point to the local/non-standard shared object location.

      I have instead managed to work around this particular problem by linking the build output directory's version of libmongocxx.so. This version of libmongocxx.so links to the build directory's version of libbsoncxx.so.

      So instead of using the NOTE section from above, I use the following variable setting:

       

      set(_LIBMONGOCXX_LIBRARIES
        "${CMAKE_BINARY_DIR}/libmongocxx-build/src/mongocxx/libmongocxx.so")
      

       

      With this, the application works without the missing shared object error.

      I wanted to ask why there was such a difference between the linking of the installed directory version of libmongocxx.so and the build directory version of libmongocxx.so.

      Considering the install operation of the project seems to drop all the necessary shared objects into the same directory, I am not sure why the installed version of libmongocxx.so was not able to pick up libbsoncxx.so object next to it.

      I wanted to see if there is a way to fix this so that the mongo-cxx-driver can be a bit more portable and not need to be directly installed into the system libraries. I don't think it is good practice to directly reference the build object when the project has an install target available for it.

      Thanks!

            Assignee:
            roberto.sanchez@mongodb.com Roberto Sanchez
            Reporter:
            jesse.pai@gmail.com Jesse Pai
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: