Skip to content

Commit 4b99864

Browse files
committed
add instructions for fixes to locate shared libraries
1 parent e1466c3 commit 4b99864

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

docs/content/mongocxx-v3/installation/advanced.md

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,160 @@ cmake .. \
163163
-DLIBBSON_DIR=$HOME/mongo-c-driver \
164164
-DCMAKE_INSTALL_PREFIX=$HOME/mongo-cxx-driver
165165
```
166+
167+
### Fixing the "Library not loaded" error on macOS
168+
169+
Applications linking to a non-standard directory installation may encounter an error loading the C++ driver at runtime. Example:
170+
171+
```sh
172+
# Tell pkg-config where to find C++ driver installation.
173+
export PKG_CONFIG_PATH=$HOME/mongo-cxx-driver/lib/pkgconfig
174+
clang++ app.cpp -std=c++11 $(pkg-config --cflags --libs libmongocxx) -o ./app.out
175+
./app.out
176+
# Prints the following error:
177+
# dyld[3217]: Library not loaded: '@rpath/libmongocxx._noabi.dylib'
178+
# Referenced from: '/Users/kevin.albertson/code/app.out'
179+
# Reason: tried: '/usr/local/lib/libmongocxx._noabi.dylib' (no such file), '/usr/lib/libmongocxx._noabi.dylib' (no such file)
180+
# zsh: abort ./app.out
181+
```
182+
183+
The default `install name` of the C++ driver on macOS includes `@rpath`:
184+
```sh
185+
otool -D $HOME/mongo-cxx-driver/lib/libmongocxx.dylib
186+
# Prints:
187+
# /Users/kevin.albertson/mongo-cxx-driver/lib/libmongocxx.dylib:
188+
# @rpath/libmongocxx._noabi.dylib
189+
```
190+
191+
Including `@rpath` in the install name allows linking applications to control the list of search paths for the library.
192+
193+
`app.out` includes the load command for `@rpath/libmongocxx._noabi.dylib`. `app.out` does not have entries to substitute for `@rpath`.
194+
195+
There are several ways to consider solving this on macOS:
196+
197+
Pass `DYLD_FALLBACK_LIBRARY_PATH` to the directory containing the C++ driver libraries:
198+
199+
```sh
200+
DYLD_FALLBACK_LIBRARY_PATH=$HOME/mongo-cxx-driver/lib ./app.out
201+
# Prints "successfully connected with C++ driver"
202+
```
203+
204+
Alternatively, the linker option `-Wl,-rpath` can be passed to add entries to substitute for `@rpath`:
205+
```sh
206+
# Tell pkg-config where to find C++ driver installation.
207+
export PKG_CONFIG_PATH=$HOME/mongo-cxx-driver/lib/pkgconfig
208+
# Pass the linker option -rpath to set an rpath in the final executable.
209+
clang++ app.cpp -std=c++11 -Wl,-rpath,$HOME/mongo-cxx-driver/lib $(pkg-config --cflags --libs libmongocxx) -o ./app.out
210+
./app.out
211+
# Prints "successfully connected with C++ driver"
212+
```
213+
214+
If building the application with cmake, the [Default RPATH settings](https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling#default-rpath-settings) include the full RPATH to all used libraries in the build tree. However, when installing, cmake will clear the RPATH of these targets so they are installed with an empty RPATH. This may result in a `Library not loaded` error after install.
215+
216+
Example:
217+
```sh
218+
# Build application `app` using the C++ driver from a non-standard install.
219+
cmake \
220+
-DCMAKE_PREFIX_PATH=$HOME/mongo-cxx-driver \
221+
-DCMAKE_INSTALL_PREFIX=$HOME/app \
222+
-DCMAKE_CXX_STANDARD=11 \
223+
-Bcmake-build -S.
224+
cmake --build cmake-build --target app.out
225+
# Running app.out from build tree includes rpath to C++ driver.
226+
./cmake-build ./cmake-build/app.out
227+
# Prints: "successfully connected with C++ driver"
228+
229+
cmake --build cmake-build --target install
230+
# Running app.out from install tree does not include rpath to C++ driver.
231+
$HOME/app/bin/app.out
232+
# Prints "Library not loaded" error.
233+
```
234+
235+
Consider setting `-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE` so the rpath for the executable is kept in the install target.
236+
```sh
237+
# Build application `app` using the C++ driver from a non-standard install.
238+
# Use CMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE to keep rpath entry on installed app.
239+
cmake \
240+
-DCMAKE_PREFIX_PATH=$HOME/mongo-cxx-driver \
241+
-DCMAKE_INSTALL_PREFIX=$HOME/app \
242+
-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE \
243+
-DCMAKE_CXX_STANDARD=11 \
244+
-Bcmake-build -S.
245+
246+
cmake --build cmake-build --target install
247+
$HOME/app/bin/app.out
248+
# Prints "successfully connected with C++ driver"
249+
```
250+
251+
See the cmake documentation for [RPATH handling](https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling) for more information.
252+
253+
### Fixing the "cannot open shared object file" error on Linux
254+
255+
Applications linking to a non-standard directory installation may encounter an error loading the C++ driver at runtime. Example:
256+
257+
```sh
258+
# Tell pkg-config where to find C++ driver installation.
259+
export PKG_CONFIG_PATH=$HOME/mongo-cxx-driver/lib/pkgconfig
260+
g++ -std=c++11 app.cpp $(pkg-config --cflags --libs libmongocxx) -o ./app.out
261+
./app.out
262+
# Prints the following error:
263+
# ./app.out: error while loading shared libraries: libmongocxx.so._noabi: cannot open shared object file: No such file or directory
264+
```
265+
266+
There are several ways to consider solving this on Linux:
267+
268+
Pass `LD_LIBRARY_PATH` to the directory containing the C++ driver libraries:
269+
270+
```sh
271+
LD_LIBRARY_PATH=$HOME/mongo-cxx-driver/lib ./app.out
272+
# Prints "successfully connected with C++ driver"
273+
```
274+
275+
Alternatively, the linker option `-Wl,-rpath` can be passed to add `rpath` entries:
276+
```sh
277+
# Tell pkg-config where to find C++ driver installation.
278+
export PKG_CONFIG_PATH=$HOME/mongo-cxx-driver/lib/pkgconfig
279+
# Pass the linker option -rpath to set an rpath in the final executable.
280+
g++ app.cpp -std=c++11 -Wl,-rpath,$HOME/mongo-cxx-driver/lib $(pkg-config --cflags --libs libmongocxx) -o ./app.out
281+
./app.out
282+
# Prints "successfully connected with C++ driver"
283+
```
284+
285+
If building the application with cmake, the [Default RPATH settings](https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling#default-rpath-settings) include the full RPATH to all used libraries in the build tree. However, when installing, cmake will clear the RPATH of these targets so they are installed with an empty RPATH. This may result in a `Library not loaded` error after install.
286+
287+
Example:
288+
```sh
289+
# Build application `app` using the C++ driver from a non-standard install.
290+
cmake \
291+
-DCMAKE_PREFIX_PATH=$HOME/mongo-cxx-driver \
292+
-DCMAKE_INSTALL_PREFIX=$HOME/app \
293+
-DCMAKE_CXX_STANDARD=11 \
294+
-Bcmake-build -S.
295+
cmake --build cmake-build --target app.out
296+
# Running app.out from build tree includes rpath to C++ driver.
297+
./cmake-build ./cmake-build/app.out
298+
# Prints: "successfully connected with C++ driver"
299+
300+
cmake --build cmake-build --target install
301+
# Running app.out from install tree does not include rpath to C++ driver.
302+
$HOME/app/bin/app.out
303+
# Prints "cannot open shared object file" error.
304+
```
305+
306+
Consider setting `-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE` so the rpath for the executable is kept in the install target.
307+
```sh
308+
# Build application `app` using the C++ driver from a non-standard install.
309+
# Use CMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE to keep rpath entry on installed app.
310+
cmake \
311+
-DCMAKE_PREFIX_PATH=$HOME/mongo-cxx-driver \
312+
-DCMAKE_INSTALL_PREFIX=$HOME/app \
313+
-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE \
314+
-DCMAKE_CXX_STANDARD=11 \
315+
-Bcmake-build -S.
316+
317+
cmake --build cmake-build --target install
318+
$HOME/app/bin/app.out
319+
# Prints "successfully connected with C++ driver"
320+
```
321+
322+
See the cmake documentation for [RPATH handling](https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling) for more information.

0 commit comments

Comments
 (0)