news 2026/4/23 9:19:14

Linux 通用软件包 AppImage 打包详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 通用软件包 AppImage 打包详解

格式介绍 - AppImage

AppImage 是 Linux 系统中一种新型的软件包格式,它与 rpm、deb 这些软件包格式相比最大的不同便是:(1)无需安装,即用即删。(2)只需打包一次,便可到处运行。完美的解决了不同 Linux 发行版(Ubuntu/Debian/Fedora/CentOS)之间软件包不统一的问题。

它的工作原理便是将程序运行所需的文件全部打包在一个文件中,待程序运行时再将这些文件提取在 /tmp/.mount_xxxxxxx/ 目录中,然后执行 AppRun 脚本启动程序以进行资源的调用。以下便是一个 AppImage 文件内部包含的目录树结构:

AppDir/

├── AppRun

├── 应用图标.png

├── 程序名.desktop

├── usr/

├── bin/

├── lib/

├── share/

它本质上就是一个 squashfs 文件系统 + runtime 执行器。

特别注意:

(1)要实现跨平台运行,待打包的程序最好是在 CentOS 7 系统上进行编译 ,然后再进行打包。【注:编译 C/C++ 程序所使用的系统库 glibc 在 Linux 系统上几乎肯定存在,而该库有着良好的向后兼容性,因此使用旧版本的 glibc 库编译出来的程序几乎可以完美的运行在新版本的 glibc 系统上。而在 CentOS 7 上的 glibc 版本是 2.17,该版本较旧且兼容性较好,因此在其系统上编译出来的 C 程序通常也可以在大部分的 Linux 发行版系统中使用。】

(2)待打包程序依赖的 lib 文件中最好只包含其专属的库文件即可,不要包含类似 glibc 这样的系统库文件。【注:这是因为在 A 系统中的 glibc 文件通常并不可以在 B 系统中使用,因此为了避免 AppImage 程序运行错误,请勿这样去做。再者,glibc 在 Linux 系统中是肯定会存在的,因此也并不需要额外去包含这样的依赖文件。】

手动打包 - appimagetool

appimagetool 是由 AppImage 官方制作的打包工具,在使用它进行打包时,必须要先分析待打包程序的动态库依赖情况,然后再完成对 AppDir 目录的装填,最后才能使用 appimagetool 完成对程序的打包。由于分析程序的依赖情况是个很复杂的问题,因此该工具在使用上体验并不太好。

接下来,我将演示如何对一个简单的 C 程序完成打包过程:

(1)文件准备:hello.c。

// 主文件 hello.c

#include <stdio.h>

int main() {

printf("Hello Appimage\n");

return 0;

}

(2)编译并打包

#(1)编译及检验运行

gcc -o hello hello.c

./hello

#(2)制作 AppDir 目录树

mkdir -p AppDir/usr/bin/

cp ./hello AppDir/usr/bin/

wget https://github.com/boolean-world/appimage-resources/blob/master/hello-world-appimage/hello-world-icon.png -O AppDir/hello.png #任意图片文件即可

nano AppDir/hello.desktop #文件内容见下方

nano AppDir/AppRun #脚本内容见下方

#(3)开始制作 AppImage 程序

/root/appimagetool-x86_64.AppImage AppDir/

附注:

hello.desktop 文件如下:

[Desktop Entry]

Name=hello

Exec=hello

Icon=hello

Type=Application

Categories=Utility;

Terminal=true

AppRun 脚本如下:

#!/bin/sh

APPDIR="$(dirname "$(readlink -f "$0")")"

# 添加库目录

if [ -d "$APPDIR/lib64" ]; then

export LD_LIBRARY_PATH="$APPDIR/lib64:$LD_LIBRARY_PATH"

fi

if [ -d "$APPDIR/usr/lib" ]; then

export LD_LIBRARY_PATH="$APPDIR/usr/lib:$LD_LIBRARY_PATH"

fi

# 启动主程序 //注意:不同应用主程序路径需要修改

exec "$APPDIR/usr/bin/hello" "$@"

AppDir 目录树结构如下:

AppDir/

├── AppRun //启动程序,可以是简单的脚本,也可以是 ELF,只要保证运行该脚本主程序能被启动即可。

├── hello.desktop //注意 EXEC 的值,它对应的是/usr/bin/目录中的程序,而 Icon 对应的是当前目录

├── hello.png //也支持 svg 格式

└── usr

└── bin

└── hello

自动打包 - linuxdeploy

linuxdeploy 是一个由第三方制作的 AppImage 打包工具,与 appimagetool 不同的是,它可以对待打包程序自动进行依赖分析,并自动将所需的依赖及资源文件按照 AppDir 的目录格式给装填完毕,用户只需将模版化的 desktop 文件和 icon 文件准备好即可,使用起来简直美滋滋。

【示例一】:接下来,我将演示如何对一个需要依赖的简单 C 程序完成打包过程:

(1)文件准备:mylib.h、mylib.c、main.c、Makefile。

// 动态库头文件 mylib.h

#ifndef MYLIB_H

#define MYLIB_H

int add(int a, int b);

void hello();

#endif

// 动态库源码 mylib.c

#include <stdio.h>

#include "mylib.h"

int add(int a, int b) {

return a + b;

}

void hello() {

printf("Hello from my dynamic library!\n");

}

// 主程序 main.c

#include <stdio.h>

#include "mylib.h"

int main() {

hello();

int result = add(3, 5);

printf("3 + 5 = %d\n", result);

return 0;

}

# Makefile 文件

CC=gcc

CFLAGS=-fPIC -Wall

LDFLAGS=-shared

TARGET_LIB=libmylib.so

TARGET_MAIN=main

all: $(TARGET_LIB) $(TARGET_MAIN)

$(TARGET_LIB): mylib.o

$(CC) $(LDFLAGS) -o $(TARGET_LIB) mylib.o

mylib.o: mylib.c mylib.h

$(CC) $(CFLAGS) -c mylib.c

$(TARGET_MAIN): main.o $(TARGET_LIB)

$(CC) main.o -L. -lmylib -o $(TARGET_MAIN)

main.o: main.c mylib.h

$(CC) -c main.c

clean:

rm -f *.o $(TARGET_MAIN) $(TARGET_LIB)

(2)编译并打包

#(1)编译及检验运行

cd myapp

make

mv libmylib.so /lib64/libmylib.so

./main

#(2)制作的 main.desktop 文件内容

cat main.desktop

[Desktop Entry]

Name=main

Exec=main

Icon=main

Type=Application

Categories=Utility;

Terminal=true

#(3)获取一个 Icon 文件

wget https://github.com/boolean-world/appimage-resources/blob/master/hello-world-appimage/hello-world-icon.png -O main.png

#(4)开始制作 AppImage 程序

/root/linuxdeploy-x86_64.AppImage --appdir /root/myapp --output appimage --icon-file main.png --desktop-file main.desktop -e main

ls -l main*.AppImage

【示例二】:最后,我再演示如何对一个系统命令 find 完成打包过程:

#(1)制作的 find.desktop 文件内容

cat find.desktop

[Desktop Entry]

Name=find

Exec=find

Icon=find

Type=Application

Categories=Utility;

Terminal=true

#(2)获取一个 Icon 文件

wget https://github.com/boolean-world/appimage-resources/blob/master/hello-world-appimage/hello-world-icon.png -O find.png

#(3)开始制作 AppImage 程序

cd $(dirname $(which find))

/root/linuxdeploy-x86_64.AppImage --appdir /root/find --output appimage --icon-file find.png --desktop-file find.desktop -e find

ls -l find*.AppImage

注意:(1)建议将 icon 和 desktop 文件放置在 find 命令根目录下,这样在打包的时候能够避免很多问题。(2)由于 linuxdeploy 在打包环节调用的是 appimagetool,而 appimagetool 在打包的时候会在 github 上拉取 runtime 文件,因此在使用前建议设置全局代理以确保 github 可访问。

杂七杂八

AppImage 参考:官网、参考文档、软件分发

linuxdeploy 插件系统:awesome-linuxdeploy,插件 linuxdeploy-plugin-checkrt 在打包较复杂的 C 程序时可能会比较有用。

理想的编译环境:CentOS 7 x64、CentOS 6 x32。【注意:64 位系统打包出的 AppImage 不可在 32 位系统使用。 】

pkg2appimage 工具支持将 deb 软件包转换给 AppImage 格式的软件包。【注:理论是美好的,但实际打包时失败率太高且太折腾,不推荐使用,还是老实用 linuxdeploy 吧。】

已打包的 AppImage 软件包,可通过 ./app*.AppImage --appimage-extract 将其包含的文件重新提取出来,以供参考或重复打包。

(*)全局代理设置

export http_proxy=http://192.168.56.1:7890

export https_proxy=http://192.168.56.1:7890

export no_proxy=192.168.56.1,localhost

export HTTP_PROXY=http://192.168.56.1:7890

export HTTPS_PROXY=http://192.168.56.1:7890

export NO_PROXY=192.168.56.1,localhost

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/8 16:07:31

银河麒麟桌面操作系统USB存储设备禁用

【使用场景】 因为某些要求,需要禁用USB存储设备。 【操作步骤】 银河麒麟桌面操作系统上执行如下步骤: 步骤1.在/etc/modprobe.d/blacklist.conf文件里面最下面加入两行: blasklist uas blacklist usb_storage 步骤2.保存退出,运行update-initramfs -u 步骤3.重启系统。…

作者头像 李华
网站建设 2026/4/21 5:48:32

构建赋能增效的测试质量度量体系

为什么需要科学的测试质量度量&#xff1f; 在敏捷开发和DevOps普及的今天&#xff0c;软件测试已从单纯的缺陷发现转变为质量保障与风险管控的核心环节。然而&#xff0c;许多测试团队仍面临共性困境&#xff1a;测试价值难以量化、质量改进缺乏数据支撑、资源分配缺乏依据。…

作者头像 李华
网站建设 2026/4/22 7:19:31

FreeSWITCH开启silk编码及转码

eeSWITCH版本&#xff1a; 1.10.11SILK编码由Skype设计&#xff0c;是一种用于VoIP的宽带音频编解码器&#xff0c;它支持8khz、12khz、16khz、24khz四种不同的采样率。今天整理下FreeSWITCH使用silk编码进行通话及转码的笔记&#xff0c;希望对你有帮助。一、模块安装及配置1、…

作者头像 李华
网站建设 2026/4/22 2:19:35

自动化测试的7个误区:从业者必知陷阱与规避策略

自动化测试作为现代软件开发的重要环节&#xff0c;已广泛应用于提升效率、保障质量。然而&#xff0c;许多测试从业者在实施过程中&#xff0c;常陷入一些误区&#xff0c;导致自动化项目效果不佳甚至失败。本文基于行业实践&#xff0c;总结七个常见误区&#xff0c;分析其根…

作者头像 李华
网站建设 2026/4/20 22:05:05

构建可持续的自动化测试体系:从探索到自愈

阶段一&#xff1a;需求分析与可行性评估&#xff08;探索期&#xff09; 在启动任何自动化测试前&#xff0c;需明确定义自动化目标。此阶段核心任务包括&#xff1a; 业务场景优先级排序&#xff1a;使用四象限法将功能模块分为高频高价值、低频高价值、高频低价值、低频低…

作者头像 李华
网站建设 2026/4/18 5:20:25

分层与数据驱动:自动化测试架构的双重演化路径

随着敏捷开发与DevOps实践的普及&#xff0c;自动化测试已成为保障软件质量的核心环节。根据架构设计理念的差异&#xff0c;当前主流的自动化测试架构可划分为分层测试架构与数据驱动测试架构两类。这两类架构分别从职责分离和数据解耦两个维度解决了测试脚本的维护性、扩展性…

作者头像 李华