[CXX-2116] Document rpath for non-standard install location Created: 04/Oct/20  Updated: 28/Oct/23  Resolved: 04/Nov/20

Status: Closed
Project: C++ Driver
Component/s: Documentation
Affects Version/s: None
Fix Version/s: 3.7.0, 3.7.0-beta1

Type: Improvement Priority: Major - P3
Reporter: Jesse Pai Assignee: Roberto Sanchez
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

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!



 Comments   
Comment by Githook User [ 04/Nov/20 ]

Author:

{'name': 'Roberto C. Sánchez', 'email': 'roberto@connexer.com', 'username': 'rcsanchez97'}

Message: CXX-2116 document rpath for non-standard install location
Branch: master
https://github.com/mongodb/mongo-cxx-driver/commit/ee47ee488e478217b8d966134b4ba7dbe6ea33dc

Comment by Jesse Pai [ 03/Nov/20 ]

Ah yes. I forgot about that CMAKE variable. That is certainly an option and is probably a better idea.

I will try it out and see if it works for my use case. Thanks for taking a look into this!

Comment by Roberto Sanchez [ 03/Nov/20 ]

jesse.pai@gmail.com, I have investigated this. The issue is that the build sets rpath for artifacts in the build directory and then clears rpath when they are copied to the install location. If you specify -DCMAKE_INSTALL_RPATH=<prefix>/lib (where <prefix> is the same directory you specified as your installation prefix), then the target directory where the libraries are to be installed will be used as the rpath. That should eliminate the loader error you are seeing. We are updating the installation docs to include this information.

Comment by Kevin Albertson [ 05/Oct/20 ]

Hi jesse.pai@gmail.com, thank you for the detailed report! We will look into this soon.

Generated at Wed Feb 07 22:04:56 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.