Ubuntu 16.04下Boost共享库链接异常:运行时为何依赖非指定版本?
libboost_filesystem.so.1.68.0 when I linked against -mt suffixed libraries? Great question—this is a super common gotcha with Boost's shared library naming and how Linux's dynamic linker works. Let's break down what's happening and how to fix it.
What's going on here?
The -mt suffix in libboost_filesystem-mt.so marks it as the multi-threaded variant of the Boost Filesystem library. But here's the key: the dynamic linker (ld.so) doesn't care about the filename you linked against at compile time. It looks at the library's SONAME (Shared Object Name)—a piece of metadata embedded directly in the .so file.
You can confirm this yourself with a quick command:
readelf -d /path/to/lib/libboost_filesystem-mt.so | grep SONAME
Chances are, the output will show SONAME: libboost_filesystem.so.1.68.0. When you link against the -mt library, the compiler writes this SONAME into your executable's dependency list. At runtime, the linker will hunt for a file matching that exact SONAME, not the -mt filename you used during compilation.
Fixes to resolve the error
1. Fix library symlinks in your Boost directory
First, check what library files exist in your Boost lib folder:
ls -l /path/to/lib/libboost_filesystem* /path/to/lib/libboost_system*
If you see libboost_filesystem-mt.so.1.68.0 but no libboost_filesystem.so.1.68.0, create a symlink to map the SONAME to your multi-threaded library:
ln -s /path/to/lib/libboost_filesystem-mt.so.1.68.0 /path/to/lib/libboost_filesystem.so.1.68.0 ln -s /path/to/lib/libboost_system-mt.so.1.68.0 /path/to/lib/libboost_system.so.1.68.0
This tells the dynamic linker that the SONAME it's looking for points directly to the multi-threaded library you want to use.
2. Add your Boost path to LD_LIBRARY_PATH
If the libraries exist but the linker can't find them, temporarily add the Boost lib directory to your runtime library path:
export LD_LIBRARY_PATH=/path/to/lib:$LD_LIBRARY_PATH ./demo
To make this permanent, add that export line to your ~/.bashrc or ~/.profile file.
3. Embed the library path in your executable with rpath (recommended)
Instead of relying on environment variables, configure CMake to embed the Boost library path directly into your executable using rpath. Add these lines to your CMakeLists.txt:
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES INSTALL_RPATH "${Boost_LIBRARY_DIRS}" BUILD_WITH_INSTALL_RPATH ON )
This way, your executable will always know where to find the Boost libraries at runtime, no extra environment setup needed.
4. Double-check your Boost build (if you compiled it yourself)
If you built Boost from source, make sure you explicitly enabled multi-threading during compilation. Run these commands when building Boost:
./bootstrap.sh --with-libraries=filesystem,system ./b2 threading=multi link=shared install
This ensures the multi-threaded variants are built correctly, and their SONAMEs align with your needs.
Verify the fix
After applying any of these fixes, confirm the executable can find its dependencies with:
ldd ./demo
You should see your Boost libraries listed with their full paths, and no more "cannot open shared object file" errors.
内容的提问来源于stack exchange,提问作者TonyParker

