2

我正在遵循此页面中的说明,并且页面尝试在 Ubuntu Linux 上构建和使用共享库。

我在我的 PC 上使用交叉编译器构建库和应用程序,而不是将文件复制到目标系统并在那里运行。

最后,我处于正确定义所有符号链接并且我能够运行应用程序的阶段 - 但不是以所需的形式。

假设我libtest.so.1.0在目录中有一个共享库/home/ysap/libs。然后我创建了符号链接libtest.so.1libtest.so在同一个目录中,都指向库文件。

在目录中,我有一个使用该库/home/ysap/apps的应用程序。app.etest

现在,要运行应用程序,我可以输入:

> 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权限运行。实际的调用行是:

> 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)
4

2 回答 2

4

sudo 问题正如@duskwuff 所述,但是如果您要编译应用程序,并且不需要修改 LD_LIBRARY_PATH 变量,则在链接应用程序时可以使用该$ORIGIN变量,该变量已被最新版本的 linux 识别。

如果所有库都在当前目录中,那么当您链接应用程序时,您将使用额外选项:

-Wl,-R'$ORIGIN'

您需要引用该选项以防止它在编译时被 shell 扩展。

如果您将其放入 a 中,Makefile则使用:

-Wl,-R\$$ORIGIN

$$为了让 make 使用 $,\是为了防止从命令行调用的 shell 在将变量传递给命令之前扩展变量。

您可以使用任何符号路径引用,因此如果您的结构中包含二进制文件bin/和库lib/,则可以使用$ORIGIN/../lib.

这也适用dlopen,因此它会在运行时动态加载库时找到它们

于 2012-12-05T20:08:47.317 回答
2

从用户指定的路径加载库存在安全风险,因此sudo请始终去除所有LD_环境变量,包括LD_LIBRARY_PATH.

于 2012-12-05T19:54:18.857 回答