如何在不使用 LD_LIBRARY_PATH 或 rpath 的情况下运行链接到共享库的二进制文件?

问题描述 投票:0回答:1

这个问题已经困扰我一段时间了。我尝试将共享对象链接到我的一个项目中的可执行文件(结构如下):

.
├── lib.c
├── lib.h
├── main.c
└── Makefile

...使用此 Makefile:

CC != if command -v clang; then continue; elif command -v gcc; then continue; else echo c99; fi

.PHONY: build

build: main
    ./main

lib.so: lib.c
    $(CC)  -shared -fPIC -o lib.so lib.c

main: main.c lib.so
    $(info Building executable: "main")
    $(CC) -o main main.c lib.so

...但后来我得到了这个错误:

./main: error while loading shared libraries: lib.so: cannot open shared object file: No such file or directory

我确实找到了一些现有的解决方案,涉及使用

LD_LIBRARY_PATH
变量或
-Wl,-rpath=path/to/dir
编译标志,但我们只是说我想要另一种方法来解决这个问题。

我知道,听我说完。我已经能够成功运行链接到分层结构中的共享对象的二进制文件,如下所示:

.
├── bin/
│   └── main
├── lib/
│   └── lib.so
├── src/
│   ├── lib.c
│   ├── lib.h
│   └── main.c
└── Makefile

...而且我不需要使用任何一种方法。在上面的示例中,我还在二进制文件上使用了

ldd

$ ldd bin/main
    linux-vdso.so.1 (0x00007ffec55e7000)
    lib/lib.so (0x00007f3198a7f000)
    libc.so.6 => /usr/lib/libc.so.6 (0x00007f3198876000)
    /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f3198a8b000)

与麻烦的二进制文件相比:

$ ldd main
    linux-vdso.so.1 (0x00007ffc2de5f000)
    lib.so => not found
    libc.so.6 => /usr/lib/libc.so.6 (0x00007880524c3000)
    /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007880526d3000)

虽然我可能在这里做出假设,但我不会假装我还没有找到这个问题的答案。在发布这个问题后不久,我将发布我自己的解决方案。

linux shared-libraries file-not-found
1个回答
0
投票

我只需要将

./
放在编译选项中的共享对象文件名之前,即可使其在同一目录中成功链接共享对象。字面意思就是这样。现在 Makefile 看起来像这样:

CC != if command -v clang; then continue; elif command -v gcc; then continue; else echo c99; fi

.PHONY: build

build: main
    ./main

lib.so: lib.c
    $(CC) -shared -fPIC -o lib.so lib.c

main: main.c lib.so
    $(info Building executable: "main")
    $(CC) -o main main.c ./lib.so
# The little './' determines whether the executable would successfully link to lib.so or not

clean:
    rm main lib.so

并在正在运行的可执行文件上使用

ldd

    linux-vdso.so.1 (0x00007ffd92ba4000)
    ./lib.so (0x000077142594c000)
    libc.so.6 => /usr/lib/libc.so.6 (0x0000771425743000)
    /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x0000771425958000)

除此之外,我还发现共享对象文件确实可以链接到工作目录以外的任何目录中,这解释了我之前使用共享库的工作到目前为止没有造成任何问题。

© www.soinside.com 2019 - 2024. All rights reserved.