Linux 通用软件包 AppImage 打包详解

news/2025/11/25 19:49:41/文章来源:https://www.cnblogs.com/kqdssheng/p/19269888

近水楼台先得月,向阳花木易为春。

导航

  • 格式介绍 - AppImage
  • 手动打包 - appimagetool
  • 自动打包 - linuxdeploy
  • 杂七杂八

格式介绍 - 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" ]; thenexport LD_LIBRARY_PATH="$APPDIR/lib64:$LD_LIBRARY_PATH"
fi
if [ -d "$APPDIR/usr/lib" ]; thenexport 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_Hint 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=mainall: $(TARGET_LIB) $(TARGET_MAIN)$(TARGET_LIB): mylib.o$(CC) $(LDFLAGS) -o $(TARGET_LIB) mylib.omylib.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.cclean: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 可访问。

杂七杂八

  1. AppImage 参考:官网、参考文档、软件分发
  2. linuxdeploy 插件系统:awesome-linuxdeploy,插件 linuxdeploy-plugin-checkrt 在打包较复杂的 C 程序时可能会比较有用。
  3. 理想的编译环境:CentOS 7 x64、CentOS 6 x32。【注意:64 位系统打包出的 AppImage 不可在 32 位系统使用。 】
  4. pkg2appimage 工具支持将 deb 软件包转换给 AppImage 格式的软件包。【注:理论是美好的,但实际打包时失败率太高且太折腾,不推荐使用,还是老实用 linuxdeploy 吧。】
  5. 已打包的 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/976430.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么理解np.array([10, 20]).reshape(-1, 1)?

非常好的问题!np.array([10, 20]).reshape(-1, 1) 是 NumPy 中将一维数组转为列向量的常用写法。 下面我将从 基本用法、-1 的含义、与 [:, None] 的对比、常见场景 四个方面,彻底讲清楚 reshape 怎么用,尤其是这种…

2025年11月机器人油脂公司推荐榜:五大专业润滑解决方案供应商对比分析

在工业自动化与机器人技术快速发展的今天,机器人油脂作为保障设备稳定运行的核心耗材,其选择直接影响设备寿命与生产效率。许多设备管理人员、采购负责人或企业技术决策者,常常面临如何从众多供应商中筛选出兼具产品…

2025年11月机器人油脂公司推荐榜:五家优质企业深度对比与客观评价

随着工业自动化程度不断提升,机器人应用场景日益广泛,对机器人油脂品质要求也愈加严格。作为设备维护的关键环节,选择合适的机器人油脂供应商成为众多工业企业技术负责人的核心需求。根据中国机械工业联合会发布的行…

11月25号

今天进行了工程实训中关于钳工的学习。

深入解析:网络安全等级保护测评高风险判定实施指引(试行)--2020与2025版对比

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

AI学习机值不值?2025年实测最有用的AI学习机品牌推荐!

AI学习机值不值?2025年实测最有用的AI学习机品牌推荐!2025年AI学习机市场规模已突破800亿元,但“智商税”的争议始终未停。不少家长困惑:动辄数千元的设备到底有没有用?实则据艾媒咨询2025年第一季度数据显示,使…

2025年11月机器人油脂公司推荐榜:五家优质供应商综合对比分析

在工业自动化快速发展的今天,机器人润滑油脂的选择成为众多企业技术负责人面临的重要课题。作为生产设备的关键"血液",机器人油脂的性能直接关系到设备的运行效率、使用寿命和维护成本。根据行业权威统计,…

AI元人文:基于“价值协议”的社会治理新范式——理论、机制与实践的深度综合

AI元人文:基于“价值协议”的社会治理新范式——理论、机制与实践的深度综合 摘要 本文旨在系统性地构建“AI元人文”治理范式的完整理论-技术-实践体系。面对数字时代治理的“语义鸿沟”与“效能瓶颈”,我们提出以“…

2025年11月机器人油脂公司推荐榜:精选五家优质供应商对比分析

在工业自动化浪潮持续深入的今天,机器人已成为众多制造业企业提升效率、保障品质的核心装备。作为机器人的“血液”,机器人油脂的性能直接关系到设备的运行稳定性、使用寿命和维护成本。许多设备管理人员、采购负责人…

效率与精准:文档信息抽取技术如何重塑财务分析流程

在当今这个数据驱动的商业世界里,财务报表是企业健康状况最核心的“体检报告”。然而,面对动辄上百页、结构复杂、数据庞杂的PDF或扫描件报告,传统的人工阅读和Excel处理方式不仅效率低下,更极易因疲劳和主观性导致…

6.1.1.3 大数据方法论与实践指南-SparkStreaming 任务优化实践 - 详解

6.1.1.3 大数据方法论与实践指南-SparkStreaming 任务优化实践 - 详解2025-11-25 19:35 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto…

机器调度 最小顶点覆盖 初始0

1.用最少的点覆盖所有的边 (重启次数) (任务) 开除最少的学生使所有的早恋关系消失 2.初始是0跳过 #include <bits/stdc++.h> using namespace std; int idx=0;int h[105]; int visited[105]; int match[10…

hikivision 考勤机数据提取

海康的某考勤机可以根据网上的 api 接口提取数据,而不必用优盘拷贝。 经过观察,有如下的流程—— graph TDA[开始] --> B[Step 1: GET sessionLogin/capabilities with random]B --> C[Step 2: POST sessionLo…

[python] Python数据类使用指北

在Python编程中,类定义是组织数据与封装逻辑的核心范式。然而,当需要创建仅用于数据存储的简单类时,开发者往往需编写大量重复机械的样板代码。例如用于属性初始化的__init__方法、支持对象信息友好展示的__repr__方…

深入解析:iOS 26 App 开发阶段性能优化 从多工具协作到数据驱动的实战体系

深入解析:iOS 26 App 开发阶段性能优化 从多工具协作到数据驱动的实战体系pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-famil…

小程序开发使用vant ui 组件快速开发

小程序开发使用vant ui 组件快速开发 1 通过 npm 安装 vant npm i @vant/weapp -S --production 2.修改 app.json, 将 app.json 中的 "style": "v2" 去除,小程序的新版基础组件强行加上了许多样式…

课后作业8

二分查找法。按照从小到大的顺序,输入n个整数并存入数组a中,然后在数组a中查找给定的x。如果数组a中的元素与x的值相同,输出相应的下标(下标从0开始);如果没有找到,输出“Not Found”。如果输入的n个整数没有按…

2025年11月25日加班

不知不觉已经上班4个月了,发生了很多故事,自己没有能力,担不起责任。 现在的心态也和刚上班的时候变化了很多,从刚开始的朦朦胧胧,到现在的已经可以能听懂用户的需求。解决问题的能力提升了好的,思考问题的方式也…

洛谷 P1908:逆序对 ← 树状数组 + 离散化(数组 + sort + STL map)

​【题目来源】https://www.luogu.com.cn/problem/P1908【题目描述】猫猫 TOM 和小老鼠 JERRY 最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM 老猫查阅到…

P10977 Cut the Sequence 分析

题目概述 你需要将一个长度为 \(n\) 的序列 \(A\) 分成若干段,满足每段中数字之和 \(\leq m\),每段将这一段的最大值作为他的贡献,求他们贡献之和的最小值。 分析 蓝书好题!这是一道例题。 不难设 \(f_i\) 表示前 …