veket官方网站论坛

veket

 找回密码
 要注册
搜索
查看: 1639|回复: 0

[推荐] AppImages进阶:手工打包

[复制链接]
发表于 2020-3-14 20:58 | 显示全部楼层 |阅读模式
手动创建一个AppDir,然后将其转换为AppImage。从下面的示例开始,然后将某些应用程序或应用程序类型捆绑为AppImage的示例。
手动创建APPDIR
实际上,您可能永远不会手动执行此操作。因此,这主要是为了说明概念。
创建一个看起来(至少)如下的AppDir结构:
MyApp.AppDir/
MyApp.AppDir/AppRun
MyApp.AppDir/myapp.desktop
MyApp.AppDir/myapp.png
MyApp.AppDir/usr/bin/myapp
MyApp.AppDir/usr/lib/libfoo.so.0

AppRun文件可以是脚本或可执行文件。它设置所需的环境变量,例如,$PATH并启动有效负载应用程序。您可以编写自己的代码,但是在大多数情况下,使用此存储库中的预编译代码最容易(并且最防错)。
当然,如果您的应用程序不需要一个库,或者您要定位的每个基本操作系统中已经包含了您应用程序需要的所有库,那么您可以省去该库。
没有硬编码路径
您的二进制文件myapp不得包含任何会阻止其重定位的硬编码路径。您可以通过运行检查
strings MyApp.AppDir/usr/bin/myapp | grep /usr
如果这返回了某些内容,那么您需要以编程方式修改您的应用程序(例如,通过使用相对路径,使用binreloc或使用QString QCoreApplication::applicationDirPath()
如果您不想更改应用程序的源代码和/或不想重新编译应用程序,则还可以修补二进制文件,例如使用以下命令
sed -i -e 's#/usr#././#g' MyApp.AppDir/usr/bin/myapp
只要应用程序不执行此操作通常chdir()就可以解决此问题,因为这样一来,././它就不再指向$APPDIR/usr任何对象。您可以运行以下命令来查看应用程序是否正在执行chdir()(99%的GUI应用程序未执行)
对于许多GNU软件包用户来说,长期以来一直困扰着这些软件包不可重定位。可重定位程序模块旨在简化使GNU程序可重定位的过程。
注意
对于您的应用程序依赖的任何帮助程序二进制文件和/或库,也是如此。您检查并修补

cd MyApp.AppDir/usr/
find . -type f -exec sed -i -e 's#/usr#././#g' {} \;
cd -

它取代所有出现/usr././,这仅仅意味着“这里”。
myapp.desktop应该包含(至少):
[Desktop Entry]
Name=MyApp
Exec=myapp
Icon=myapp
Type=Application
Categories=Utility;


请确保选择“已注册类别”之一,并确保您的桌面文件通过使用desktop-file-validate your.desktop通过验证。如果您不是使用图形用户界面(GUI)而是使用命令行工具(用于终端)来部署应用程序,请确保添加Terminal = true

从AppDir创建AppImage
若要创建AppImage,请在AppDir上运行appimagetool,以将其转换为AppImage。您可以从该存储库的“发行”页面中获取它(它本身是一个AppImage)
捆绑GTK库
以下步骤允许以可重定位的方式捆绑GTK库和配置文件,而无需修补文件和替换硬编码的路径。可以在https://github.com/aferrero2707/appimage-helper-scripts/blob/master/bundle-gtk2.sh找到以bash脚本形式出现的全套捆绑命令。他们假定存在APPDIR指向AppImage捆绑包根文件夹的环境变量。
GDK-pixbuf的模块和缓存文件
gdk_pixbuf_moduledir="$(pkg-config --variable=gdk_pixbuf_moduledir gdk-pixbuf-2.0)"
gdk_pixbuf_cache_file="$(pkg-config --variable=gdk_pixbuf_cache_file gdk-pixbuf-2.0)"
gdk_pixbuf_libdir_bundle="lib/gdk-pixbuf-2.0"
gdk_pixbuf_cache_file_bundle="$APPDIR/usr/${gdk_pixbuf_libdir_bundle}/loaders.cache"
mkdir -p "$APPDIR/usr/${gdk_pixbuf_libdir_bundle}"
cp -a "$gdk_pixbuf_moduledir" "$APPDIR/usr/${gdk_pixbuf_libdir_bundle}"
cp -a "$gdk_pixbuf_cache_file" "$APPDIR/usr/${gdk_pixbuf_libdir_bundle}"
sed -i -e "s|${gdk_pixbuf_moduledir}/||g" "$gdk_pixbuf_cache_file_bundle"

sed命令将删除高速缓存文件中的硬编码路径。在运行时,必须将$APPDIR/usr/ib/gdk-pixbuf-2.0/loaders文件夹添加到LD_LIBRARY_PATH环境变量中,以便链接器可以正确找到捆绑的GDK-Pixbuf加载器。

GLib的模式
glib_prefix="$(pkg-config --variable=prefix glib-2.0)"
mkdir -p "$APPDIR/usr/share/glib-2.0/schemas/"
cp -a ${glib_prefix}/share/glib-2.0/schemas/* "$APPDIR/usr/share/glib-2.0/schemas"
cd "$APPDIR/usr/share/glib-2.0/schemas/"
glib-compile-schemas .

主题
mkdir -p "$APPDIR/usr/lib/gtk-2.0"
GTK_LIBDIR=$(pkg-config --variable=libdir gtk+-2.0)
GTK_BINARY_VERSION=$(pkg-config --variable=gtk_binary_version gtk+-2.0)
cp -a "${GTK_LIBDIR}/gtk-2.0/${GTK_BINARY_VERSION}"/* "$APPDIR/usr/lib/gtk-2.0"

RSVG库
不会自动选择该库,因为它是GDK-Pixbuf加载程序的依赖项,而不是全局GTK库的依赖项。
export GDK_PIXBUF_MODULEDIR="${APPDIR}/usr/lib/gdk-pixbuf-2.0/loaders"

mkdir -p "$APPDIR/usr/lib"
RSVG_LIBDIR=$(pkg-config --variable=libdir librsvg-2.0)
if [ x"${RSVG_LIBDIR}" != "x" ]; then
export GDK_PIXBUF_MODULE_FILE="${APPDIR}/usr/lib/gdk-pixbuf-2.0/loaders.cache"
     echo "cp -a ${RSVG_LIBDIR}/librsvg*.so* $APPDIR/usr/lib"
     cp -a "${RSVG_LIBDIR}"/librsvg*.so* "$APPDIR/usr/lib"
fi

运行时环境变量
运行AppImage时需要设置以下环境变量:
export GDK_PIXBUF_MODULEDIR="${APPDIR}/usr/lib/gdk-pixbuf-2.0/loaders"
export GDK_PIXBUF_MODULE_FILE="${APPDIR}/usr/lib/gdk-pixbuf-2.0/loaders.cache"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$GDK_PIXBUF_MODULEDIR"
export GTK_PATH="$APPDIR/usr/lib/gtk-2.0"
export GTK_IM_MODULE_FILE="$APPDIR/usr/lib/gtk-2.0:$GTK_PATH"
export PANGO_LIBDIR="$APPDIR/usr/lib"
您需要登录后才可以回帖 登录 | 要注册

本版积分规则

QQ|手机版|Archiver|veket官方网站论坛 ( 粤ICP备 11052856 )

GMT+8, 2024-5-6 09:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表