当使用rpath时,C++可执行文件无法找到动态链接的共享库
C++ executable cannot find the dynamically-linking shared libraries when using rpath
大家好,我用和一些poco库为Ubuntu 16.04(g++5.4.0)创建了一个c++应用程序。我需要在以前的Ubuntu 14.04(g++4.8.4)中安装该应用程序。因此,我决定将共享库与可执行文件一起分发。关于libstdc++.so库的分发,我静态地遵循了链接libstdc++的帖子:有什么问题吗?我正在使用以下makefile来构建可执行文件:
CC := g++
# Folders
SRCDIR := src
BUILDDIR := build
TARGETDIR := /usr/bin
# Targets
EXECUTABLE := my_app
TARGET := $(TARGETDIR)/$(EXECUTABLE)
SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
CFLAGS := -c -Wall -std=c++14
INC := -I include
LDFLAGS := '-Wl,-rpath,$$ORIGIN/../share/my_app_data/libs' -L/usr/share/my_app_data/libs
LDLIBS := -lPocoNet -lPocoFoundation -lPocoJSON
$(TARGET): $(OBJECTS)
@echo " Linking..."
sudo $(CC) $^ -o $@ $(LDFLAGS) $(LDLIBS)
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
@mkdir -p $(BUILDDIR)
$(CC) $(CFLAGS) $(INC) -c -o $@ $<
clean:
@echo " Cleaning...";
sudo $(RM) -r $(BUILDDIR) $(TARGET)
.PHONY: clean
我在/usr/bin中安装了可执行文件,在/usr/share/my_app_data/libs中安装了libs文件夹。当我给出readelf -d my_app
时,我在两个Ubuntu版本中都得到了以下内容:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libPocoFoundation.so.48]
0x0000000000000001 (NEEDED) Shared library: [libPocoJSON.so.48]
0x0000000000000001 (NEEDED) Shared library: [libPocoNet.so.48]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000f (RPATH) Library rpath: [$ORIGIN/../share/my_app_data/libs]
运行my_app时,找不到共享库。我使用文件夹/usr/share/my_app_data/libs更新/etc/ld/so.conf,然后找到与poco相关的库。然而,它找不到libstdc++.so.6,即使libs文件夹中存在libstdc+.so.6.21文件,并且我得到了以下打印输出:
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by my_app)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by my_app)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /usr/share/my_app_data/libs/libPocoFoundation.so.48)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/share/my_app_data/libs/libPocoFoundation.so.48)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /usr/share/my_app_data/libs/libPocoJSON.so.48)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/share/my_app_data/libs/libPocoJSON.so.48)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /usr/share/my_app_data/libs/libPocoNet.so.48)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/share/my_app_data/libs/libPocoNet.so.48)
libs文件夹中ls -l
的输出为:
-rwx---rwx 1 root root 2092592 Dec 13 23:06 libPocoFoundation.so.48
-rwx---rwx 1 root root 348488 Dec 13 23:06 libPocoJSON.so.48
-rwx---rwx 1 root root 1225968 Dec 13 23:06 libPocoNet.so.48
lrwxrwxrwx 1 root root 19 Dec 13 23:07 libstdc++.so.6 -> libstdc++.so.6.0.21
-rw----rwx 1 root root 1566440 Dec 13 23:06 libstdc++.so.6.0.21
file libs/*
的输出为:
libs/libPocoFoundation.so.48: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=9b5472754fa836e7be0893d6ed306f63b2cbc4aa, stripped
libs/libPocoJSON.so.48: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=fb57d0459e72415f90a1fc32b7bb2f695b49c5d7, stripped
libs/libPocoNet.so.48: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=175c019baa1ec16d908737443294ed3cf03d3315, stripped
libs/libstdc++.so.6: symbolic link to `libstdc++.so.6.0.21'
libs/libstdc++.so.6.0.21: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=b6d9d56d8e8afa9d4b46a60eda985d45dcd51524, stripped
ldd my_app
的输出为:
linux-vdso.so.1 => (0x00007ffcbd394000)
libPocoFoundation.so.48 => /usr/bin/./../share/my_app_data/libs/libPocoFoundation.so.48 (0x00007feddb89a000)
libPocoJSON.so.48 => /usr/bin/./../share/my_app_data/libs/libPocoJSON.so.48 (0x00007feddb645000)
libPocoNet.so.48 => /usr/bin/./../share/my_app_data/libs/libPocoNet.so.48 (0x00007feddb317000)
libstdc++.so.6 => /usr/bin/./../share/my_app_data/libs/libstdc++.so.6 (0x00007fedd9f99000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fedd9c7f000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fedd9a68000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fedd96a3000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fedd9485000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fedd9280000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fedd9078000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fedd8180000)
libidn.so.11 => /usr/lib/x86_64-linux-gnu/libidn.so.11 (0x00007fedd7f4d000)
librtmp.so.0 => /usr/lib/x86_64-linux-gnu/librtmp.so.0 (0x00007fedd7d33000)
libgssapi_krb5.so.2 => /usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2 (0x00007fedd7aeb000)
liblber-2.4.so.2 => /usr/lib/x86_64-linux-gnu/liblber-2.4.so.2 (0x00007fedd78dc000)
libldap_r-2.4.so.2 => /usr/lib/x86_64-linux-gnu/libldap_r-2.4.so.2 (0x00007fedd768b000)
libgnutls.so.26 => /usr/lib/x86_64-linux-gnu/libgnutls.so.26 (0x00007fedd73cc000)
libgcrypt.so.11 => /lib/x86_64-linux-gnu/libgcrypt.so.11 (0x00007fedd714c000)
libkrb5.so.3 => /usr/lib/x86_64-linux-gnu/libkrb5.so.3 (0x00007fedd6e81000)
libk5crypto.so.3 => /usr/lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007fedd6c51000)
libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007fedd6a4d000)
libkrb5support.so.0 => /usr/lib/x86_64-linux-gnu/libkrb5support.so.0 (0x00007fedd6842000)
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007fedd6626000)
libsasl2.so.2 => /usr/lib/x86_64-linux-gnu/libsasl2.so.2 (0x00007fedd640b000)
libgssapi.so.3 => /usr/lib/x86_64-linux-gnu/libgssapi.so.3 (0x00007fedd61cd000)
libtasn1.so.6 => /usr/lib/x86_64-linux-gnu/libtasn1.so.6 (0x00007fedd5fb8000)
libp11-kit.so.0 => /usr/lib/x86_64-linux-gnu/libp11-kit.so.0 (0x00007fedd5d76000)
libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007fedd5b71000)
libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007fedd596c000)
libheimntlm.so.0 => /usr/lib/x86_64-linux-gnu/libheimntlm.so.0 (0x00007fedd5763000)
libkrb5.so.26 => /usr/lib/x86_64-linux-gnu/libkrb5.so.26 (0x00007fedd54da000)
libasn1.so.8 => /usr/lib/x86_64-linux-gnu/libasn1.so.8 (0x00007fedd5239000)
libhcrypto.so.4 => /usr/lib/x86_64-linux-gnu/libhcrypto.so.4 (0x00007fedd5006000)
libroken.so.18 => /usr/lib/x86_64-linux-gnu/libroken.so.18 (0x00007fedd4df0000)
libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007fedd4be8000)
libwind.so.0 => /usr/lib/x86_64-linux-gnu/libwind.so.0 (0x00007fedd49be000)
libheimbase.so.1 => /usr/lib/x86_64-linux-gnu/libheimbase.so.1 (0x00007fedd47b0000)
libhx509.so.5 => /usr/lib/x86_64-linux-gnu/libhx509.so.5 (0x00007fedd4567000)
我还发现,通过在一个库中给出ldd e.x.libPocoFoundation.so.48我得到
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6
因此,my_app可执行文件显示了libstdc++.So.6的正确路径,而共享库则没有。由于这些库不包含使用chrpath的rpath,是否有另一种方法可以使它们显示
libstdc++.so.6 => /usr/share/npt-data/libs/libstdc++.so.6
从Natty Narwhal开始,Ubuntu附带的链接器默认使用as-needed
。这意味着主可执行文件中没有符号的库将不会被链接。您可以通过添加Wl,--no-as-needed
来快速覆盖它。
https://wiki.ubuntu.com/NattyNarwhal/ToolchainTransition
相关文章:
- g++用户定义的动态链接库上的全局new和delete运算符
- 如何使用C++导出制作动态链接库
- 使用动态链接加载程序 <dlfcn.h> 而不是直接函数调用的目的是什么?
- 动态链接库中C++回调函数
- 我的动态链接队列在同一输出流中调用时不正确地输出三个返回函数
- 如何动态链接 grpc 库 c++?
- 调用函数一次用于动态链接库,一次从可执行文件调用函数
- 将函数传递给动态链接库
- aarch64动态链接器rpath使用辅助依赖链接
- 动态链接-Linux与Windows
- 如何将动态链接库与CMake一起使用
- 使用动态链接从.dll库调用函数
- 静态链接 Visual Studio dll 到动态链接的 sfml 项目
- 从另一个动态链接库项目调用静态库函数
- JNI 不满意链接错误: 动态链接库 (DLL) 初始化例程失败
- 使用 GCC 的静态和动态链接
- 静态链接MSVC库,动态链接Qt
- 在动态链接中,.exe如何知道在更新库时在哪里搜索库?
- 如何强制Windows.h在Visual Studio中静态链接而不是动态链接?
- 对应于 stdio.h 的库文件是动态链接还是静态链接