疑难错误:/usr/bin/ld: cannot find -lxxx
AI摘要: 本文讲述了在开发过程中遇到的一个编译错误,即`/usr/bin/ld: cannot find -lLLVM-13-rust-1.58.0-nightly`。原因是该库的路径被写入了zshrc的配置文件中的`LD_LIBRARY_PATH`位置,导致编译器无法找到。通过查阅资料,发现`LIBRARY_PATH`和`LD_LIBRARY_PATH`的区别,并了解到它们在编译和运行时的作用及影响工具。同时,文章还提供了如何同时使用这两个变量的建议,以及在使用时应考虑的安全性问题、调试问题和持久化配置。
前几天做在做开发的时候,遇到一个编译报错问题,弄到半夜3点才解决。
具体错误是:/usr/bin/ld: cannot find -lLLVM-13-rust-1.58.0-nightly
, 也就是gcc
编译的时候缺少lLLVM-13-rust-1.58.0-nightly
的第三方库,但是这个库的存放位置已经被写入zshrc的配置文件中的LD_LIBRARY_PATH
位置,所以百思不得其解,最终查看各种资料才发现LIBRARY_PATH
和LD_LIBRARY_PATH
的区别。
1. LIBRARY_PATH
-
用途:
-
用于 编译阶段,告诉编译器(如
gcc
或clang
)在哪里查找静态库 (.a
) 和动态库 (.so
或.dylib
)。 -
编译器在链接时使用这个路径来找到依赖的库文件。
-
-
常见场景:
- 当你编译程序并需要链接某些库(例如
gcc main.c -o main -lfoo
),如果foo
不在默认的库搜索路径下,你可以通过设置LIBRARY_PATH
来告诉编译器去哪里找。
- 当你编译程序并需要链接某些库(例如
-
影响工具:
- 主要被编译器(如
gcc
、clang
)使用。
- 主要被编译器(如
-
示例:
export LIBRARY_PATH=/custom/lib/path:$LIBRARY_PATH gcc main.c -o main
2. LD_LIBRARY_PATH
-
用途:
-
用于 运行阶段,告诉动态链接器(
ld.so
或ld-linux.so
)在加载动态库时,优先从哪里查找.so
文件。 -
这是运行时的动态库搜索路径。
-
-
常见场景:
- 当运行的程序依赖的动态库不在默认的搜索路径(如
/usr/lib
、/lib
)中时,可以通过设置LD_LIBRARY_PATH
告诉系统去哪里找动态库。
- 当运行的程序依赖的动态库不在默认的搜索路径(如
-
影响工具:
- 主要被动态链接器(
ld.so
)使用。
- 主要被动态链接器(
-
示例:
export LD_LIBRARY_PATH=/custom/lib/path:$LD_LIBRARY_PATH ./main
主要区别
| 属性 | LIBRARY_PATH | LD_LIBRARY_PATH |
| ------------ | ------------------------------ | --------------------------------------- |
| 作用阶段 | 编译阶段 | 运行阶段 |
| 使用场景 | 查找静态库和动态库以供链接 | 加载动态库以供程序运行 |
| 使用工具 | 编译器(如 gcc
、clang
) | 动态链接器(如 ld.so
、ld-linux.so
) |
| 作用对象 | 静态库 (.a
) 和动态库 (.so
) | 动态库 (.so
) |
如何同时使用
如果你在开发时需要编译和运行程序,并且库文件不在系统默认路径中,你可能需要同时设置这两个变量。
export LIBRARY_PATH=/custom/lib/path:$LIBRARY_PATH
export LD_LIBRARY_PATH=/custom/lib/path:$LD_LIBRARY_PATH
gcc main.c -o main
./main
这样,编译器和动态链接器都能正确找到所需的库文件。
注意事项
-
安全性问题:
-
滥用
LD_LIBRARY_PATH
可能引入安全风险,特别是在多用户系统中,攻击者可以通过伪造动态库进行攻击。 -
如果可能,优先使用
rpath
或RUNPATH
来指定运行时库路径,而不是依赖LD_LIBRARY_PATH
。
-
-
调试问题:
- 设置过多的路径可能导致链接器行为复杂化,建议仅在必要时设置,并注意路径的优先级。
-
持久化配置:
- 如果需要长时间使用这些变量,可以将它们添加到
~/.bashrc
或~/.zshrc
中。
- 如果需要长时间使用这些变量,可以将它们添加到
总结
-
编译时找不到库 → 设置
LIBRARY_PATH
。 -
运行时找不到库 → 设置
LD_LIBRARY_PATH
。 -
它们的功能不同,不是同一个东西。