ClangQL
ClangQL copied to clipboard
Crash on macOS: dyld[50112]: Library not loaded: @rpath/libclang.dylib
Describe the bug Built clangql from git on macOS Sonoma 14.4.1 with rust 1.71.1 and the resulting binary is crashing due to unset LC_RPATH, and hence the binary fails to load libclang.dylib
$ clangql
dyld[50112]: Library not loaded: @rpath/libclang.dylib
Referenced from: <2E046823-CCFD-39AC-8724-B8765694F2F4> /usr/local/bin/clangql
Reason: no LC_RPATH's found
Abort trap: 6
I used DYLD_FALLBACK_LIBRARY_PATH to set my libclang.dylib path and it worked afterwards. Not sure if there is any way to fix this via code. I seen that opencv faces this issue in rust
I used DYLD_FALLBACK_LIBRARY_PATH to set my libclang.dylib path and it worked afterwards. Not sure if there is any way to fix this via code. I seen that opencv faces this issue in rust
Thats good i think we can't solve this using code but when we release executables we don't need dyn linking for all users
I will mark this issue as solution for anyone who faced same issue
Thank you
Please note that macOS sanitizes your environment if you have System Integrity Protection (SIP) enabled. E.g. export DYLD_FALLBACK_LIBRARY_PATH=/usr/local/lib
followed by echo $DYLD_FALLBACK_LIBRARY_PATH
prints nothing.
The following variables are sanitized:
DYLD_LIBRARY_PATH
DYLD_FALLBACK_LIBRARY_PATH
LD_LIBRARY_PATH
DYLD_INSERT_LIBRARIES
See more info here: https://briandfoy.github.io/macos-s-system-integrity-protection-sanitizes-your-environment/
Please also note that from macOS Sonoma onwards the dynamic linker no longer sets DYLD_FALLBACK_LIBRARY_PATH
(it used to be set to /usr/local/lib:/usr/lib
previously, which allowed binaries to find libraries in those paths without having to explicitly set library load paths). This means that maintainers of software now have to make an explicit decision on how to find dependent libraries. The choices are to:
- Set the absolute path to the dependent library
- Use
@rpath
andLC_PATH
loader command to set absolute path to the library from - Use
@rpath
andLC_PATH
loader command to set library load path relative to the executable (use variables like@executable_path
or@loader_path
).
Last choice offers most flexibility to relocate the executable binary. However, low level system tools should probably use option 1. I think this tool probably should as well.
For more information see man dyld
.
So, the proper solution here is to somehow pass -rpath
option to the system linker. I've done a bit of research and it looks like cargo build system is a bit immature in this regard. There was a request to add support for setting arbitrary rpaths through cargo over 6 years ago, but it is still Open:
https://github.com/rust-lang/cargo/issues/5077
Please note that macOS sanitizes your environment if you have System Integrity Protection (SIP) enabled. E.g.
export DYLD_FALLBACK_LIBRARY_PATH=/usr/local/lib
followed byecho $DYLD_FALLBACK_LIBRARY_PATH
prints nothing.The following variables are sanitized:
DYLD_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH LD_LIBRARY_PATH DYLD_INSERT_LIBRARIES
See more info here: https://briandfoy.github.io/macos-s-system-integrity-protection-sanitizes-your-environment/
Please also note that from macOS Sonoma onwards the dynamic linker no longer sets
DYLD_FALLBACK_LIBRARY_PATH
(it used to be set to/usr/local/lib:/usr/lib
previously, which allowed binaries to find libraries in those paths without having to explicitly set library load paths). This means that maintainers of software now have to make an explicit decision on how to find dependent libraries. The choices are to:
- Set the absolute path to the dependent library
- Use
@rpath
andLC_PATH
loader command to set absolute path to the library from- Use
@rpath
andLC_PATH
loader command to set library load path relative to the executable (use variables like@executable_path
or@loader_path
).Last choice offers most flexibility to relocate the executable binary. However, low level system tools should probably use option 1. I think this tool probably should as well.
For more information see
man dyld
.So, the proper solution here is to somehow pass
-rpath
option to the system linker. I've done a bit of research and it looks like cargo build system is a bit immature in this regard. There was a request to add support for setting arbitrary rpaths through cargo over 6 years ago, but it is still Open:
Thank you so much for information, I will use them in CD Too
@AmrDeveloper Try using compiler flags -rpath liek @mario-grgic suggested. When I faced this problem for cpp project I built in that way not sure if there is a way to do that in Rust or not.