Eksperimen Bikin Paket AppImage

JS NEWS – Selama ini, jika seorang pengembang ingin mendistribusikan aplikasinya untuk GNU/Linux, mereka berarti perlu memaketkannya untuk distribusi Debian, Ubuntu, Fedora, Arch Linux, dan distribusi-distribusi lain. Namun itu tidak mungkin, terlalu berat dan rumit bagi seseorang untuk memaketkan aplikasi untuk lebih dari satu distribusi. Oleh sebab itu umumnya pengembang aplikasi FLOSS (upstream) hanya memaketkan untuk distribusi besar seperti Debian. Mereka memasrahkan pemaketan distribusi lain kepada masing-masing pengembang distribusi tersebut (downstream).

AppImage adalah format yang memperkenankan pengembang aplikasi untuk memaketkan produk mereka agar dapat dijalankan di distribusi GNU/Linux apapun. AppImage merupakan solusi atas masalah pendistribusian aplikasi untuk sistem operasi bebas/merdeka tersebut.

Ia lahir pada tahun 2004 di tangan Simon Peter (Probono). Awalnya ia dinamakan sebagai klik sebelum berganti nama menjadi PortableLinuxApps pada tahun 2011. Perkakas ini mulai berjenama AppImage pada tahun 2013 dan dirilis dengan lisensi MIT.

Meskipun berusia tua, AppImage cenderung kalah populer kalau dibandingkan dengan Flatpak, maklum AppImage hanya “dipasarkan” oleh satu orang pengembang dan komunitas yang tak terlalu besar, berbeda kalau dibandingkan dengan Flatpak yang penyebarannya didukung oleh proyek besar seperti Fedora beserta komunitasnya.

Bagi saya, AppImage adalah format pemaketan terfavorit. Dalam ranah pemaketan portabel (satu berkas biner dapat dijalankan di semua distribusi GNU/Linux) lho ya. Coba bandingkan dengan dua perangkat lunak lain yang menawarkan solusi sama, Snap dan Flatpak. Ada perangkat lunak khusus yang perlu diinstal jika ingin menjalankan aplikasi berbasis keduanya, snapd (paket snapd di Ubuntu) dan flatpak (paket flatpak di Ubuntu).

Alur kerjanya seperti ini. Jika ingin memasang paket berbasis Snap. Pasang snapd (di Ubuntu sudah bawaan) → cari paket yang diinginkan dengan snap find → pasang paket aplikasi dengan snap install → jalankan dengan snap run …​.

Dengan Flatpak alur kerjanya seperti ini. Pasang flatpak → tambah repositori dengan flatpak remote-add …​ → pasang paket aplikasi dengan flatpak install …​ → jalankan dengan flatpak run …​.

Kalau AppImage?

Cukup unduh berkas AppImage → tambahkan mode executable pada berkas tersebut dengan chmod +x …​ → jalankan dengan klik dua kali berkas.

Karena kesederhanaan itu, saya jadi tertarik untuk mencoba membuat paket aplikasi dengan AppImage.

Memaketkan Write.as sebagai AppImage

Saya perlu mengubek-ubek aplikasi FLOSS apa saja yang belum memiliki paket AppImage. Sebenarnya masih banyak, tetapi karena saya baru ingin belajar, saya memilih aplikasi yang tidak terlalu besar, dan akhirnya keputusan jatuh pada Writeas-GTKWrite.as merupakan platform menulis blog sedangkan Writeas-GTK sendiri adalah aplikasi desktop untuk menulis dan menerbitkan tulisan di platform tersebut.

Writeas-GTK hanya memerlukan dependensi GTK+3, gtksourceview, vala, dan Writeas-CLI. Dependensi terakhir opsional, dipasang apabila pengguna ingin menerbitkan tulisannya langsung ke platform Write.as. Tidak dipasang pun tidak apa-apa karena aplikasi tetap dapat dipakai untuk menulis secara luring.

Ada lima cara memaketkan aplikasi menjadi AppImage:

  1. Mengonversi paket biner seperti DEB ke AppImage
  2. Menggunakan OBS (Open Build Service)
  3. Membundel hasil build Travis CI menjadi AppImage
  4. Menjalankan linuxdeployqt jika aplikasi Anda berbasis Qt
  5. Menggunakan Electron-builder jika aplikasi Anda berbasis Electron
  6. Membuat direktori AppDir secara manual

Cara pertama memanfaatkan berkas .yml atau berkas resep yang berisi skrip untuk mengunduh berkas biner (DEB misalnya) dari repositori distro, kemudian menjalankan beberapa perintah instalasi (install …​). Berkas resep ini kemudian dapat dibangun menjadi AppImage menggunakan perkakas pkg2appimage. Hingga saat ini, Writeas-GTK hanya tersedia secara resmi di repositori elementaryOS. Karena saya tidak tahu detail URL repositori distro tersebut, saya melewati cara ini.

Cara kedua dan ketiga tidak saya pertimbangkan. Saya ingin langsung belajar memaketkan AppImage tanpa perlu belajar memaketkan dengan OBS dan membangun dengan Travis CI. Cara keempat dan kelima juga saya lewati karena Writeas-GTK bukanlah aplikasi berbasis Qt dan Electron.

Benar sekali! Karena aplikasi yang ingin saya ubah menjadi AppImage tidaklah terlalu rumit, saya putuskan untuk membuat direktori AppDir secara manual.

Persiapan

Sebelum membentuk paket AppImage untuk Writeas-GTK, saya akan mengunduh kode sumber dan mengompilasinya secara manual. Untuk apa? Untuk memastikan pustaka apa saja yang dibutuhkan, yang nantinya akan dimasukkan ke berkas AppImage.

$ git clone https://github.com/writeas/writeas-gtk.git

Kompilasi manual Writeas-gtk memerlukan meson, ninja, paket development GTK+3, paket development vala, dan paket development gtksourceview, jadi pastikan kelimanya sudah dipasang di sistem operasi. Untuk mengatasi tidak ditemukannya berkas meson.build di direktori writeas-gtk/fonts/lora, kita perlu membuat berkas tersebut di situ.

$ cd writeas-gtk
$ touch fonts/lora/meson.build

Langsung sikat dengan meson dan ninja.

$ meson build && cd build
$ ninja

Di laptop yang saya pakai, proses kompilasi hanya sebentar. Berkas biner Writeas-gtk hasil kompilasi akan muncul di direktori build/src dengan nama com.github.writeas.writeas-gtk.

Membangun AppImage

Seperti yang sudah saya sampaikan tadi, saya akan membangun paket AppImage untuk Writeas-GTK secara manual menggunakan—​membuat direktori AppDir dan memasukkan berkas biner aplikasi dan pustakanya di sana. AppDir adalah sebutan direktori yang isinya akan dimampatkan menjadi satu berkas AppImage.

Buat direktori AppDir.

$ mkdir writeas.AppDir

Direktori writeas.AppDir minimal berisi berkas AppRun.desktop, berkas ikon .png, direktori usr/bin yang berisi berkas biner aplikasi, dan direktori usr/lib yang berisi pustaka-pustaka (lib) aplikasi.

Berikut isi writeas.AppDir yang saya buat.

writeas.AppDir
├── AppRun
├── com.github.writeas.writeas-gtk.png
├── usr
│   ├── bin
│   │   ├── com.github.writeas.writeas-gtk
│   └── lib
│       ├── libX11.so.6
│       ├── libXcomposite.so.1
│       ├── libXcursor.so.1
│       ├── libXdamage.so.1
│       ├── libXext.so.6
│       ├── libXfixes.so.3
│       ├── libXi.so.6
│       ├── libXinerama.so.1
│       ├── libXrandr.so.2
│       ├── libXrender.so.1
│       ├── libatk-1.0.so.0
│       ├── libatk-bridge-2.0.so.0
│       ├── libatspi.so.0
│       ├── libdatrie.so.1
│       ├── libdbus-1.so.3
│       ├── libexpat.so.1
│       ├── libffi.so.6
│       ├── libfribidi.so.0
│       ├── libgbm.so.1
│       ├── libgdk-3.so.0
│       ├── libgdk_pixbuf-2.0.so.0
│       ├── libgio-2.0.so.0
│       ├── libglib-2.0.so.0
│       ├── libgmodule-2.0.so.0
│       ├── libgobject-2.0.so.0
│       ├── libgraphite2.so.3
│       ├── libgtk-3.so.0
│       ├── libgtksourceview-3.0.so.1
│       ├── libpangocairo-1.0.so.0
│       ├── libpixman-1.so.0
│       ├── libpng16.so.16
│       ├── libthai.so.0
│       ├── libuuid.so.1
│       ├── libwayland-client.so.0
│       ├── libwayland-cursor.so.0
│       ├── libwayland-egl.so.1
│       ├── libxcb-render.so.0
│       ├── libxcb-shm.so.0
│       ├── libxcb.so.1
│       └── libxkbcommon.so.0
└── writeas.desktop

AppRun adalah skrip executable yang mengatur variabel environment dan memanggil berkas aplikasi di direktori usr/bin. Jika belum paham benar bagaimana AppRun bekerja, kita dapat mengunduh berkas biner AppRun melalui laman rilis AppImageKit. Karena saya akan membuat AppImage Writeas-GTK untuk x86_64, maka saya mengunduh AppRun-x86_64

Berkas ikon com.github.writeas.writeas-gtk.png adalah berkas yang saya salin dari direktori sumber kode Writeas-GTK.

$ cp writeas-gtk/data/icons/128/com.github.writeas.writeas-gtk.png writeas.AppDir/

Isi direktori usr/bin adalah berkas biner hasil kompilasi manual Writeas-GTK.

$ cp writeas-gtk/build/src/com.github.writeas.writeas-gtk writeas.AppDir/usr/bin/

Isi direktori usr/lib adalah pustaka-pustaka yang digunakan oleh Writeas-GTK. Untuk memilih pustaka ini sungguh tricky (penuh trik). Pustaka atau lib harus merupakan pustaka yang bukan bawaan distribusi GNU/Linux. Bagaimana kita tahu kalau pustaka ini adalah bawaan distribusi dan pustaka itu adalah pustaka khusus untuk menjalankan Writeas-GTK? Kita bisa melakukan riset melalui mesin pencari. Perlu jam terbang untuk melakukan ini, saya pun ragu jika pustaka yang saya salin ke direktori usr/lib sudah benar adanya.

Untuk melihat pustaka apa saja yang diperlukan oleh Writeas-GTK, kita dapat menggunakan perkakas ldd.

$ ldd writeas-gtk/build/src/com.github.writeas.writeas-gtk
linux-vdso.so.1 (0x00007ffdb87ba000)
libgtk-3.so.0 => /usr/lib/libgtk-3.so.0 (0x00007fb5121e0000)
libgdk-3.so.0 => /usr/lib/libgdk-3.so.0 (0x00007fb5120e6000)
libgio-2.0.so.0 => /usr/lib/libgio-2.0.so.0 (0x00007fb511f42000)
libgobject-2.0.so.0 => /usr/lib/libgobject-2.0.so.0 (0x00007fb511eee000)
libglib-2.0.so.0 => /usr/lib/libglib-2.0.so.0 (0x00007fb511dd0000)
libgtksourceview-3.0.so.1 => not found
libc.so.6 => /usr/lib/libc.so.6 (0x00007fb511c0d000)
libgmodule-2.0.so.0 => /usr/lib/libgmodule-2.0.so.0 (0x00007fb511c07000)
libpangocairo-1.0.so.0 => /usr/lib/libpangocairo-1.0.so.0 (0x00007fb5119f9000)
libX11.so.6 => /usr/lib/libX11.so.6 (0x00007fb5118b8000)
libXi.so.6 => /usr/lib/libXi.so.6 (0x00007fb5116a7000)
libXfixes.so.3 => /usr/lib/libXfixes.so.3 (0x00007fb5114a1000)
libcairo-gobject.so.2 => /usr/lib/libcairo-gobject.so.2 (0x00007fb511296000)
libcairo.so.2 => /usr/lib/libcairo.so.2 (0x00007fb510f60000)
libgdk_pixbuf-2.0.so.0 => /usr/lib/libgdk_pixbuf-2.0.so.0 (0x00007fb510d3b000)
libatk-1.0.so.0 => /usr/lib/libatk-1.0.so.0 (0x00007fb510b15000)
libatk-bridge-2.0.so.0 => /usr/lib/libatk-bridge-2.0.so.0 (0x00007fb5108e2000)
libepoxy.so.0 => /usr/lib/libepoxy.so.0 (0x00007fb5105b4000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007fb51042f000)
libharfbuzz.so.0 => /usr/lib/libharfbuzz.so.0 (0x00007fb51032f000)
libpangoft2-1.0.so.0 => /usr/lib/libpangoft2-1.0.so.0 (0x00007fb51011a000)
libpango-1.0.so.0 => /usr/lib/libpango-1.0.so.0 (0x00007fb50fed4000)
libfontconfig.so.1 => /usr/lib/libfontconfig.so.1 (0x00007fb50fc90000)
libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x00007fb50f9c8000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fb50f9a5000)
libXinerama.so.1 => /usr/lib/libXinerama.so.1 (0x00007fb50f7a2000)
libXrandr.so.2 => /usr/lib/libXrandr.so.2 (0x00007fb50f597000)
libXcursor.so.1 => /usr/lib/libXcursor.so.1 (0x00007fb50f38c000)
libXcomposite.so.1 => /usr/lib/libXcomposite.so.1 (0x00007fb50f189000)
libXdamage.so.1 => /usr/lib/libXdamage.so.1 (0x00007fb50ef86000)
libxkbcommon.so.0 => /usr/lib/libxkbcommon.so.0 (0x00007fb50ed44000)
libwayland-cursor.so.0 => /usr/lib/libwayland-cursor.so.0 (0x00007fb50eb3c000)
libwayland-egl.so.1 => /usr/lib/libwayland-egl.so.1 (0x00007fb50e93a000)
libwayland-client.so.0 => /usr/lib/libwayland-client.so.0 (0x00007fb50e72b000)
libXext.so.6 => /usr/lib/libXext.so.6 (0x00007fb50e519000)
librt.so.1 => /usr/lib/librt.so.1 (0x00007fb50e50f000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007fb50e508000)
libpcre.so.1 => /usr/lib/libpcre.so.1 (0x00007fb50e293000)
libffi.so.6 => /usr/lib/libffi.so.6 (0x00007fb50e08a000)
libz.so.1 => /usr/lib/libz.so.1 (0x00007fb50de73000)
libresolv.so.2 => /usr/lib/libresolv.so.2 (0x00007fb50de59000)
libmount.so.1 => /usr/lib/libmount.so.1 (0x00007fb50ddfa000)
/lib/ld-linux-x86-64.so.2 (0x00007fb51294d000)
libxcb.so.1 => /usr/lib/libxcb.so.1 (0x00007fb50ddce000)
libpixman-1.so.0 => /usr/lib/libpixman-1.so.0 (0x00007fb50dd28000)
libEGL.so.1 => /usr/lib/libEGL.so.1 (0x00007fb50dcea000)
libpng16.so.16 => /usr/lib/libpng16.so.16 (0x00007fb50dcb5000)
libxcb-shm.so.0 => /usr/lib/libxcb-shm.so.0 (0x00007fb50dcb0000)
libxcb-render.so.0 => /usr/lib/libxcb-render.so.0 (0x00007fb50dca1000)
libXrender.so.1 => /usr/lib/libXrender.so.1 (0x00007fb50da95000)
libGL.so.1 => /usr/lib/libGL.so.1 (0x00007fb50da1f000)
libdbus-1.so.3 => /usr/lib/libdbus-1.so.3 (0x00007fb50d9cc000)
libatspi.so.0 => /usr/lib/libatspi.so.0 (0x00007fb50d79a000)
libgraphite2.so.3 => /usr/lib/libgraphite2.so.3 (0x00007fb50d772000)
libthai.so.0 => /usr/lib/libthai.so.0 (0x00007fb50d566000)
libfribidi.so.0 => /usr/lib/libfribidi.so.0 (0x00007fb50d349000)
libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007fb50d10f000)
libuuid.so.1 => /usr/lib/libuuid.so.1 (0x00007fb50d106000)
libbz2.so.1 => /usr/lib/libbz2.so.1 (0x00007fb50cef6000)
libblkid.so.1 => /usr/lib/libblkid.so.1 (0x00007fb50ce9f000)
libXau.so.6 => /usr/lib/libXau.so.6 (0x00007fb50cc9b000)
libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x00007fb50ca95000)
libgbm.so.1 => /usr/lib/libgbm.so.1 (0x00007fb50ca85000)
libglapi.so.0 => /usr/lib/libglapi.so.0 (0x00007fb50ca51000)
libX11-xcb.so.1 => /usr/lib/libX11-xcb.so.1 (0x00007fb50ca4c000)
libxcb-dri2.so.0 => /usr/lib/libxcb-dri2.so.0 (0x00007fb50ca43000)
libxcb-xfixes.so.0 => /usr/lib/libxcb-xfixes.so.0 (0x00007fb50ca39000)
libdrm.so.2 => /usr/lib/libdrm.so.2 (0x00007fb50ca25000)
libwayland-server.so.0 => /usr/lib/libwayland-server.so.0 (0x00007fb50c812000)
libxcb-dri3.so.0 => /usr/lib/libxcb-dri3.so.0 (0x00007fb50c80c000)
libxcb-present.so.0 => /usr/lib/libxcb-present.so.0 (0x00007fb50c807000)
libxcb-sync.so.1 => /usr/lib/libxcb-sync.so.1 (0x00007fb50c7fb000)
libxshmfence.so.1 => /usr/lib/libxshmfence.so.1 (0x00007fb50c5f8000)
libxcb-glx.so.0 => /usr/lib/libxcb-glx.so.0 (0x00007fb50c5db000)
libXxf86vm.so.1 => /usr/lib/libXxf86vm.so.1 (0x00007fb50c3d5000)
libdatrie.so.1 => /usr/lib/libdatrie.so.1 (0x00007fb50c1cd000)

Untuk menyalin pustaka libdatrie, misalnya, ke direktori AppDir usr/lib:

$ cp /usr/lib/libdatrie.so.1 writeas.AppDir/usr/lib/

Yang terakhir adalah membuat berkas .desktop Writeas-GTK. Berkas ini tinggal saya salin dari direktori kode sumber.

$ cp writeas-gtk/data/com.githup.writeas.writeas-gtk.desktop writeas.AppDir/

Hasil akhir

Sudah cukup yakin dengan isi writeas.AppDir, saya kemudian mengunduh perkakas appimagetool melalui laman rilis AppImageKit. Kemudian bundel direktori tersebut ke AppImage dengan perintah,

$ chmod +x appimagetool-x86_64.AppImage
$ ./appimagetool-x86_64.AppImage -v writeas.AppDir/ writeas-x86_64.AppImage

Saatnya uji coba!

Tambahkan mode executable pada writeas-x86_64.AppImage, lalu jalankan.

$ chmod +x writeas-x86_64.AppImage
$ ./writeas-x86_64.AppImage (atau cukup klik dua kali berkas tersebut

Untuk mengunduh berkas AppImage di atas, silakan unduh melalui tautan ini.

SUMBER : Kabar Linux

Share Is Cool