Skip to content

11.3 Ubuntu/Debian 兼容层

本节基于 debootstrap 在 FreeBSD 上构建 Ubuntu 22.04 LTS 兼容层,并附 Debian 12 构建脚本。内容包括 X11 应用运行以及与 systemd、Wine 相关的故障排除。

注意

由于 FreeBSD Ports 中的 sysutils/debootstrap 长期未更新,经测试,该工具目前尚不支持 Ubuntu 24.04 和 Debian 13 的基本系统引导。

视频教程:06-FreeBSD-Ubuntu 兼容层脚本使用说明

11.3.1 Ubuntu 兼容层

Ubuntu 兼容层

以下教程在 FreeBSD 14.3-RELEASE 上测试通过。

此外,可采用类似方法构建 Debian 兼容层。其他系统的支持情况请参见 /usr/local/share/debootstrap/scripts/ 目录。

11.3.1.1 开始构建 Ubuntu 兼容层(基于 Ubuntu 22.04 LTS)

构建前,需启用相关守护进程和服务:

sh
# service linux enable   # 启用 Linux 兼容层服务,并设置为开机自启
# service linux start    # 启动 Linux 兼容层服务
# service dbus enable    # 启用 D-Bus 服务,并设置为开机自启;通常桌面已经配置
# service dbus start     # 启动 D-Bus 服务。通常桌面已经配置

构建 Ubuntu 22.04 LTS 基本系统:

sh
# pkg install debootstrap                                   # 安装 debootstrap 工具
# debootstrap jammy /compat/ubuntu http://mirrors.ustc.edu.cn/ubuntu/   # 使用 debootstrap 安装 Ubuntu Jammy 到 /compat/ubuntu

11.3.1.2 挂载文件系统

构建完成后,需要挂载必要的文件系统。

nullfs_load="YES" 写入 /boot/loader.conf 文件。

将以下行写入 /etc/fstab 文件:

ini
# Device        Mountpoint              FStype          Options                      Dump    Pass#
devfs           /compat/ubuntu/dev      devfs           rw,late                      0       0
tmpfs           /compat/ubuntu/dev/shm  tmpfs           rw,late,size=1g,mode=1777    0       0
fdescfs         /compat/ubuntu/dev/fd   fdescfs         rw,late,linrdlnk             0       0
linprocfs       /compat/ubuntu/proc     linprocfs       rw,late                      0       0
linsysfs        /compat/ubuntu/sys      linsysfs        rw,late                      0       0
/tmp            /compat/ubuntu/tmp      nullfs          rw,late                      0       0
#/home           /compat/ubuntu/home     nullfs          rw,late                      0       0

检查挂载有无报错。挂载所有在 /etc/fstab 文件中标记为自动挂载的文件系统:

sh
# mount -al

在 Ubuntu 兼容环境中创建 home 目录:

sh
# mkdir /compat/ubuntu/home

重启系统:

sh
# reboot

11.3.1.3 设置 Linux 内核版本

需要设定合适的 Linux 内核版本,否则 chroot 时可能会提示 FATAL: kernel too old

6.16.2 仅为示例,建议参考 The Linux Kernel Archives 中公布的版本号设置。

sh
# echo "compat.linux.osrelease=6.16.2" >> /etc/sysctl.conf   # 将 Linux 兼容层内核版本写入 sysctl 配置文件,使其永久生效
# sysctl compat.linux.osrelease=6.16.2                      # 立即设置 Linux 兼容层内核版本,便于当前会话继续使用

11.3.1.4 进入 Ubuntu 兼容层

完成文件系统挂载和内核版本设定后,进入 Ubuntu 兼容层继续配置。

chroot 进入 Ubuntu 兼容环境,移除会导致报错的软件:

bash
# chroot /compat/ubuntu /bin/bash	# 进入 /compat/ubuntu 目录对应的 Linux 兼容环境,并启动 Bash Shell
# apt remove rsyslog # 此时已位于 Ubuntu 兼容层,卸载 rsyslog 软件包

11.3.1.5 Ubuntu 切换软件源

更换 Ubuntu 兼容层的软件源可提高下载速度。

在卸载 rsyslog 之后需要更换软件源;由于 SSL 证书尚未更新,暂时无法使用 HTTPS 源。

使用文本编辑器编辑 Ubuntu 兼容环境中的 APT 软件源配置文件 /compat/ubuntu/etc/apt/sources.list,写入软件源:

ini
deb http://mirrors.ustc.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse

进入 Ubuntu 兼容层,开始更新系统,安装常用软件:

bash
# export LANG=C # 设定字符集,防止出现错误
# apt update && apt upgrade && apt install nano wget fonts-wqy-microhei fonts-wqy-zenhei language-pack-zh-hans # 此时已经位于 Ubuntu 兼容层了。
# update-locale LC_ALL=zh_CN.UTF-8 LANG=zh_CN.UTF-8 # 设置中文字符集

11.3.2 附录:Ubuntu 兼容层脚本(基于 Ubuntu 22.04 LTS,FreeBSD 14.3-RELEASE 测试通过)

脚本内容如下:

sh
#!/bin/sh                                             # 使用 /bin/sh 作为脚本解释程序

rootdir=/compat/ubuntu                                # 定义 Ubuntu 根目录路径
baseurl="https://mirrors.ustc.edu.cn/ubuntu/"         # 定义 Ubuntu 软件源基础地址
codename=jammy                                        # 定义 Ubuntu 发行版代号(22.04)

echo "Starting Ubuntu jammy (22.04 LTS) installation..."                    # 输出开始安装提示
echo "check modules ..."                              # 输出模块检查提示

# check linux module                                  # 检查 Linux 兼容层模块
if [ "$(sysrc -n linux_enable)" = "NO" ]; then        # 判断 linux 兼容层是否未启用
        echo "linux module should be loaded. Continue? (N|y)"  # 提示是否继续
        read answer                                  # 读取用户输入
        case $answer in                              # 根据用户输入进行分支判断
                [Nn][Oo]|[Nn])                        # 用户选择否
                        echo "linux module not loaded" # 输出提示信息
                        exit 1                       # 退出脚本并返回错误码 1
                        ;;
                *)                                   # 其他情况,视为同意
                        sysrc linux_enable=YES       # 启用 linux 兼容层并写入 rc.conf 文件
                        ;;
        esac                                         # case 语句结束
fi                                                    # if 判断结束
echo "start linux"                                   # 输出启动 linux 服务提示
service linux start                                  # 启动 linux 兼容层服务

# check dbus                                         # 检查 dbus 服务
if ! /usr/bin/which -s dbus-daemon;then               # 判断 dbus-daemon 是否存在
        echo "dbus-daemon not found. Install it [N|y]"# 提示是否安装 dbus
        read  answer                                 # 读取用户输入
        case $answer in                              # 根据用户输入进行分支判断
            [Nn][Oo]|[Nn])                            # 用户选择否
                echo "dbus not installed"             # 输出提示信息
                exit 2                               # 退出脚本并返回错误码 2
                ;;
            *)                                       # 其他情况,视为同意
                pkg install -y dbus                  # 使用 pkg 安装 dbus
                ;;
        esac                                         # case 语句结束
    fi                                                # if 判断结束

if [ "$(sysrc -n dbus_enable)" != "YES" ]; then       # 判断 dbus 是否未设置为启用
        echo "dbus should be enabled. Continue? (N|y)"# 提示是否继续
        read answer                                  # 读取用户输入
        case $answer in                              # 根据用户输入进行分支判断
            [Nn][Oo]|[Nn])                            # 用户选择否
                        echo "dbus not running"      # 输出提示信息
                        exit 2                       # 退出脚本并返回错误码 2
                        ;;
            *)                                       # 其他情况,视为同意
                        service dbus enable          # 启用 dbus 服务
                        ;;
        esac                                         # case 语句结束
fi                                                    # if 判断结束
echo "start dbus"                                    # 输出启动 dbus 提示
service dbus start                                   # 启动 dbus 服务

echo "Now I should change 'compat.linux.osrelease'. Continue? (Y|n)" # 提示修改内核版本
read answer                                          # 读取用户输入
case $answer in                                      # 根据用户输入进行分支判断
	[Nn][Oo]|[Nn])                                    # 用户选择否
		echo "close to success"                       # 输出提示信息
		exit 4                                       # 退出脚本并返回错误码 4
		;;
	[Yy][Ee][Ss]|[Yy]|"")                            # 用户选择
		echo "compat.linux.osrelease=6.16.2" >> /etc/sysctl.conf  # 写入 sysctl 配置文件
		sysctl compat.linux.osrelease=6.16.2          # 立即设置 linux 兼容层内核版本
                ;;
esac                                                 # case 语句结束

if ! /usr/bin/which -s debootstrap; then              # 判断 debootstrap 是否存在
        echo "debootstrap not found. Install it? (N|y)" # 提示是否安装 debootstrap
        read  answer                                 # 读取用户输入
        case $answer in                              # 根据用户输入进行分支判断
            [Nn][Oo]|[Nn])                            # 用户选择否
                echo "debootstrap not installed"     # 输出提示信息
                exit 3                               # 退出脚本并返回错误码 3
                ;;
            *)                                       # 其他情况,视为同意
                pkg install -y debootstrap           # 使用 pkg 安装 debootstrap
                ;;
        esac                                         # case 语句结束
    fi                                                # if 判断结束
echo "Now we will bootstrap ${codename}. Press any key." # 提示开始 bootstrap
read  answer                                         # 等待用户确认

debootstrap ${codename} ${rootdir} ${baseurl}         # 使用 debootstrap 安装 Ubuntu 系统

if [ ! "$(sysrc -f /boot/loader.conf -qn nullfs_load)" = "YES" ]; then # 检查 nullfs 是否配置加载
        echo "nullfs_load should load. Continue? (N|y)" # 提示是否继续
        read answer                                  # 读取用户输入
        case $answer in                              # 根据用户输入进行分支判断
            [Nn][Oo]|[Nn])                            # 用户选择否
                echo "nullfs is not loaded"               # 输出提示信息
				exit 4                               # 退出脚本并返回错误码 4
                ;;
            *)                                       # 其他情况,视为同意
                sysrc -f /boot/loader.conf nullfs_load=yes # 设置 nullfs 启动加载
                ;;
        esac                                         # case 语句结束
    fi                                                # if 判断结束

if ! kldstat -n nullfs >/dev/null 2>&1;then           # 判断 nullfs 模块是否已加载
        echo "load nullfs module"                     # 输出加载提示
        kldload -v nullfs                             # 加载 nullfs 内核模块
fi                                                    # if 判断结束

echo "mount some fs for linux"                        # 输出挂载文件系统提示
echo "devfs ${rootdir}/dev devfs rw,late 0 0" >> /etc/fstab      # 挂载 devfs
echo "tmpfs ${rootdir}/dev/shm tmpfs rw,late,size=1g,mode=1777 0 0" >> /etc/fstab # 挂载 tmpfs
echo "fdescfs ${rootdir}/dev/fd fdescfs rw,late,linrdlnk 0 0" >> /etc/fstab        # 挂载 fdescfs
echo "linprocfs ${rootdir}/proc linprocfs rw,late 0 0" >> /etc/fstab               # 挂载 linprocfs
echo "linsysfs ${rootdir}/sys linsysfs rw,late 0 0" >> /etc/fstab                  # 挂载 linsysfs
echo "/tmp ${rootdir}/tmp nullfs rw,late 0 0" >> /etc/fstab                        # 绑定 /tmp
echo "/home ${rootdir}/home nullfs rw,late 0 0" >> /etc/fstab                      # 绑定 /home
mount -al                                         # 挂载所有自动挂载的文件系统

echo "add ustc apt sources"                        # 输出添加 APT 源提示
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ jammy main restricted universe multiverse" > /compat/ubuntu/etc/apt/sources.list      # 写入主仓库源
echo "deb-src http://mirrors.ustc.edu.cn/ubuntu/ jammy main restricted universe multiverse" >> /compat/ubuntu/etc/apt/sources.list # 写入源代码仓库
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ jammy-security main restricted universe multiverse" >> /compat/ubuntu/etc/apt/sources.list # 写入安全更新源
echo "deb-src http://mirrors.ustc.edu.cn/ubuntu/ jammy-security main restricted universe multiverse" >> /compat/ubuntu/etc/apt/sources.list # 写入安全源代码源
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse" >> /compat/ubuntu/etc/apt/sources.list # 写入更新源
echo "deb-src http://mirrors.ustc.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse" >> /compat/ubuntu/etc/apt/sources.list # 写入更新源代码源
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse" >> /compat/ubuntu/etc/apt/sources.list # 写入回溯源
echo "deb-src http://mirrors.ustc.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse" >> /compat/ubuntu/etc/apt/sources.list # 写入回溯源代码源

echo "remove rsyslog and install nano fonts-wqy-microhei fonts-wqy-zenhei language-pack-zh-hans and wget" # 输出软件安装提示
chroot ${rootdir} /bin/bash -c "apt remove rsyslog && apt update && apt upgrade && apt install nano wget fonts-wqy-microhei fonts-wqy-zenhei language-pack-zh-hans" # 在 Ubuntu 环境中执行软件管理命令
chroot ${rootdir} /bin/bash -c "update-locale LC_ALL=zh_CN.UTF-8 LANG=zh_CN.UTF-8" # 设置中文 UTF-8 语言环境
echo "Now you can run '#chroot /compat/ubuntu/ /bin/bash' to enter Ubuntu 22.04 LTS"   # 输出完成提示

11.3.3 附录:Debian 12(bookworm)(FreeBSD 14.2-RELEASE 测试通过)

脚本内容如下:

sh
#!/bin/sh                                             # 使用 /bin/sh 作为脚本解释程序

rootdir=/compat/debian                                # 定义 Debian 根目录路径
baseurl="https://mirrors.ustc.edu.cn/debian/"        # 定义 Debian 软件源基础地址
codename=bookworm                                     # 定义 Debian 发行版代号(12)

echo "Starting Debian 12 AKA bookworm installation..."    # 输出开始安装提示
echo "check modules ..."                              # 输出模块检查提示

# check linux module                                  # 检查 Linux 兼容层模块
if [ "$(sysrc -n linux_enable)" = "NO" ]; then        # 判断 linux 兼容层是否未启用
        echo "linux module should be loaded. Continue? (N|y)"  # 提示是否继续
        read answer                                  # 读取用户输入
        case $answer in                              # 根据用户输入进行分支判断
                [Nn][Oo]|[Nn])                        # 用户选择否
                        echo "linux module not loaded" # 输出提示信息
                        exit 1                       # 退出脚本并返回错误码 1
                        ;;
                *)                                   # 其他情况,视为同意
                        sysrc linux_enable=YES       # 启用 linux 兼容层并写入 rc.conf 文件
                        ;;
        esac                                         # case 语句结束
fi                                                    # if 判断结束
echo "start linux"                                   # 输出启动 linux 服务提示
service linux start                                  # 启动 linux 兼容层服务

# check dbus                                         # 检查 dbus 服务
if ! /usr/bin/which -s dbus-daemon;then               # 判断 dbus-daemon 是否存在
        echo "dbus-daemon not found. Install it [N|y]"# 提示是否安装 dbus
        read  answer                                 # 读取用户输入
        case $answer in                              # 根据用户输入进行分支判断
            [Nn][Oo]|[Nn])                            # 用户选择否
                echo "dbus not installed"             # 输出提示信息
                exit 2                               # 退出脚本并返回错误码 2
                ;;
            *)                                       # 其他情况,视为同意
                pkg install -y dbus                  # 使用 pkg 安装 dbus
                ;;
        esac                                         # case 语句结束
    fi                                                # if 判断结束

if [ "$(sysrc -n dbus_enable)" != "YES" ]; then       # 判断 dbus 是否未设置为启用
        echo "dbus should be enabled. Continue? (N|y)"# 提示是否继续
        read answer                                  # 读取用户输入
        case $answer in                              # 根据用户输入进行分支判断
            [Nn][Oo]|[Nn])                            # 用户选择否
                        echo "dbus not running"      # 输出提示信息
                        exit 2                       # 退出脚本并返回错误码 2
                        ;;
            *)                                       # 其他情况,视为同意
                        service dbus enable          # 启用 dbus 服务
                        ;;
        esac                                         # case 语句结束
fi                                                    # if 判断结束
echo "start dbus"                                    # 输出启动 dbus 提示
service dbus start                                   # 启动 dbus 服务

if ! /usr/bin/which -s debootstrap; then              # 判断 debootstrap 是否存在
        echo "debootstrap not found. Install it? (N|y)" # 提示是否安装 debootstrap
        read  answer                                 # 读取用户输入
        case $answer in                              # 根据用户输入进行分支判断
            [Nn][Oo]|[Nn])                            # 用户选择否
                echo "debootstrap not installed"      # 输出提示信息
                exit 3                               # 退出脚本并返回错误码 3
                ;;
            *)                                       # 其他情况,视为同意
                pkg install -y debootstrap           # 使用 pkg 安装 debootstrap
                ;;
        esac                                         # case 语句结束
    fi                                                # if 判断结束
echo "Now we will bootstrap ${codename}. Press any key." # 提示开始 bootstrap
read  answer                                         # 等待用户确认

debootstrap ${codename} ${rootdir} ${baseurl}        # 使用 debootstrap 安装 Debian 系统

if [ ! "$(sysrc -f /boot/loader.conf -qn nullfs_load)" = "YES" ]; then # 检查 nullfs 是否配置加载
        echo "nullfs_load should load. Continue? (N|y)" # 提示是否继续
        read answer                                  # 读取用户输入
        case $answer in                              # 根据用户输入进行分支判断
            [Nn][Oo]|[Nn])                            # 用户选择否
                echo "nullfs is not loaded"               # 输出提示信息
				exit 4                               # 退出脚本并返回错误码 4
                ;;
            *)                                       # 其他情况,视为同意
                sysrc -f /boot/loader.conf nullfs_load=yes # 设置 nullfs 启动加载
                ;;
        esac                                         # case 语句结束
    fi                                                # if 判断结束

if ! kldstat -n nullfs >/dev/null 2>&1;then           # 判断 nullfs 模块是否已加载
        echo "load nullfs module"                     # 输出加载提示
        kldload -v nullfs                             # 加载 nullfs 内核模块
fi                                                    # if 判断结束

echo "mount some fs for linux"                        # 输出挂载文件系统提示
echo "devfs ${rootdir}/dev devfs rw,late 0 0" >> /etc/fstab      # 挂载 devfs
echo "tmpfs ${rootdir}/dev/shm tmpfs rw,late,size=1g,mode=1777 0 0" >> /etc/fstab # 挂载 tmpfs
echo "fdescfs ${rootdir}/dev/fd fdescfs rw,late,linrdlnk 0 0" >> /etc/fstab        # 挂载 fdescfs
echo "linprocfs ${rootdir}/proc linprocfs rw,late 0 0" >> /etc/fstab               # 挂载 linprocfs
echo "linsysfs ${rootdir}/sys linsysfs rw,late 0 0" >> /etc/fstab                  # 挂载 linsysfs
echo "/tmp ${rootdir}/tmp nullfs rw,late 0 0" >> /etc/fstab                        # 绑定 /tmp
#echo "/home ${rootdir}/home nullfs rw,late 0 0" >> /etc/fstab                     # 绑定 /home(已注释掉)
mount -al                                         # 挂载所有自动挂载的文件系统

echo "Now I should change 'compat.linux.osrelease'. Continue? (Y|n)" # 提示修改内核版本
read answer                                          # 读取用户输入
case $answer in                                      # 根据用户输入进行分支判断
	[Nn][Oo]|[Nn])                                    # 用户选择否
		echo "close to success"                       # 输出提示信息
		exit 4                                       # 退出脚本并返回错误码 4
		;;
	[Yy][Ee][Ss]|[Yy]|"")                            # 用户选择
		echo "compat.linux.osrelease=6.16.2" >> /etc/sysctl.conf  # 写入 sysctl 配置文件
		sysctl compat.linux.osrelease=6.16.2          # 立即设置 linux 兼容层内核版本
                ;;
esac                                                 # case 语句结束

echo "add ustc apt sources"                        # 输出添加 APT 源提示
echo "deb http://mirrors.ustc.edu.cn/debian stable main contrib non-free non-free-firmware" > /compat/debian/etc/apt/sources.list      # 写入主仓库源
echo "# deb-src http://mirrors.ustc.edu.cn/debian stable main contrib non-free non-free-firmware" >> /compat/debian/etc/apt/sources.list # 写入源代码仓库
echo "deb http://mirrors.ustc.edu.cn/debian stable-updates main contrib non-free non-free-firmware" >> /compat/debian/etc/apt/sources.list # 写入更新源
echo "# deb-src http://mirrors.ustc.edu.cn/debian stable-updates main contrib non-free non-free-firmware" >> /compat/debian/etc/apt/sources.list # 写入更新源代码
echo "# deb http://mirrors.ustc.edu.cn/debian stable-proposed-updates main contrib non-free non-free-firmware" >> /compat/debian/etc/apt/sources.list # 写入预发布源
echo "# deb-src http://mirrors.ustc.edu.cn/debian stable-proposed-updates main contrib non-free non-free-firmware" >> /compat/debian/etc/apt/sources.list # 写入预发布源代码
echo "deb http://mirrors.ustc.edu.cn/debian-security/ stable-security main non-free contrib" >> /compat/debian/etc/apt/sources.list # 写入安全更新源
echo "# deb-src http://mirrors.ustc.edu.cn/debian-security/ stable-security main non-free contrib" >> /compat/debian/etc/apt/sources.list # 写入安全源代码

echo "install nano fonts-wqy-microhei fonts-wqy-zenhei and wget" # 输出软件安装提示
chroot ${rootdir} /bin/bash -c "apt update && apt --fix-broken install -y && apt upgrade && apt install nano wget fonts-wqy-microhei fonts-wqy-zenhei -y" # 在 Debian 环境中执行软件管理命令
chroot ${rootdir} /bin/bash -c "update-locale LC_ALL=zh_CN.UTF-8 LANG=zh_CN.UTF-8" # 设置中文 UTF-8 语言环境
echo "Now you can run '#chroot /compat/debian/ /bin/bash' to enter Debian 12 bookworm"   # 输出完成提示

11.3.4 附录:运行 X11 软件

允许所有本地用户访问当前 X Server 实例:

sh
# xhost +local:	# 此时处于 FreeBSD 系统

11.3.5 故障排除与未竟事宜

11.3.5.1 程序的命令行启动命令是什么?

按以下方法依次查找(以 gedit 为例):

  • 直接执行软件包名 # gedit
  • whereis 软件包名,定位后执行。whereis gedit
  • 通过软件图标定位,进入 /usr/share/applications 目录,根据软件包名找到对应文件,并使用文本编辑器(如 ee、nano)打开(.desktop 文件 是文本文件,而非软链接或图片),找到其中的程序启动命令并复制到终端运行即可。
  • 通过 find 命令全局查找(如 # find / -name gedit)。

如何查找软件?

bash
# apt search --names-only XXX # 按名称搜索包含 XXX 的软件包

将 XXX 改为所需搜索的软件名即可。

11.3.5.2 缺少 .so 文件

  • 首先查看缺少哪些 .so 文件,通常不会只缺失一个。
sh
# ldd /usr/bin/qq	# 查看可执行文件 qq 所依赖的动态链接库
	linux_vdso.so.1 (0x00007ffffffff000)
	libffmpeg.so => not found
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x0000000801061000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x0000000801066000)
	…………………………以下省略……………………………………

根据输出 libffmpeg.so => not found,判断缺失“libffmpeg.so”。

  • 安装工具
bash
# apt install apt-file   # 安装 apt-file 工具,用于查询文件所属的软件包
# apt-file update        # 更新 apt-file 的软件包索引数据库
  • 查看 libffmpeg.so 文件属于哪个包:
bash
# apt-file search libffmpeg.so	# 查询包含 libffmpeg.so 文件的软件包
qmmp: /usr/lib/qmmp/plugins/Input/libffmpeg.so
webcamoid-plugins: /usr/lib/x86_64-linux-gnu/avkys/submodules/MultiSink/libffmpeg.so
webcamoid-plugins: /usr/lib/x86_64-linux-gnu/avkys/submodules/MultiSrc/libffmpeg.so
webcamoid-plugins: /usr/lib/x86_64-linux-gnu/avkys/submodules/VideoCapture/libffmpeg.so

多个包都提供了该文件,任选一个安装即可。

bash
# apt install webcamoid-plugins	# 安装 Webcamoid 的插件组件
  • 按照上述路径复制文件,并刷新 ldd 缓存:
sh
# cp /usr/lib/x86_64-linux-gnu/avkys/submodules/MultiSink/libffmpeg.so /usr/lib   # 将 libffmpeg.so 文件复制到系统库目录
# ldconfig                                                                     # 重新生成动态链接库缓存
  • 再次查看可执行文件 /usr/bin/qq 所依赖的动态链接库:
sh
# ldd /usr/bin/qq
	linux_vdso.so.1 (0x00007ffffffff000)
	libffmpeg.so => /lib/libffmpeg.so (0x0000000801063000)
	…………………………以下省略……………………………………

11.3.6 参考文献