veket官方网站论坛

nz2017 发表于 2020-3-14 21:15

AppImages进阶:从二进制包转化

在某些情况下,可以将现有的二进制程序包转换为AppImages。本文将着重介绍。
pkg2appimage
如果您已经有现有的二进制文件(归档文件,.deb格式文件或ppa),则建议将它们转换为AppImage的方法是编写一个.yml描述文件,并使用pkg2appimage运行它。
要从.yml描述文件构建AppImage ,只需运行:
bash -ex ./pkg2appimage recipes/XXX.yml
.yml描述文件告诉pkg2appimage从何处获取配料以及如何将其转换为AppImage(除了pkg2appimage中已包含的常规步骤之外)。你可以研究一些示例以了解其工作原理。
pkg2appimage存在一些明显的问题:
最终的AppImage可能会增加很多膨胀。由于它仅提取软件包的内容,因此不会检查应用程序是否实际使用了这些资源中的任何资源。建议您检查最终的AppImage,并rm在配方中添加命令以删除未使用的数据。
pkg2appimage使用使用软件包管理器下载的分发软件包,但是,由于大多数安全功能已被停用,因此未对软件包进行身份验证。这是一个主要的安全问题。因此,建议仅将pkg2appimage供个人使用。上游作者应考虑从源头打包。
.yml文件
构建AppImage的最简单方法是编写.yml文件。我们开发了一种相当简单的格式,该格式允许开发人员编写一个app.yml文件来描述如何构建AppImage app,从而能够重用预构建的二进制文件(例如来自Debian软件包的二进制文件),从而节省创建和构建AppImage的时间。本文介绍了这些.yml文件的用途,它们的结构以及一些描述如何使用所有高级功能的示例。
.yml是通常用于YAML(又一种标记语言,今天也用作YAML不是标记语言的缩写)的文件扩展名。YAML描述数据的方法是组合关联列表(例如,在Python中称为dict或在JavaScript中称为object literal),列表(数组)和标量值。这导致易于解析且易于阅读的格式。
pkg2appimage.yml使用这些文件,该pkg2appimage在AppImages项目中用于将二进制成分转换为AppImages以进行演示。它们的主要目的是使将现有的二进制文件转换为AppImage格式非常简单。如果可以从源代码构建软件,则可以在构建工作流中直接生成AppImage。在这种情况下,您可能不需要.yml文件(但是Travis CI .travis.yml和/或Makefile等)。
该.yml文件格式不是AppImage标准的一部分,该标准仅描述AppImage容器格式,并且与如何生成AppImage内部的有效载荷无关。它都不是AppImageKit的一部分,因为AppImageKit只与获取预先存在的AppDir并将其转换为AppImage有关。这样的AppDir是根据存储在.yml文件中的指令创建的,并使用AppImageKit转换为AppImage。
.yml文件的一般格式如下:
app: (name of the application)
(optional flags)
ingredients:
(instructions that describe from where to get
the binary ingredients used for the AppImage)
script:
(instructions on how to convert these ingredients to an AppImage)
.yml文件一般包括三个部分:
1整体部分(包含应用程序和可选标志的名称)
2成分部分(从哪里获得用于AppImage二进制成分描述)
3脚本部分(描述如何将这些成分转换为AppImage)
注意,这些部分可能包含子部分。例如,成分部分也可以有一个脚本部分,其中包含有关如何确定成分的最新版本以及如何下载它们的说明。
app密钥
必选 包含应用程序的名称。如果.yml文件使用包中的成分(例如.deb),则该名称必须与主可执行文件的包名称匹配。
这是可选的。binpatch:true或union:true。这些密钥提供了一些变通方法,这些变通方法使得可以从文件系统中不同的位置(即,使它们可重定位)运行其他应用程序,而这并不是为此目的而进行的。例如,某些应用程序包含指向编译时$ PREFIX的硬编码路径,例如/ usr。 通常不建议这样做,并且要求应用程序作者使用相对于主要可执行文件的路径。 存在诸如binreloc之类的库来简化此过程。 由于许多应用程序仍无法重定位,因此这些密钥之一可以使用一些解决方法:
       binpatch: true 指示应修补AppImage中的二进制文件,以用字符串替换/usr字符串././,AppRun应在执行有效负载应用程序之前将文件放置在AppImage中,chdir()该usr/文件对AppDir内部的目录进行处理。最终结果是,只要应用程序自身usr/不内部使用chdir()操作,它们就可以在AppImage内的目录中找到其资源 。
       union: true指示AppRun应将一个文件放在AppImage内,以尝试创建联合文件系统的印象,从而有效地给有效载荷应用程序留下印象,即AppImage的内容被覆盖在上面/。这可以通过使用LD_PRELOAD和重定向文件系统调用的库来实现。只要有效负载应用程序是动态链接的二进制文件,它就可以工作。
成分部分
描述如何获取进入AppImage的二进制成分。二进制成分可以是.zip文件之类的档案,.deb文件之类的软件包或Debian软件包之类的PPT或APT存储库。
.yml文件不应对版本号进行硬编码,而是在运行时确定最新版本。如果 .yml文件描述了发行版本,则应在运行时确定最新发行版本。如果 .yml文件描述了开发版本,则它可能引用最新的每晚或连续构建。
使用二进制存档中的成分
以下示例成分部分介绍了如何获取最新版本的二进制存档:
ingredients:
script:
    - DLD=$(wget -q "https://api.github.com/repos/atom/atom/releases/latest" -O - | grep -E "https.*atom-amd64.tar.gz" | cut -d'"' -f4)
    - wget -c $DLD
    - tar zxvf atom*tar.gz
该script部分内部的ingredients部分确定其URL,下载并提取二进制存档。
使用来自Debian存储库的成分
以下示例成分部分描述了如何从Debian档案库获取软件包的最新版本:
ingredients:
dist: xenial
sources:
    - deb http://archive.ubuntu.com/ubuntu/ xenial main universe
    - deb http://download.opensuse.org/repositories/isv:/KDAB/xUbuntu_16.04/ /

本dist节内的ingredients部分定义应将哪个Debian发行版用作基础。本sources节内的ingredients部分描述了应从中取出软件包的存储库。这些条目与debian sources.list文件中的行格式相同。请注意,http://download.opensuse.org/repositories/isv:/KDAB/xUbuntu_16.04存储库需要http://archive.ubuntu.com/ubuntu/存储库,以便可以解决依赖关系。
使用来自Ubuntu PPA的成分
这是Debian存储库的特例。PPA可以用该模式唯一标识,owner/name并且为简洁起见,可以这样指定:
ingredients:
dist: xenial
sources:
    - deb http://us.archive.ubuntu.com/ubuntu/ xenial main universe
ppas:
    - geany-dev/ppa
本ppas部分内的ingredients部分可让您指定一个或多个Ubuntu PPA。这等效于,但比sources.list在sources部分内部的ingredients部分中添加相应的条目更为优雅。
使用本地deb文件
这允许使用本地deb文件(而不是下载deb成分)
ingredients:
dist: xenial
sources:
    - deb http://us.archive.ubuntu.com/ubuntu/ xenial main universe
debs:
    - /home/area42/kdenlive.deb
    - /home/area42/kdenlive/*

对于单个文件,只需使用
- /path/to/file.deb
对于目录中的所有文件(例如本地存储库)。请注意,路径的以/*结尾:
- /path/to/local/repo/*
这是供个人使用的,如果使用成分部分,则debs文件不在指定目录中,则它将在另一台计算机上不起作用
不计入某些包
一些软件包声明了运行软件不一定必需的依赖项。该.yml格式允许通过假装软件包已经安装来覆盖它们。要排除这些依赖关系(以及否则将引入的任何依赖关系),必须将包添加到exclude的ingredients节的键中:
ingredients:
dist: xenial
packages:
    - multisystem
    - gksu
sources:
    - deb http://us.archive.ubuntu.com/ubuntu/ xenial main universe
    - deb http://liveusb.info/multisystem/depot all main
exclude:
    - qemu
    - qemu-kvm
    - cryptsetup
    - libwebkitgtk-3.0-0
    - dmsetup

在此示例中,排除qemu意味着qemu包及其通常会拉入AppImage的所有依赖项将从AppImage中排除(除非AppImage中的其他内容已经拉入了某些依赖关系)。
假装正在安装的某些版本的依赖项
如果系统中不存在某些确切的依赖性版本,则某些软件包中的依赖性信息可能会导致软件包管理器拒绝安装该应用程序。在这种情况下,可能有必要使用ingredients部分中的pretend来假装要在目标系统上安装的依赖项的确切版本:
ingredients:
dist: xenial
sources:
    - deb http://archive.ubuntu.com/ubuntu/ xenial main universe
ppas:
    - otto-kesselgulasch/gimp-edge
pretend:
    - libcups2 1.7.2-0ubuntu1
这里的假设是每个目标系统至少都有可用的伪装版本,并且较新版本的伪装包能够像伪装版本本身一样运行应用程序(如果不是,则伪装包运行)已破坏了向下兼容性,应予以修复)。
成分部分中的任意脚本
您可以在该script部分的内部添加任意的shell命令,ingredients以方便检索二进制成分。这允许针对复杂情况构建AppImage,如以下示例所示:
ingredients:
script:
    - URL=$(wget -q https://www.fosshub.com/JabRef.html -O - | grep jar | cut -d '"' -f 10)
    - wget -c "$URL"
    - wget -c --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u66-b17/jre-8u66-linux-x64.tar.gz
这将下载有效负载应用程序JabRef和所需的JRE,后者需要设置特殊的cookie标头。
该脚本还可用于从GitHub发布页面获取预构建的Debian软件包,或覆盖软件包的版本。
如果在其他配料处理完成后需要运行此命令,请使用post_script代替。script
脚本部分
该script部分可能包含将二进制成分转换为AppDir适合于生成AppImage 所需的任意shell命令。
脚本部分需要将成分复制到位
如果.deb在本ingredients节中指定了软件包,Debian存储库或PPA ,则将自动解决它们的依赖关系(考虑所有最新版本的所有目标系统上都存在的软件包黑名单,例如glibc),并且包被提取到AppDir中。本script节中包含的Shell命令在此AppDir的根目录内执行。但是,某些软件包将内容放置在非标准位置,即主可执行文件位于之外usr/bin。在这些情况下,本script节中包含的命令应规范化文件系统结构。有时还需要编辑其他文件以反映更改后的文件位置。以下示例说明了这一点:
ingredients:
dist: xenial
sources:
    - deb http://archive.ubuntu.com/ubuntu/ xenial main universe

script:
    - DLD=$(wget -q "https://github.com/feross/webtorrent-desktop/releases/" -O - | grep _amd64.deb | head -n 1 | cut -d '"' -f 2)
    - wget -c "https://github.com/$DLD"

script:
- mv opt/webtorrent-desktop/* usr/bin/
- sed -i -e 's|/opt/webtorrent-desktop/||g' webtorrent-desktop.desktop
在本ingredients节中,将.deb下载软件包。然后,在该script部分中,将主可执行文件移动到AppDir中的标准位置。最后,.desktop文件被更新以反映这一点。
如果指定了其他类型的二进制成分,则本script节中包含的shell命令需要通过将它们复制到位来检索它们。请注意,由于该script部分中包含的命令是在AppDir的根目录内执行的,因此在配料部分中下载的配料在上一级目录中,即在中../。以下示例说明了这一点
ingredients:
script:
    - wget -c "https://telegram.org/dl/desktop/linux" --trust-server-names
    - tar xf tsetup.*.tar.xz

script:
- cp ../Telegram/Telegram ./usr/bin/telegram-desktop
在本ingredients节中,将下载档案并解压缩。然后,在该script部分中,将主可执行文件复制到AppDir内部。
脚本部分需要将图标和.desktop文件复制到位
运行.yml文件的脚本会尝试自动执行此操作,如果在app:键中指定的应用程序名称与$ ID.desktop文件和相应的图标文件的名称匹配,该脚本将起作用。例如,如果设置了app:myapp,并且有usr / bin / myapp,usr / share / applications / myapp.desktop和usr / share / icons / * / myapp.png,则有myapp.desktop和myapp。png文件会自动复制到AppDir的顶级目录中。不幸的是,许多软件包都在命名中。在这种情况下,脚本部分中包含的shell命令必须将一个$ ID.desktop文件和相应的图标文件精确复制到AppDir的顶级目录中。
以下示例说明了这一点:
script:
- tar xf ../fritzing* -C usr/bin/ --strip 1
- mv usr/bin/fritzing.desktop .
不幸的是,许多应用程序不包含$ID.desktop文件。如果缺少它,则script需要创建本节中包含的shell命令。以下(简化的)示例说明了这一点:
script:
- # Workaround for:
- # https://bugzilla.mozilla.org/show_bug.cgi?id=296568
- cat > firefox.desktop <<EOF
-
- Type=Application
- Name=Firefox
- Icon=firefox
- Exec=firefox %u
- Categories=GNOME;GTK;Network;WebBrowser;
- MimeType=text/html;text/xml;application/xhtml+xml;
- StartupNotify=true
- EOF
注意,可选的desktopintegration脚本假定app:键中指定的应用程序的名称与$ ID.desktop文件的名称以及相应的主要可执行文件(区分大小写)相匹配。例如,如果设置了app:myapp,则期望usr / bin / myapp和usr / share / applications / myapp.desktop。因此,如果您想使用可选的Desktopintegration脚本,则可以重新排列AppDir。以下示例说明了这一点
script:
- cp ./usr/share/applications/FBReader.desktop fbreader.desktop
- sed -i -e 's|Exec=FBReader|Exec=fbreader|g' fbreader.desktop
- sed -i -e 's|Name=.*|Name=FBReader|g' fbreader.desktop
- sed -i -e 's|Icon=.*|Icon=fbreader|g' fbreader.desktop
- mv usr/bin/FBReader usr/bin/fbreader
- cp usr/share/pixmaps/FBReader.png fbreader.png

转换pip打包的Python应用程序
假设您已经使用打包了Python应用程序pip。在这种情况下,您可以使用该pkg2appimage工具生成AppImage。在以下示例中,我们将使用转换Python 3应用程序pip3。
以下示例将使用virtualenv和转换Python 3 PyQt应用程序pip3
app: mu.codewith.editor
ingredients:
dist: xenial
sources:
    - deb http://us.archive.ubuntu.com/ubuntu/ xenial xenial-updates xenial-security main universe
    - deb http://us.archive.ubuntu.com/ubuntu/ xenial-updates main universe
    - deb http://us.archive.ubuntu.com/ubuntu/ xenial-security main universe
packages:
    - python3.4-venv
script:
    -wget -c https://raw.githubusercontent.com/mu-editor/mu/master/conf/mu.codewith.editor.png
    -wget -c https://raw.githubusercontent.com/mu-editor/mu/master/conf/mu.appdata.xml
script:
- cp ../mu.codewith.editor.png ./usr/share/icons/hicolor/256x256/
- cp ../mu.codewith.editor.png .
- mkdir -p usr/share/metainfo/ ; cp ../mu.appdata.xml usr/share/metainfo/
- virtualenv --python=python3 usr
- ./usr/bin/pip3 install mu-editor
- cat > usr/share/applications/mu.codewith.editor.desktop <<\EOF
-
- Type=Application
- Name=Mu
- Comment=A Python editor for beginner programmers
- Icon=mu.codewith.editor
- Exec=python3 bin/mu-editor %F
- Terminal=false
- Categories=Application;Development;
- Keywords=Python;Editor;microbit;micro:bit;
- StartupWMClass=mu
- MimeType=text/x-python3;text/x-python3;
- EOF
- cp usr/share/applications/mu.codewith.editor.desktop .
- usr/bin/pip3 freeze | grep "mu-editor" | cut -d "=" -f 3 >> ../VERSION
可选资源和功能
如果您已经按照教程进行操作,那么恭喜!您现在应该已经可以使用AppImage。
但是,您还可以进一步改进产生的AppImage。AppImage提供了一些附加功能,例如二进制增量更新和标准化且可验证的签名机制。
另外,您可以添加可选资源,例如AppStream元数据,以允许与AppImages一起使用的工具(例如AppImageHub)显示有关AppImage的其他信息。

部分参考:https://www.gnu.org/software/gnulib/manual/html_node/Supporting-Relocation.html
                https://specifications.freedesktop.org/menu-spec/latest/index.html
















xboxbox 发表于 2020-3-14 22:05

如何使用AppImage软件包
http://www.lucky8k.com/thread-132940-1-1.html
辛苦了,强烈支持!
页: [1]
查看完整版本: AppImages进阶:从二进制包转化