我正在按照this page和this page中的解释来尝试在Ubuntu Linux上构建和使用共享库。
我在PC上使用交叉编译器构建库和应用程序,而不是将文件复制到目标系统并在那里运行。
最后,我处于正确定义所有符号链接并且我能够运行应用程序的阶段 - 但不是以所需的形式。
假设我在目录libtest.so.1.0
中有一个共享库/home/ysap/libs
。然后,我在同一目录中创建了符号链接libtest.so.1
和libtest.so
,两者都指向库文件。
在目录/home/ysap/apps
中,我有一个使用app.e
库的应用程序test
。
现在,要运行该应用程序,我可以输入:
> LD_LIBRARY_PATH=/home/ysap/libs ./app.e
并且应用程序运行良好。但是,我想删除作业,所以我尝试输入:
> export LD_LIBRARY_PATH=/home/ysap/libs
> ./app.e
但不幸的是我收到一条错误消息,说:
./app.e: error while loading shared libraries: libtest.so.1: cannot open shared object file: No such file or directory
我也尝试输入:
> ldconfig -n /home/ysap/libs
和
> sudo ldconfig -n /home/ysap/libs
但它没有帮助。
我做错了什么?如何使用变量赋值运行app.e
更新1 :
应用程序使用mmap()
调用,因此必须使用 sudo priviledge运行。实际的调用行是:
> sudo LD_LIBRARY_PATH=/home/ysap/libs ./app.e
sudo 环境中是否可能未更新export
-ed变量?
更新2 :
ldd ./app.e
的输出:
libtest.so.1 => /home/ysap/libs/libtest.so.1 (0xb6faa000)
libgcc_s.so.1 => /lib/arm-linux-gnueabi/libgcc_s.so.1 (0xb6f85000)
libc.so.6 => /lib/arm-linux-gnueabi/libc.so.6 (0xb6ea4000)
/lib/ld-linux.so.3 (0xb6fb7000)
答案 0 :(得分:4)
sudo问题与@duskwuff一样,但如果你想编译一个应用程序,而不需要修改LD_LIBRARY_PATH变量,那么在链接应用程序时你可以使用大多数人都能识别的$ORIGIN
变量。最新版本的linux。
如果所有库都在当前目录中,那么在链接应用程序时,使用额外选项:
-Wl,-R'$ORIGIN'
您需要引用该选项以防止在编译时由shell进行扩展。
如果您将其放入Makefile
,那么您可以使用:
-Wl,-R\$$ORIGIN
$$
是让make使用$,\
是为了防止从命令行调用的shell在将变量传递给命令之前扩展变量。
您可以使用任何符号路径引用,因此如果您的结构中的二进制文件位于bin/
且库位于lib/
中,则可以使用$ORIGIN/../lib
。
这也适用于dlopen
,因此它会在运行时动态加载时找到库
答案 1 :(得分:2)
从用户指定的路径加载库存在安全风险,因此sudo
始终会删除所有LD_
个环境变量,包括LD_LIBRARY_PATH
。