Linux下Run-path依赖库链接阶段依赖缺失问题求解
Great question! Let's break down what's happening here and how to fix it while keeping your "each library manages its own dependencies" goal intact.
Understanding the Cross-Platform Linker Difference
First, the root of the issue is a key behavior gap between macOS and Linux linkers:
- macOS: The
dyldlinker only verifies direct dependencies (likelibmymaths.dylib) during the build phase ofsimpleapp. At runtime, it uses the@loader_path/@rpathembedded inlibmymaths.dylibto automatically findlibfastmatrix.dylib—no build-time check for indirect dependencies is required. - Linux: The GNU
ldlinker is stricter: when linkingsimpleapp, it resolves all dependencies, including indirect ones likelibfastmatrix.so. Even iflibmymaths.sohas a valid$ORIGIN-based RUNPATH,ldstill needs to locatelibfastmatrix.soduring the link phase ofsimpleapp—this is why you’re seeing that warning/error.
Fixing Linux Without Exposing Indirect Dependencies
Your goal is to keep simpleapp unaware of libfastmatrix.so, so we’ll configure libmymaths to pass the necessary linker hints to any target that links against it. Here’s how:
Step 1: Ensure $ORIGIN is Properly Escaped in CMake
First, double-check that the $ORIGIN token is correctly passed to the linker. In CMake, $ is a special variable character, so you need to escape it:
if(APPLE) set(TOKEN "@loader_path") elif(UNIX AND NOT APPLE) # Escape $ so CMake doesn’t interpret it as a variable set(TOKEN "\$ORIGIN") endif()
This ensures $ORIGIN is embedded correctly in libmymaths.so’s RUNPATH, which will work at runtime.
Step 2: Add Interface Link Options to libmymaths
We’ll tell CMake to automatically pass the -rpath-link flag to any target that links against libmymaths. This flag tells ld where to find indirect dependencies during the link phase, without adding those paths to simpleapp’s own RPATH.
Add this to libmymaths’ CMakeLists.txt:
if(UNIX AND NOT APPLE) # Adjust this path to match where libfastmatrix.so is built set(FASTMATRIX_BUILD_DIR "${CMAKE_SOURCE_DIR}/../libfastmatrix/build") # Pass -rpath-link to all targets linking against libmymaths target_link_options(${PROJECT_NAME} INTERFACE "-Wl,-rpath-link,${FASTMATRIX_BUILD_DIR}") endif()
- The
INTERFACEkeyword ensures this flag is applied automatically tosimpleapp(or any other target that linkslibmymaths)—no changes needed tosimpleapp’s CMake script. - This keeps dependency management encapsulated in
libmymaths, exactly as you want.
Step 3: Verify the Configuration
After updating the scripts:
- Rebuild
libfastmatrixandlibmymathsfirst. - Build
simpleapp—theldwarning/error should disappear. - At runtime, use
ldd simpleappto confirmlibmymaths.sois found, andldd libmymaths.soto confirmlibfastmatrix.sois located via the$ORIGIN-based RUNPATH.
Why This Works (and Why Your Temporary Fixes Were Needed)
Your temporary fixes (adding -rpath-link or extra RPATH to simpleapp) worked because they told ld where to find libfastmatrix.so during the link phase. By moving this configuration to libmymaths, you’re keeping the dependency logic tied to the library that actually depends on libfastmatrix.so—no exposure to simpleapp.
What If You Want to Avoid -rpath-link Entirely?
If you’re looking to skip the build-time check for indirect dependencies, you could use the --allow-shlib-undefined linker flag, but this is not recommended. It suppresses the ld warning, but if libfastmatrix.so can’t be found at runtime, your application will crash unexpectedly. This flag is intended for niche edge cases, not general use.
Per GNU ld documentation:
--allow-shlib-undefinedallows undefined symbols in shared libraries. This is normally not allowed, since it would cause a link error. However, if you are creating a shared library that will be linked against other shared libraries later, this option may be useful. But note that using this option can lead to runtime errors if the undefined symbol is not resolved at runtime.
Final Notes
- Your existing macOS configuration is already correct—no changes needed there.
- With these Linux adjustments, both platforms will behave consistently:
simpleappcan be moved anywhere (as long as the relative path betweensimpleapp,libmymaths.so, andlibfastmatrix.sostays the same), and each library manages its own dependencies independently.
内容的提问来源于stack exchange,提问作者thomasarvanitidis

