机器人主控框架使用了QP状态机,QP状态机的图形化编辑器QM最新版本基于Qt6,Ubuntu 18.04不支持,升级系统风险太大,所以需要使用snapcraft打包二进制文件到目标系统上运行。

1. 安装snapcraft

sudo snap install snapcraft --classic
sudo snap install lxd
# 设置环境变量
export SNAPCRAFT_BUILD_ENVIRONMENT_CPU=8
export SNAPCRAFT_BUILD_ENVIRONMENT_MEMORY=16G
# 使用multipass
sudo snap set snapcraft provider=lxd

添加用户到lxd组

sudo usermod -aG lxd $USER

注销后重新登录,初始化lxd,选项选择默认选项即可

lxd init

2. 创建snapcraft.yaml

可以使用snapcraft init命令创建一个snapcraft.yaml文件,或者手动创建一个snapcraft.yaml文件,下面是我针对qm状态机编辑器做的一个配置:

name: qmcraft
version: '7.0.1'
summary: QM 应用
description: |
  QM snap package.
base: core22
grade: stable
confinement: classic

# assumes:
#   - snapd2.43
#   - command-chain

# plugs:
#   # 添加标准桌面应用所需插件
#   gnome-42-2204:
#     interface: content
#     target: $SNAP/gnome-platform
#     default-provider: gnome-42-2204
#   gtk-3-themes:
#     interface: content
#     target: $SNAP/data-dir/themes
#     default-provider: gtk-common-themes
#   icon-themes:
#     interface: content
#     target: $SNAP/data-dir/icons
#     default-provider: gtk-common-themes
#   sound-themes:
#     interface: content
#     target: $SNAP/data-dir/sounds
#     default-provider: gtk-common-themes

parts:
  qm-binary:
    plugin: dump
    source: ./qm
    # organize:
    #   "bin/*": bin/
    #   "Resources/*": Resources/
    #   "html/*": html/
    build-packages:
      - patchelf
    stage-packages:
      - libegl1
      - libgl1
      - libx11-6
      - libfontconfig1
      - libxkbcommon0
      - libxcb1
      - libxcb-cursor0
      - libxcb-icccm4
      - libxcb-image0
      - libxcb-keysyms1
      - libxcb-randr0
      - libxcb-render-util0
      - libxcb-render0
      - libxcb-shape0
      - libxcb-shm0
      - libxcb-sync1
      - libxcb-xfixes0
      - libxcb-xkb1
      - libxkbcommon-x11-0
      - libc6
      - libstdc++6
      - libpthread-stubs0-dev

    override-prime: |
      snapcraftctl prime

      # 修改 bin 目录权限为 755 (rwxr-xr-x)
      chmod -R 755 $SNAPCRAFT_PRIME/bin

      # 处理可执行文件:设置解释器和rpath
      for f in $SNAPCRAFT_PRIME/bin/qm $SNAPCRAFT_PRIME/bin/qmc; do
        if [ -f "$f" ]; then
          patchelf --set-interpreter /snap/core22/current/lib64/ld-linux-x86-64.so.2 \
                  --set-rpath '$ORIGIN:/snap/core22/current/lib/x86_64-linux-gnu:/snap/core22/current/usr/lib/x86_64-linux-gnu' \
                  "$f"
          # 确保不使用宿主机的 libpthread
          patchelf --replace-needed libpthread.so.0 /snap/core22/current/lib/x86_64-linux-gnu/libpthread.so.0 "$f"
        fi
      done
      
      # 处理共享库:只设置rpath,不设置解释器
      for f in $SNAPCRAFT_PRIME/bin/*.so* $SNAPCRAFT_PRIME/bin/platforms/libqxcb.so; do
        if [ -f "$f" ]; then
          patchelf --set-rpath '$ORIGIN:/snap/core22/current/lib/x86_64-linux-gnu:/snap/core22/current/usr/lib/x86_64-linux-gnu' "$f"
        fi
      done

apps:
  qm:
    command: bin/qm
    plugs:
      - home
      - network
      - desktop
      - x11
      - wayland
      - opengl
      # - gnome-42-2204
      # - gtk-3-themes
      # - icon-themes
      # - sound-themes
    # extensions:
    #   - gnome
    environment:
      LD_LIBRARY_PATH: $SNAP/usr/lib/x86_64-linux-gnu:$SNAP/bin:$SNAP/lib/x86_64-linux-gnu:/snap/core22/current/lib/x86_64-linux-gnu:/snap/core22/current/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH
      XDG_DATA_DIRS: $XDG_DATA_DIRS:$SNAP/share:$SNAP/usr/share
      
  qmc:
    command: bin/qmc
    plugs:
      - home
      - network
      - desktop
      - x11
      - wayland
      - opengl
      # - gnome-42-2204
      # - gtk-3-themes
      # - icon-themes
      # - sound-themes
    # extensions:
    #   - gnome
    environment:
      LD_LIBRARY_PATH: $SNAP/usr/lib/x86_64-linux-gnu:$SNAP/bin:$SNAP/lib/x86_64-linux-gnu:/snap/core22/current/lib/x86_64-linux-gnu:/snap/core22/current/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH
      XDG_DATA_DIRS: $XDG_DATA_DIRS:$SNAP/share:$SNAP/usr/share

3. 打包

snapcraft

打包完成后,生成的文件在当前目录下。

详细上手可参考我的qm_snapcraft仓库: qm_snapcraft

4. 安装

sudo snap install --classic --dangerous ./qmcraft_7.0.1_amd64.snap

5. 问题

本人测试,自己打包后自己安装运行没问题,复制到其他电脑上安装后会失败,打印cannot extract the snap-name from change: data entry not found,具体原因不明。

参考

  1. installing-snapcraft