Troubleshooting error: /usr/bin/ld: cannot find -lxxx
"TLDR: This article describes a compilation error encountered during development, namely `/usr/bin/ld: cannot find -lLLVM-13-rust-1.58.0-nightly`. The cause is that the path to this library was written into the `LD_LIBRARY_PATH` variable in the zshrc configuration file, preventing the compiler from locating it. By consulting relevant resources, the difference between `LIBRARY_PATH` and `LD_LIBRARY_PATH` was identified, along with their respective roles and effects on tools during compilation and runtime. Additionally, the article provides suggestions on how to use both variables simultaneously, as well as considerations regarding security issues, debugging problems, and persistent configuration when using them."
A few days ago, while working on development, I encountered a compilation error that kept me up until 3 AM before I finally resolved it.
The specific error was: /usr/bin/ld: cannot find -lLLVM-13-rust-1.58.0-nightly, which means gcc couldn't find the third-party library lLLVM-13-rust-1.58.0-nightly during compilation. However, the location of this library had already been written into the LD_LIBRARY_PATH variable in the zshrc configuration file, so I was completely baffled. After searching through various resources, I finally discovered the difference between LIBRARY_PATH and LD_LIBRARY_PATH.
1. LIBRARY_PATH
-
Purpose:
- Used during the compilation phase to tell the compiler (such as
gccorclang) where to find static libraries (.a) and dynamic libraries (.soor.dylib). - The compiler uses this path during linking to locate the required library files.
- Used during the compilation phase to tell the compiler (such as
-
Common scenarios:
- When you compile a program and need to link against certain libraries (e.g.,
gcc main.c -o main -lfoo), iffoois not in the default library search path, you can setLIBRARY_PATHto tell the compiler where to find it.
- When you compile a program and need to link against certain libraries (e.g.,
-
Affected tools:
- Primarily used by compilers (such as
gcc,clang).
- Primarily used by compilers (such as
-
Example:
export LIBRARY_PATH=/custom/lib/path:$LIBRARY_PATH gcc main.c -o main
2. LD_LIBRARY_PATH
-
Purpose:
- Used during the runtime phase to tell the dynamic linker (
ld.soorld-linux.so) where to preferentially look for.sofiles when loading dynamic libraries. - This is the runtime search path for dynamic libraries.
- Used during the runtime phase to tell the dynamic linker (
-
Common scenarios:
- When a program being run depends on dynamic libraries that are not in the default search paths (such as
/usr/lib,/lib), you can setLD_LIBRARY_PATHto tell the system where to find the dynamic libraries.
- When a program being run depends on dynamic libraries that are not in the default search paths (such as
-
Affected tools:
- Primarily used by the dynamic linker (
ld.so).
- Primarily used by the dynamic linker (
-
Example:
export LD_LIBRARY_PATH=/custom/lib/path:$LD_LIBRARY_PATH ./main
Key Differences
| Attribute | LIBRARY_PATH | LD_LIBRARY_PATH |
|---|---|---|
| Phase | Compilation phase | Runtime phase |
| Use case | Find static and dynamic libraries for linking | Load dynamic libraries for program execution |
| Tools used | Compilers (e.g., gcc, clang) |
Dynamic linker (e.g., ld.so, ld-linux.so) |
| Targets | Static libraries (.a) and dynamic libraries (.so) |
Dynamic libraries (.so) |
How to Use Both Together
If you need to compile and run programs during development and the library files are not in the system default paths, you may need to set both variables.
export LIBRARY_PATH=/custom/lib/path:$LIBRARY_PATH
export LD_LIBRARY_PATH=/custom/lib/path:$LD_LIBRARY_PATH
gcc main.c -o main
./main
This way, both the compiler and the dynamic linker can correctly find the required library files.
Important Notes
-
Security concerns:
- Misusing
LD_LIBRARY_PATHcan introduce security risks, especially in multi-user systems where attackers can exploit forged dynamic libraries. - If possible, prefer using
rpathorRUNPATHto specify runtime library paths instead of relying onLD_LIBRARY_PATH.
- Misusing
-
Debugging issues:
- Setting too many paths can complicate linker behavior. It's recommended to set them only when necessary and pay attention to path priority.
-
Persistent configuration:
- If you need to use these variables for an extended period, you can add them to
~/.bashrcor~/.zshrc.
- If you need to use these variables for an extended period, you can add them to
Summary
- Library not found during compilation → Set
LIBRARY_PATH. - Library not found during runtime → Set
LD_LIBRARY_PATH. - They serve different functions and are not the same thing.