DingTalk Fedora Packager#

把官方钉钉 Linux .deb 包重新打成 Fedora 可安装的 .rpm。

这个项目不是通用 deb -> rpm 转换器,只处理钉钉包,并固化了 Fedora 上实际踩到的兼容问题。

处理代码#

![[build_dingtalk_rpm.py]]

背景#

官方钉钉 Linux 包主要面向 Debian/Ubuntu 系发行版。直接原样转换成 RPM 后,在 Fedora 上会遇到几个典型问题:

  • 菜单入口执行 /opt/apps/com.alibabainc.dingtalk/files/Elevator.sh,它会走钉钉自带的预加载逻辑。
  • 包内旧版 libm.so.6 会遮住 Fedora 系统库,导致 GLIBC_2.38、GLIBC_2.43 等符号找不到。
  • dingtalk_dll.so、libconference_new.so 带有 executable stack 标记,Fedora 会拒绝加载。
  • RPM 如果声明拥有 /usr/bin、/usr/share/applications 这类系统目录,会和 filesystem 包冲突。

这里的处理思路参考了 zhullyb/dingtalk-for-fedora,并整理成一个可以直接处理本地 .deb 的脚本。

已验证版本#

本次实际处理并验证通过的钉钉版本:

com.alibabainc.dingtalk_8.1.0.6021101_amd64.deb

生成并验证通过的 Fedora RPM:

com.alibabainc.dingtalk-8.1.0.6021101-4.x86_64.rpm

验证环境为 Fedora 44 x86_64,glibc 2.43。其他钉钉版本可以用脚本尝试处理,但需要重新验证启动和会议等核心功能。

环境依赖#

构建依赖:

sudo dnf install python3-rpm rpm cpio xz patchelf binutils tar

运行依赖会写进生成的 RPM,安装时由 dnf 自动处理:

sudo dnf install mesa-libGLU libxcrypt-compat

通常不需要手动装运行依赖,直接 dnf install ./xxx.rpm 即可。

使用#

以下载目录中的官方包为例:

python3 scripts/build_dingtalk_rpm.py \
"/home/ian/下载/com.alibabainc.dingtalk_8.1.0.6021101_amd64.deb" \
--rpm-release 1

默认输出到 .deb 所在目录:

/home/ian/下载/com.alibabainc.dingtalk-8.1.0.6021101-1.x86_64.rpm

如果同版本需要重打,递增 --rpm-release:

python3 scripts/build_dingtalk_rpm.py \
"/home/ian/下载/com.alibabainc.dingtalk_8.1.0.6021101_amd64.deb" \
--rpm-release 2

指定输出目录:

python3 scripts/build_dingtalk_rpm.py ./com.alibabainc.dingtalk_8.1.0.6021101_amd64.deb \
--output-dir ./dist \
--rpm-release 1

保留工作目录便于排查:

python3 scripts/build_dingtalk_rpm.py ./com.alibabainc.dingtalk_8.1.0.6021101_amd64.deb \
--workdir ./work/build \
--keep-workdir

安装#

sudo dnf install "/home/ian/下载/com.alibabainc.dingtalk-8.1.0.6021101-1.x86_64.rpm"

同版本升级时不需要先卸载,直接安装更高 Release 的 RPM:

sudo dnf install "/home/ian/下载/com.alibabainc.dingtalk-8.1.0.6021101-2.x86_64.rpm"

安装后验证:

rpm -q com.alibabainc.dingtalk
command -v dingtalk
grep '^Exec=' /usr/share/applications/com.alibabainc.dingtalk.desktop
dingtalk

预期:

/usr/bin/dingtalk
Exec=dingtalk %u

不要直接执行:

/opt/apps/com.alibabainc.dingtalk/files/Elevator.sh

脚本处理流程#

scripts/build_dingtalk_rpm.py 的流程:

  1. 使用 ar 拆开官方 .deb。
  2. 使用 tar 解出 control.tar.* 和 data.tar.*。
  3. 校验 Debian 包名必须是 com.alibabainc.dingtalk,架构必须是 amd64。
  4. 定位 /opt/apps/com.alibabainc.dingtalk/files/*Release*。
  5. 删除 Fedora 上会冲突的自带库:
    • libm.so.6
    • libstdc++.so.6*
    • libcurl.so.4
    • libz.so*
    • libgtk-x11-2.0.so.*
  6. 删除无用或易冲突资源:
    • Resources/i18n/tool/*.exe
    • Resources/web_content/NativeWebContent_*.zip
    • Resources/qss/mac
  7. 设置 plugins/dtwebview/chrome-sandbox 为 4755。
  8. 新增 /usr/bin/dingtalk 启动器,不设置 LD_LIBRARY_PATH,不调用 Elevator.sh。
  9. 改写 desktop 文件为 Exec=dingtalk %u。
  10. 扫描所有 ELF 文件,用 patchelf --clear-execstack 清掉 executable stack 标记。
  11. 生成 cpio.xz payload。
  12. 写 RPM v4 header、签名摘要和文件清单。
  13. 自动执行:
    • rpm -Kv
    • rpm -Uvh --test --nodeps

常见问题#

GLIBC_2.38 not found / GLIBC_2.43 not found#

通常是钉钉自带的旧 libm.so.6 被加载了。确认菜单入口不是 Elevator.sh:

grep '^Exec=' /usr/share/applications/com.alibabainc.dingtalk.desktop

应为:

Exec=dingtalk %u

cannot enable executable stack#

说明某个 .so 还带 executable stack 标记。检查:

patchelf --print-execstack /opt/apps/com.alibabainc.dingtalk/files/*Release*/dingtalk_dll.so

应为:

execstack: -

/usr/bin conflicts with filesystem#

RPM 包不应该拥有 /usr/bin 目录本身,只应该包含 /usr/bin/dingtalk 文件。脚本默认会跳过这些系统父目录:

  • /usr
  • /usr/bin
  • /usr/share
  • /usr/share/applications

说明#

钉钉是专有软件。这个项目只提供本地重新打包脚本,不重新分发钉钉二进制文件。请从官方渠道获取 .deb。