摘 要:Linux系統(tǒng)由于自由開源特性,許多個(gè)人、組織以及商業(yè)機(jī)構(gòu)都能夠進(jìn)行Linux操作系統(tǒng)的構(gòu)建,因此出現(xiàn)了眾多各有特色的Linux發(fā)行版,每個(gè)發(fā)行版采用的包管理與軟件分發(fā)技術(shù)不盡相同。文中主要介紹了Snap、Flatpak以及AppImage等Linux發(fā)行版常用軟件打包技術(shù),由于AppImage具有單一文件免安裝的獨(dú)有特性,作者對(duì)AppImage的原理及技術(shù)進(jìn)行了詳細(xì)分析,并將局域網(wǎng)即時(shí)通信軟件Iptux進(jìn)行了單文件打包。經(jīng)測(cè)試驗(yàn)證,軟件打包后能夠在申威統(tǒng)信服務(wù)器操作系統(tǒng)以及麒麟服務(wù)器操作系統(tǒng)上正常運(yùn)行,實(shí)用性強(qiáng),為申威平臺(tái)的軟件打包提供了更多的思路和方法。
關(guān)鍵詞:申威平臺(tái);單文件;軟件打包;AppImage;跨發(fā)行版;Linux
中圖分類號(hào):TP39 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):2095-1302(2024)06-0-04
0 引 言
在Linux系統(tǒng)生態(tài)建設(shè)過程中,應(yīng)用軟件的打包與分發(fā)是Linux生態(tài)系統(tǒng)中不可忽視的一環(huán)。應(yīng)用軟件的打包與分發(fā)是指將軟件源代碼編譯成可執(zhí)行二進(jìn)制文件,并打包成一個(gè)安裝包,通過軟件倉(cāng)庫和第三方軟件源將軟件分發(fā)給用戶,使用戶能夠方便地進(jìn)行應(yīng)用軟件的安裝、升級(jí)和卸載。在Linux系統(tǒng)中,常用的軟件打包格式包括RPM和DEB兩
種[1]。RPM是Red Hat Package Manager的縮寫,是Red Hat開發(fā)的一種軟件包管理工具,主要用于Red Hat系列的Linux發(fā)行版。DEB是Debian Package的縮寫,是Debian開發(fā)的一種軟件包格式,主要用于Debian系列的Linux發(fā)行版。由于不同的Linux發(fā)行版之間存在差異,軟件打包也存在不同。首先,不同的發(fā)行版使用不同的包管理工具,因此需要為每個(gè)發(fā)行版打包不同的軟件包。其次,不同的發(fā)行版之間存在著不同的依賴關(guān)系,因此需要為每個(gè)發(fā)行版打包不同的依賴關(guān)系。這些問題使得軟件打包變得復(fù)雜和繁瑣,同時(shí)也增加了軟件開發(fā)者的工作量[2]。為解決這些問題,一些新的軟件打包和分發(fā)工具正在被開發(fā)和推廣,其中,AppImage是一種新型軟件打包和分發(fā)工具,它可以將軟件打包成一個(gè)獨(dú)立的、可執(zhí)行的二進(jìn)制文件,使得軟件可以在不同的Linux發(fā)行版之間運(yùn)行,并且不受系統(tǒng)依賴關(guān)系的影響,使得軟件的安裝和升級(jí)變得更加方便和簡(jiǎn)單。
1 Linux常用軟件打包
通常一個(gè)應(yīng)用軟件在Linux系統(tǒng)上打包需要針對(duì)不同的Linux發(fā)行版生成不同的軟件包格式,工作量大且繁瑣。為了使Linux系統(tǒng)上應(yīng)用軟件的開發(fā)和打包過程更加簡(jiǎn)單和高效,開發(fā)人員構(gòu)建了與發(fā)行版無關(guān)的軟件包格式,其中包括Snap、Flatpak以及AppImage[3],這些軟件包具有共同的特點(diǎn),即包含了應(yīng)用程序所需的所有庫和依賴項(xiàng),能夠獨(dú)立于操作系統(tǒng)環(huán)境運(yùn)行,應(yīng)用開發(fā)人員無需為不同的Linux系統(tǒng)構(gòu)建不同的軟件包,即一個(gè)軟件打包一次,可以在多個(gè)發(fā)行版上安裝、運(yùn)行以及更新。
1.1 Snap打包
Snap是一種通用的、跨平臺(tái)的打包方式,由Canonical公司開發(fā),最早出現(xiàn)在Ubuntu發(fā)行版中。它旨在簡(jiǎn)化軟件的安裝和更新過程,同時(shí)提供更好的安全性、隔離性和依賴管理。
(1)跨平臺(tái):Snap支持多種Linux發(fā)行版,包括Ubuntu、Fedora、Arch Linux等。開發(fā)者只需創(chuàng)建一個(gè)Snap包就可以在所有支持Snap的發(fā)行版上運(yùn)行。
(2)安全性:Snap應(yīng)用程序運(yùn)行在沙箱環(huán)境中,與系統(tǒng)其它部分隔離,降低了安全風(fēng)險(xiǎn)。
(3)依賴管理:Snap軟件打包包含了應(yīng)用程序運(yùn)行所需的所有依賴庫,避免軟件運(yùn)行時(shí)缺少依賴或者依賴沖突,使應(yīng)用程序在不同的系統(tǒng)和環(huán)境中保持一致的行為。
1.2 Flatpak打包
Flatpak是一種靈活、安全、跨發(fā)行版的應(yīng)用程序打包和分發(fā)技術(shù),它將應(yīng)用程序打包成一個(gè)獨(dú)立的容器,并包含所有運(yùn)行所需的庫和依賴項(xiàng),使應(yīng)用程序可以在不同的Linux發(fā)行版上運(yùn)行。
(1)跨發(fā)行版支持:Flatpak可以在不同的Linux發(fā)行版上運(yùn)行,無需重新編譯或適配。
(2)隔離環(huán)境:Flatpak應(yīng)用程序運(yùn)行在一個(gè)獨(dú)立的容器中,與主系統(tǒng)隔離,可以防止應(yīng)用程序之間的沖突和干擾,同時(shí)防止惡意軟件的攻擊。
(3)自依賴:Flatpak應(yīng)用程序包含所有運(yùn)行所需的庫和依賴項(xiàng),不依賴主系統(tǒng)上安裝的軟件包。
1.3 AppImage打包
AppImage是一種可以將應(yīng)用程序打包成一個(gè)獨(dú)立可執(zhí)行文件的軟件打包技術(shù),包含所有運(yùn)行所需的庫和依賴項(xiàng),可以在不同的Linux發(fā)行版上運(yùn)行。與傳統(tǒng)的軟件包管理不同,AppImage無需解壓或安裝,用戶可以直接運(yùn)行和刪除應(yīng)用程序,而不會(huì)對(duì)系統(tǒng)造成影響。
(1)跨發(fā)行版支持:使用AppImage打包的應(yīng)用程序可以在許多發(fā)行版上運(yùn)行,無需重新編譯或適配。
(2)自依賴:一個(gè)應(yīng)用程序就是一個(gè)文件,包含所有運(yùn)行所需的庫和依賴項(xiàng),不依賴主系統(tǒng)上的環(huán)境獨(dú)立運(yùn)行。
(3)環(huán)境隔離:AppImage應(yīng)用程序運(yùn)行在一個(gè)獨(dú)立的隔離環(huán)境中,通過Linux內(nèi)核的Namespaces和Cgroups機(jī)制隔離不同應(yīng)用的文件系統(tǒng),不會(huì)干擾系統(tǒng)以及系統(tǒng)上的其它程序。
(4)非root權(quán)限:無需root權(quán)限,運(yùn)行AppImage應(yīng)用程序前,通過設(shè)置環(huán)境變量、掛載臨時(shí)文件系統(tǒng)、設(shè)置用戶權(quán)限等,確保應(yīng)用程序在運(yùn)行時(shí)有足夠的權(quán)限和資源。
除Snap、Flatpak和AppImage外,Deepin的玲瓏軟件包也是一種具有跨發(fā)行版、自依賴、與主系統(tǒng)隔離等特點(diǎn)的應(yīng)用打包方式,主要運(yùn)用在深度Linux操作系統(tǒng)中,這些新穎的打包方式很好地解決了Linux系統(tǒng)中軟件安裝和軟件依賴的問題,減少了軟件打包和發(fā)布的工作量[4],同時(shí)改善了Linux系統(tǒng)的軟件使用體驗(yàn),提高了軟件的安全性。
2 AppImage實(shí)現(xiàn)原理及技術(shù)分析
2.1 AppImage實(shí)現(xiàn)原理
AppImage軟件包主要由兩部分組成[5]─AppImage運(yùn)行時(shí)Runtime以及一個(gè)只讀壓縮文件系統(tǒng)SquashFS,兩部分共同打包成一個(gè)可執(zhí)行二進(jìn)制文件。相比Snap與Flatpak打包,AppImage的自解壓、自掛載、免安裝運(yùn)行是其最為獨(dú)特的一個(gè)特性。
當(dāng)用戶運(yùn)行AppImage文件時(shí),由運(yùn)行時(shí)Runtime將AppImage中的只讀壓縮文件系統(tǒng)SquashFS解壓到系統(tǒng)臨時(shí)目錄中,并使用Linux內(nèi)核的fusefs用戶態(tài)文件系統(tǒng)來掛載SquashFS,完成掛載后在臨時(shí)虛擬文件系統(tǒng)中運(yùn)行應(yīng)用程序。當(dāng)退出軟件時(shí),運(yùn)行時(shí)Runtime自動(dòng)卸載虛擬文件系統(tǒng)并清理相關(guān)臨時(shí)文件,保持系統(tǒng)整潔。
SquashFS文件系統(tǒng)包含了應(yīng)用軟件運(yùn)行時(shí)所需的二進(jìn)制可執(zhí)行程序、動(dòng)態(tài)鏈接庫、圖標(biāo)文件以及配置文件等,這也是AppImage應(yīng)用程序能夠在不同Linux發(fā)行版上運(yùn)行的主要原因。AppImage應(yīng)用程序就是一個(gè)二進(jìn)制可執(zhí)行文件,無需安裝直接運(yùn)行,并且刪除AppImage文件本身即完成卸載,極大地方便了用戶對(duì)應(yīng)用軟件進(jìn)行更新和管理。AppImage軟件包組成如圖1所示。
2.2 AppImage技術(shù)分析
2.2.1 AppImage運(yùn)行時(shí)Runtime
運(yùn)行時(shí)Runtime是AppImage的核心組成部分之一,由C語言編寫,通常使用靜態(tài)鏈接來實(shí)現(xiàn)在不同Linux發(fā)行版上的兼容性。同時(shí)為了兼顧輕量、快速的運(yùn)行,在嵌入式Linux應(yīng)用中,Runtime一般采用musl C Library構(gòu)建,musl C Library具有更小的二進(jìn)制文件和更快的啟動(dòng)速度,能夠顯著減小AppImage并加快程序啟動(dòng),使應(yīng)用程序更加簡(jiǎn)潔高效。Runtime在AppImage中主要實(shí)現(xiàn)的功能有:
(1)解壓縮AppImage文件:運(yùn)行時(shí)Runtime首先會(huì)使用appimage_get_elf_section_offset_and_length()函數(shù)獲取Runtime的大小以及SquashFS在AppImage中的偏移量,解壓縮SquashFS到一個(gè)臨時(shí)目錄中。
(2)掛載SquashFS文件系統(tǒng):通過build_mount_point()函數(shù)創(chuàng)建掛載點(diǎn),在臨時(shí)目錄中以.mount_appname-xxxx命名隱藏文件,并以fusefs用戶態(tài)文件系統(tǒng)掛載。
(3)啟動(dòng)應(yīng)用程序:Runtime使用execv()函數(shù)啟動(dòng)SquashFS中的AppRun,AppRun設(shè)置一些環(huán)境變量并啟動(dòng)應(yīng)用程序。
(4)卸載SquashFS文件系統(tǒng)并清理緩存:在應(yīng)用程序退出時(shí),Runtime清理臨時(shí)目錄中解壓的SquashFS文件。
2.2.2 AppImage應(yīng)用載體SquashFS
SquashFS是一個(gè)包含AppImage應(yīng)用程序主體文件的目錄結(jié)構(gòu)AppDir,通常是一個(gè)以$APPNAME.AppDir命名的文件夾。在構(gòu)建AppImage時(shí),應(yīng)用程序以及它所需的依賴庫會(huì)被復(fù)制到AppDir中,搜集和復(fù)制的過程可以手動(dòng)進(jìn)行也可以使用AppImageKit提供的工具,如使用Open Build Service(OBS)、Qt部署工具linuxdeployqt等來完成。
AppDir的目錄結(jié)構(gòu)通常包含以下幾部分:
(1)usr目錄:應(yīng)用程序和它所需的依賴庫目錄通常包括bin目錄、lib目錄和share目錄等。
(2)AppRun腳本:AppRun腳本是一個(gè)可執(zhí)行腳本或是一個(gè)可執(zhí)行程序的軟鏈接,用于啟動(dòng)應(yīng)用程序,它通常會(huì)設(shè)置一些環(huán)境變量,如APPDIR、LD_LIBRARY_PATH、PATH等。其中,APPDIR變量指向AppImage文件所在的目錄,LD_LIBRARY_PATH變量用于指定動(dòng)態(tài)鏈接庫搜索路徑,PATH變量用于指定可執(zhí)行文件配置項(xiàng)搜索路徑。
(3)desktop文件:該文件是一個(gè)用于在桌面環(huán)境中顯示應(yīng)用程序圖標(biāo)和名稱的配置文件,通常包含應(yīng)用程序的名稱、圖標(biāo)、描述和啟動(dòng)命令等信息。
(4)圖標(biāo)文件:該文件是用于在桌面環(huán)境中顯示應(yīng)用程序圖標(biāo)的文件。
AppDir目錄結(jié)構(gòu)如圖2所示。
2.2.3 Qt應(yīng)用打包linuxdeployqt
linuxdeployqt是一個(gè)Qt應(yīng)用程序打包工具,它可以自動(dòng)處理應(yīng)用程序的依賴關(guān)系,利用ldd讀取可執(zhí)行文件的頭部信息來確定需要哪些依賴庫,并將依賴庫和資源打包到AppDir中,同時(shí)使用patchelf工具修改可執(zhí)行文件的依賴庫路徑、RPATH路徑等信息[6],將應(yīng)用程序運(yùn)行時(shí)尋找依賴的路徑限定在AppDir內(nèi)。
linuxdeployqt在打包應(yīng)用程序時(shí),會(huì)自動(dòng)生成AppRun腳本來啟動(dòng)應(yīng)用程序,如果需要自定義AppRun腳本,可以在AppDir目錄下手動(dòng)創(chuàng)建AppRun腳本,linuxdeployqt會(huì)優(yōu)先使用自定義的AppRun腳本。
linuxdeployqt使用-appimage參數(shù)進(jìn)行可執(zhí)行程序和依賴庫的打包:
$ linuxdeployqt path/to/your/app -appimage
3 申威平臺(tái)應(yīng)用軟件AppImage打包
目前支持申威平臺(tái)的Linux發(fā)行版本主要有統(tǒng)信UOS、麒麟KylinOS以及openEuler,采用的應(yīng)用軟件打包方式主要為Debian系列的DEB包和Red Hat系列的RPM包,因此在申威平臺(tái)上應(yīng)用軟件的分發(fā)需要針對(duì)不同的發(fā)行版單獨(dú)進(jìn)行打包和適配,增加了工作量,限制了軟件的通用性和易用性。為此,通過前文對(duì)AppImage軟件打包實(shí)現(xiàn)原理及技術(shù)的分析,現(xiàn)將Linux局域網(wǎng)即時(shí)通信軟件Iptux在申威平臺(tái)上進(jìn)行單文件AppImage構(gòu)建,一次打包能夠在多個(gè)發(fā)行版上兼容運(yùn)行[7-9]。
3.1 Iptux編譯移植
Iptux是一款開源局域網(wǎng)即時(shí)通信軟件,可以在局域網(wǎng)內(nèi)實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)聊天、文件傳輸、遠(yuǎn)程桌面共享等功能。由于采用GTK+編寫,因此Iptux的編譯移植需要首先完善編譯主機(jī)的GTK開發(fā)環(huán)境,以使用apt包管理的統(tǒng)信UOS為例:
$ apt install gcc-c++ cmake gettext gflags libgoogle-glog-dev libgtk-3-dev libglib2.0-dev libjsoncpp-dev ninja-build meson libsigc++-2.0-dev libfuse-dev patchelf
根據(jù)meson.build中的定義生成具體的構(gòu)建定義文件build.ninja,并使用ninja完成Iptux的編譯:
$ meson builddir --default-library static amp;amp; ninja -C builddir
編譯完成后生成申威平臺(tái)的Iptux二進(jìn)制可執(zhí)行文件以及動(dòng)態(tài)鏈接庫libiptux-core.so、libiptux-core.so.0和libiptux-core.so.0.8.3,因?yàn)檫@些文件用于后續(xù)AppImage打包,因此不需要通過ninja-C builddir install進(jìn)行Iptux安裝。
3.2 linuxdeployqt編譯移植
進(jìn)入linuxdeployqt源碼目錄并修改tools/linuxdeployqt/main.cpp中的版本檢查:
/*if (strverscmp (glcv, \"2.27\") gt;= 0) {//注釋版本檢查
qInfo() lt;lt; \"ERROR: The host system is too new.\";
...
return 1;
}*/
編譯linuxdeployqt,生成申威平臺(tái)的linuxdeployqt-sw_64:
$ cmake CMakeLists.txt amp;amp; make
3.3 AppDir構(gòu)建
AppDir是AppImage應(yīng)用軟件的主體部分,根據(jù)前文分析說明的AppDir目錄結(jié)構(gòu)將Iptux編譯生成的二進(jìn)制可執(zhí)行文件、動(dòng)態(tài)鏈接庫以及應(yīng)用圖標(biāo)文件復(fù)制到對(duì)應(yīng)usr/bin、usr/lib和usr/share目錄中,并使用linuxdeployqt工具將Iptux運(yùn)行時(shí)所依賴的動(dòng)態(tài)鏈接庫打包進(jìn)AppDir的usr/lib目錄中,linuxdeployqt打包動(dòng)態(tài)鏈接庫命令:
$ linuxdeployqt-sw_64 Iptux.AppDir/usr/bin/iptux -appimage
完成打包后Iptux.AppDir目錄結(jié)構(gòu):
$ ls Iptux.AppDir/AppRun" .DirIcon" iptux.desktop" iptux-icon.png" usr
3.4 AppImage運(yùn)行時(shí)RunTime編譯移植
運(yùn)行時(shí)Runtime使用靜態(tài)鏈接構(gòu)建,以滿足在不同Linux發(fā)行版上的兼容性要求,主要依賴組件有squashfuse、fuse、zstd等,編譯runtime.c,生成申威平臺(tái)的runtime:
$ gcc runtime.c -o runtime-fuse-sw_64 -std=gnu99 -s -Os -D_FILE_OFFSET_BITS=64 -DGIT_COMMIT=\\"1.0.0\\" -T data_sections.ld -ffunction-sections -fdata-sections -Wl,--gc-sections -I/usr/local/include/squashfuse -I/usr/include/fuse -L/usr/local/lib -lsquashfuse -lsquashfuse_ll -L/opt/zstd/usr/lib -lzstd -lfuse -llzma -lz -ldl -llz4 -lpthread -static
3.5 AppImage構(gòu)建
根據(jù)前文分析,AppImage軟件包主要由運(yùn)行時(shí)Runtime以及只讀壓縮文件系統(tǒng)SquashFS組成,因此拼接Runtime和SquashFS壓縮文件即可完成AppImage構(gòu)建:
$ mksquashfs Iptux.AppDir Iptux.squashfs -root-owned -noappend
$ cat runtime-fuse-sw_64 gt;gt; Iptux-sw_64.AppImage
$ cat Iptux.squashfs gt;gt; Iptux-sw_64.AppImage
生成的Iptux-sw_64.AppImage是一個(gè)單一文件的可執(zhí)行文件,其包含Iptux可執(zhí)行文件以及運(yùn)行時(shí)所依賴的動(dòng)態(tài)鏈接庫、圖標(biāo)以及配置文件,經(jīng)測(cè)試驗(yàn)證,能夠在申威統(tǒng)信UOS Server以及麒麟V10上免安裝運(yùn)行,具有很好的Linux跨發(fā)行版兼容性和便攜性[10]。
4 結(jié) 語
國(guó)產(chǎn)CPU廠商近年來奮楫前行,軟硬件生態(tài)建設(shè)有了長(zhǎng)足的發(fā)展,特別是在黨政、金融領(lǐng)域,大量適配軟件已經(jīng)能夠滿足用戶需求,但在消費(fèi)領(lǐng)域,軟件生態(tài)建設(shè)仍然需要廣大開發(fā)者和用戶的共同努力。文中提出的AppImage單文件軟件打包具有很強(qiáng)的實(shí)用性,極大地方便了軟件的分發(fā)與使用,希望能夠?yàn)樯晖浖鷳B(tài)建設(shè)者在軟件打包與分發(fā)方面提供一些新的思路,也為國(guó)產(chǎn)CPU的發(fā)展和生態(tài)建設(shè)提供支持。
參考文獻(xiàn)
[1]岑鵬瑞,吳玲達(dá),楊超.淺談Linux平臺(tái)下軟件管理現(xiàn)狀[J].電腦知識(shí)與技術(shù),2015,11(17):56-59.
[2]趙正旭,陶智,徐騫.基于國(guó)產(chǎn)操作系統(tǒng)應(yīng)用軟件部署對(duì)策的探討[J].微型機(jī)與應(yīng)用,2016,35(18):16-18.
[3] Flatpak vs.Snap vs.AppImage [EB/OL].(2022-06-08). https://phoenixnap.com/kb/flatpak-vs-snap-vs-appimage
[4]馬俊,周凱,任怡,等.面向操作系統(tǒng)版本構(gòu)建的軟件包依賴關(guān)系分析[J].計(jì)算機(jī)工程與科學(xué),2021,43(11):1926-1933.
[5] AppImage中文文檔[DB/OL].https://doc.appimage.cn/docs/appimage/
[6]蔣立兵,申秋,韓隆隆.內(nèi)網(wǎng)漫游過程中的編譯方法研究[J].通信技術(shù),2021,54(7):1690-1695.
[7]柴赟達(dá).面向國(guó)產(chǎn)申威平臺(tái)的編譯訪存優(yōu)化技術(shù)研究[D].鄭州:鄭州大學(xué),2021.
[8]高順凱.一種基于申威平臺(tái)可靠性評(píng)測(cè)方法的設(shè)計(jì)與實(shí)現(xiàn)[J].艦船電子工程,2021,41(10):150-154.
[9]陳偉.一種基于申威平臺(tái)的AppImage應(yīng)用軟件打包裝置及其方法:CN116661904B [P]. 2023-10-13.
[10]倪杰,何佩佩,王俊,等.一種針對(duì)申威平臺(tái)代碼遷移的軟件依賴檢測(cè)及判斷方法:CN202111525606.3 [P]. 2022-04-19.