我正在关注这个页面的解释, 这个页面试图在Ubuntu Linux上构build和使用共享库。
我在PC上使用交叉编译器构build库和应用程序,而不是将文件复制到目标系统并在那里运行。
最后,我处于正确定义所有符号链接的阶段,而且我能够运行应用程序 – 但不是以所需的forms。
假设我在目录/home/ysap/libs
有共享库libtest.so.1.0
。 然后我在同一个目录中创build了符号链接libtest.so.1
和libtest.so
,它们都指向库文件。
在目录/home/ysap/apps
我有一个使用test
库的应用程序app.e
现在,运行应用程序,我可以input:
> 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运行W / Ovariables赋值?
更新1 :
应用程序使用mmap()
调用,因此必须使用sudo priviledge运行。 实际的调用行是:
> sudo LD_LIBRARY_PATH=/home/ysap/libs ./app.e
是否有可能export
variables没有在sudo环境中更新?
更新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)
sudo问题就像@duskwuff状态,但是如果你想编译一个应用程序,而不需要修改LD_LIBRARY_PATH变量,那么在链接应用程序时,你可以使用$ORIGIN
变量,这个变量可以被最新版本的linux所识别。
如果所有的库都在当前目录中,那么当您链接应用程序时,可以使用额外的选项:
-Wl,-R'$ORIGIN'
您需要引用该选项以防止在编译时由shell进行扩展。
如果你把它放到一个Makefile
那么你使用:
-Wl,-R\$$ORIGIN
$$
是为了使用$, \
是为了防止从命令行调用的shell在将该变量传递到命令之前展开该变量。
你可以使用任何符号路径引用,所以如果你有一个结构的二进制文件在bin/
和库在lib/
,你可以使用$ORIGIN/../lib
。
这也适用于dlopen
,因此它将在运行时动态加载时找到库
从用户指定的路径加载库存在安全风险,所以sudo
总是删除所有LD_
环境变量,包括LD_LIBRARY_PATH
。