我用librtmp构建了ffmpeg.我的librtmp位于/ opt/librtmp/lib.当我执行ffmpeg时,它说:
./ffmpeg: error while loading shared libraries: librtmp.so.0: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我使用ldd命令显示未找到:
[qty@testing bin]# ldd ffmpeg
linux-vdso.so.1 => (0x00007fff15576000)
librtmp.so.0 => not found
libz.so.1 => /lib64/libz.so.1 (0x00002b9a71e10000)
libm.so.6 => /lib64/libm.so.6 (0x00002b9a72025000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b9a722a8000)
libc.so.6 => /lib64/libc.so.6 (0x00002b9a724c3000)
/lib64/ld-linux-x86-64.so.2 (0x00002b9a71bf2000)
Run Code Online (Sandbox Code Playgroud)
我知道我的意思是:
[qty@testing bin]# ls -alh /opt/librtmp/lib/
total 300K
drwxr-xr-x 3 root root 4.0K Sep 25 17:10 .
drwxr-xr-x 7 root root 4.0K Sep 25 17:10 ..
-rw-r--r-- 1 root …
Run Code Online (Sandbox Code Playgroud) 我有两个库,例如两个烤箱库libtoaster_a.so和libtoaster_b.so以及所有相关的major/minor/rev符号链接,例如libtoaster_a.so.1.0.0等.两个库实现相同的烤箱接口,但只是简单地进行处理不同.因此,当我构建一个使用该库的应用程序时,使用哪个应用程序并不重要(从应用程序的角度看它们是相同的).
因为我想在编译和分发应用程序之后决定使用哪个库,所以我创建一个符号链接libtoaster.so,它指向libtoaster.so.1,然后指向libtoaster_a.so.1和libtoaster_b.so. 1.因此,用户/安装程序可以简单地更改libtoaster.so.1链接以选择要使用的实现.
对于构建说我有libtoaster.so.1挂libtoaster_a.so.1默认.当我编译我的应用程序时,例如:my_app由类似的东西gcc -o my_app -ltoaster...
编译,甚至正确运行libtoaster_a.so.1.但是,如果我在my_app上运行ldd,我将看到它根据需要链接到libtoaster_a.so.1而不是libtoaster.so.1,因此更改libtoaster.so.1链接无效.
有没有更好的方法来解决这个问题,而不是制作libtoaster_a.so.1,将其重命名为 libtoaster.so.1,对该库进行my_app,然后删除libtoaster.so.1并再次将其创建为符号链接?
ldd
是一种检查给定可执行文件正在或将要使用的共享库的简单方法.但是它并不总是按预期工作.例如,请参阅以下shell片段,演示如何"失败"将libreadline"依赖"发现到python二进制文件中
我尝试了很多其他发行版,但我是从Tikanga复制的
$ lsb_release -a
LSB Version: :core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-ia32:printing-4.0-noarch
Distributor ID: RedHatEnterpriseServer
Description: Red Hat Enterprise Linux Server release 5.6 (Tikanga)
Release: 5.6
Codename: Tikanga
Run Code Online (Sandbox Code Playgroud)
查看ldd
默认安装的内容python
(来自官方存储库).
$ which python
/usr/bin/python
$ ldd `which python`
libpython2.4.so.1.0 => /usr/lib64/libpython2.4.so.1.0 (0x00000030e6200000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00000030e0e00000)
libdl.so.2 => /lib64/libdl.so.2 (0x00000030e0a00000)
libutil.so.1 => /lib64/libutil.so.1 (0x00000030ee800000)
libm.so.6 => /lib64/libm.so.6 (0x00000030e0600000)
libc.so.6 => /lib64/libc.so.6 (0x00000030e0200000)
/lib64/ld-linux-x86-64.so.2 (0x00000030dfe00000)
$ ldd `which python` | grep readline
$
Run Code Online (Sandbox Code Playgroud)
没有找到关于readline的内容.现在我从交互式使用中知道这个二进制文件确实具有实际功能,所以不要试图看看它来自何处.
$ python &
[1] 21003
$ Python …
Run Code Online (Sandbox Code Playgroud) 在ldd
文件上执行时,它会在它找到的每个库的括号中返回一个十六进制数.
例如:
root@server> ldd wpa_supplicant
linux-gate.so.1 => (0xb779b000)
libnl.so.1 => /usr/lib/libnl.so.1 (0xb774d000)
libssl.so.1.0.0 => not found
libcrypto.so.1.0.0 => not found
libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7748000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb75ed000)
libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb75c7000)
/lib/ld-linux.so.2 (0xb779c000)
Run Code Online (Sandbox Code Playgroud)
如果十六进制数不是可执行文件被链接的库之一,则可能发生版本信息错误.
我有两个问题:
有谁知道之前将执行哪个 LLVM IR 代码的一般规则main
?
使用 Clang++ 3.6 时,似乎全局类变量的构造函数通过对象文件的“.text.startup”部分中的函数调用。例如:
define internal void @__cxx_global_var_init() section ".text.startup" {
call void @_ZN7MyClassC2Ev(%class.MyClass* @M)
ret void
}
Run Code Online (Sandbox Code Playgroud)
从这个例子中,我猜我应该寻找那些指定section ".text.startup"
.
我有两个理由怀疑我的理论是正确的:
我在我的 LLVM IR 文件中没有看到任何其他内容(.ll)
如果我们假设 LLVM 没有嗅探 C++ 特定的函数名称,例如“__cxx_global_var_init”,那么建议首先运行全局对象构造函数。所以section ".text.startup"
是唯一明显的方法说代码应该在 之前运行main()
。但即使这是正确的,我们已经确定了导致函数在之前运行的充分条件main()
,但没有表明这是 LLVM IR 中导致函数在 之前运行的唯一方法main()
。
在某些情况下,Gnu 链接器将使用段中的第一条指令.text
作为程序入口点。 这篇关于 Raspberry Pi 编程的文章描述了使.text.startup
内容成为程序.text
部分中出现的第一个代码体,作为使.text.startup
代码首先运行的一种方式。
不幸的是,我没有找到太多其他东西来支持我的理论:
当我为字符串“.startup”grep LLVM 3.6 源代码时,我只能在 LLVM 代码的 …
我无法弄清楚为什么我的二进制文件无法加载。它是MATLAB加载的dylib(MEX文件),并链接到位于不同位置的许多dylib。MATLAB告诉我它无法加载MEX文件,但是我无法弄清它找不到哪个依赖项。
有人对如何调试这样的东西有任何建议吗?
在Linux上,ldd
是调试此问题的理想工具。人们一直说otool -L
MacOS与Linux等效ldd
,但这不是事实。ldd
实际上会查找这些库,并告诉您可以找到哪些库以及在何处找到它们。otool -L
仅告诉您需要链接的库。无需检查它们是否存在。它甚至没有告诉您使用库时在哪里搜索库@rpath
。
otool -l
(小写的L)为您提供了“加载命令”的转储,您可以在LC_RPATH
其中看到这些命令,这些命令确定了在何处@rpath
搜索库。但是这些无法向我解释未找到哪个依赖项。
希望这不是重复的(我发现了很多类似的问题,但不完全是我要问的问题)。
\n\n当我运行时在linux上ldd <path/to/executable>
,我会得到一个很好的共享库依赖项列表,以及动态链接器找到这些依赖项的路径(或者一条未找到依赖项的消息)。
在mac上使用时otool -L <path/to/executable>
我得到依赖项,并且路径是相对于 rpath 的,即使依赖项不存在。本质上,它报告依赖关系应该相对于 rpath 的位置,而不是动态链接器发现的位置。据我了解,otool 直接从二进制文件中读取此信息,而不是像 ldd 那样调用链接器。
我知道我可以通过将 DYLD_PRINT_LIBRARIES 变量设置为 1 来运行可执行文件来获取这些路径,但这对于动态库不起作用,甚至对于可执行文件也不方便。
\n\n所以我的问题是,我可以在 mac 中获得与 ldd 完全相同的行为吗?
\n\no工具信息:
\n\n\xe2\x9e\x9c otool --version\nllvm-otool(1): Apple Inc. version cctools-906\nApple LLVM version 9.1.0 (clang-902.0.39.1)\n Optimized build.\n Default target: x86_64-apple-darwin17.5.0\n Host CPU: ivybridge\n
Run Code Online (Sandbox Code Playgroud)\n 考虑这个 AMD64 汇编程序:
.globl _start
_start:
xorl %edi, %edi
movl $60, %eax
syscall
Run Code Online (Sandbox Code Playgroud)
如果我编译gcc -nostdlib
并运行ldd a.out
,我得到这个:
statically linked
Run Code Online (Sandbox Code Playgroud)
如果我改为使用gcc -static -nostdlib
并运行编译它ldd a.out
,我会得到这个:
not a dynamic executable
Run Code Online (Sandbox Code Playgroud)
什么之间的区别statically linked
和not a dynamic executable
?如果我的二进制文件已经静态链接,为什么添加-static
会影响任何事情?
我正在尝试在现代 GNU/Linux 发行版(Gentoo Linux)上运行一个在 CentOS 6 上编译的旧 C++ 程序。现在CentOS 6和建议的库都已经过时,因此有必要为二进制文件提供工作环境。
我已经尝试使用命令ldd
和一些脚本从 CentOS 6 复制二进制文件所需的所有必需的共享库。现在我有一个包含所有必需库的目录。但是,当我尝试使用 LD_LIBRARY_PATH="带有 .so 文件的目录"运行程序时,终端显示一条消息
$ LD_LIBRARY_PATH=`pwd`/lib ./my-program
Inconsistency detected by ld.so: dl-call-libc-early-init.c: 37: _dl_call_libc_early_init: Assertion `sym != NULL' failed!
Run Code Online (Sandbox Code Playgroud)
所以它出于某种原因不想工作。如果没有强制链接到旧的 .so,二进制文件也不会运行(显然)。我没有时间在现代 Linux 上重新编译我的程序或制作它的静态版本,因为它需要旧的库,并且该程序必须在我不维护的几台 PC 上运行。
有没有一种可靠的方法可以在没有容器或虚拟机的情况下在现代 Linux 上运行旧的二进制文件?也许我走在正确的道路上,但需要解决一些问题,或者我走在错误的道路上,需要尝试其他事情。
如果您阅读到此行,感谢您的关注!
我附上所需库的列表( 的输出ldd my-program
):
linux-vdso.so.1 => (0x00007ffc26b40000)
librfftw.so.2 => /usr/lib64/librfftw.so.2 (0x00007f026f631000)
libfftw.so.2 => /usr/lib64/libfftw.so.2 (0x00007f026f3f8000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f026f1f4000)
libboost_thread-mt.so.5 => /usr/lib64/libboost_thread-mt.so.5 (0x00007f026efdf000)
libboost_system-mt.so.5 => /usr/lib64/libboost_system-mt.so.5 (0x00007f026eddc000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f026ebbf000)
libxml++-2.6.so.2 => /usr/lib64/libxml++-2.6.so.2 (0x00007f026e99c000) …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 docker 和 qemu 在我的 x86 主机上构建arm镜像
我使用arm64v8/ubuntu作为基础镜像
我制作了一个简单的 opencv 程序并尝试使用 ldd 命令来查看依赖关系。
然而,ldd总是显示:
ldd:退出,退出代码未知 (132)
如果我保存此图像并将其加载到 Arm 计算机中,ldd 就会起作用。
但是,我的主项目太大(或者我的arm计算机空间太小),无法导入到arm计算机,我想使用ldd来找出该项目真正需要哪些库。
我还尝试 nvcr.io/nvidia/l4t-base:r32.4.4 作为基础图像和 ldd 显示
ldd:退出,退出代码未知 (139)
如果我在 docker 中的 arm 镜像中并且我的主机是 x86,我应该怎么做才能使用 ldd 命令?
我的 dockerfile 是这样的:
FROM arm64v8/ubuntu
ENV TZ=Asia/Taipei
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt-get install -y \
build-essential -y \
cmake -y \
git -y \
libgtk2.0-dev -y \
libjpeg-dev -y \
libpng-dev -y \
libtiff-dev …
Run Code Online (Sandbox Code Playgroud)