文章目录
前言
提示:这里可以添加本文要记录的大概内容:
打包可执行文件或者共享库的时候需要将其依赖的共享库一并打包,在 Linux 系统里,使用ldd(list dynamic dependencies)命令查看所依赖的共享库
仅查看还是不够的,还需要将ldd列出的共享库拷贝出来打包出去,制作一个脚本执行即可
一、查看依赖
在Linux系统里,ldd
(list dynamic dependencies)命令主要用于列出一个可执行文件或者共享库所依赖的共享库。下面为你详细介绍该命令:
1、基本语法
ldd [选项] 文件
这里的“文件”可以是可执行文件,也可以是共享库文件。
2、常用选项
-v
:显示详细的版本信息和符号依赖。-u
:显示未使用的直接依赖。-d
:执行重定位并报告任何丢失的对象。-r
:执行数据对象和函数的重定位,并报告任何丢失的对象和函数。
3、常用场景及示例
查看可执行文件依赖的共享库
假设你要查看/bin/ls
命令所依赖的共享库,只需执行以下命令:
ldd /bin/ls
执行后,输出结果类似如下:
linux-vdso.so.1 (0x00007ffe8a7d0000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f687d3d4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f687d1f2000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f687d163000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f687d15d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f687d407000)
每行输出都代表一个依赖的共享库,包含库的名称和它的加载路径。如果某行中只有库名而没有路径(如linux-vdso.so.1
),这表明它是虚拟动态共享对象,在运行时由内核提供。
查看共享库的依赖关系
若要查看某个共享库(如libssl.so
)所依赖的其他共享库,可执行以下命令:
ldd /usr/lib/x86_64-linux-gnu/libssl.so
显示详细的版本信息和符号依赖
使用-v
选项能显示详细的版本信息和符号依赖:
ldd -v /bin/ls
查找未使用的直接依赖
利用-u
选项可以找出未使用的直接依赖:
ldd -u /bin/ls
4、用途和注意事项
用途
- 调试问题:当执行某个程序时出现错误,你可以用
ldd
命令查看它所依赖的共享库是否存在或者是否版本兼容,从而找出问题所在。 - 移植程序:在把程序移植到其他系统时,借助
ldd
命令能知道程序依赖哪些共享库,这样就能确保目标系统也有这些库。
注意事项
ldd
命令实际上是通过运行程序并在其启动时进行探测来工作的,所以如果程序本身有问题(例如权限不足、文件损坏等),可能无法得到准确的结果。- 某些特殊的程序(如静态链接的程序)没有动态依赖,使用
ldd
命令查看时可能只会显示not a dynamic executable
。
二、拷贝依赖
1、自动化脚本
代码如下(示例):
#!/bin/bash
# 定义要查看依赖的程序路径
PROGRAM_PATH="/path/to/your/program"
# 定义要拷贝到的目标文件夹
TARGET_DIR="/path/to/target/directory"
# 创建目标文件夹(如果不存在)
mkdir -p "$TARGET_DIR"
# 使用 ldd 命令获取依赖库列表,并过滤出实际的库文件路径
DEPENDENCIES=$(ldd "$PROGRAM_PATH" | awk '{print $3}' | grep -v '^$')
# 遍历依赖库列表并拷贝到目标文件夹
for lib in $DEPENDENCIES; do
cp --parents "$lib" "$TARGET_DIR"
done
echo "依赖库已拷贝到 $TARGET_DIR"
2、使用方法
1、保存脚本:将上述脚本保存为一个文件,例如 copy_dependencies.sh。
2、赋予执行权限:在终端中执行以下命令赋予脚本执行权限:
chmod +x copy_dependencies.sh
3、运行脚本:在终端中执行以下命令运行脚本:
./copy_dependencies.sh
3、可能存在的问题
bash: ./copy_dependencies.sh:/bin/bash^M:解释器错误: 没有那个文件或目录
问题解释:
你遇到的这个错误 bash: ./copy.sh: /bin/bash^M: 解释器错误: 没有那个文件或目录 通常是由于文件的换行符格式问题导致的。在不同的操作系统中,换行符的表示方式有所不同:
Windows 系统使用回车符(Carriage Return, CR)和换行符(Line Feed, LF)组合 \r\n 来表示换行。
Linux 和 macOS 系统仅使用换行符 \n 来表示换行。
当你在 Windows 系统中编辑脚本文件,然后将其复制到 Linux 系统上运行时,文件中可能会保留 Windows 的换行符格式 \r\n,其中 \r(对应错误信息里的 ^M)会被当作命令解释器路径的一部分,从而导致系统找不到 /bin/bash^M 这个解释器。
解决办法
使用 sed 命令替换换行符
sed -i 's/\r$//' copy_dependencies.sh
检查验证
file copy_dependencies.sh
若输出显示为 ASCII text, with CRLF line terminators,说明文件仍为 Windows 格式,需要再次使用 dos2unix 或者 sed 命令进行转换。
如果 file 命令输出显示为 ASCII text,说明文件格式已经是 Unix 风格的文本格式了