Pembuatan Paket Dari Awal

[Penting]

Yang dibutuhkan: build-essential, automake, gnupg, lintian, fakeroot and pbuilder.

Dalam contoh ini Anda akan menggunakan program GNU hello sebagai contoh. Anda dapat men-download tarball source dari ftp.gnu.org. Untuk keperluan contoh ini, Anda akan menggunakan direktori ~/hello/.

mkdir ~/hello
cd ~/hello
wget http://ftp.gnu.org/gnu/hello/hello-2.1.1.tar.gz

Kita juga akan membandingkan paket kita dengan paket yang telah diletakkan di repository Ubuntu. Untuk saat ini, kita akan menempatkannya di direktori ubuntu supaya kita dapat melihatnya nanti. Untuk mendapatkan paket source, pastikan Anda menambahkan baris "deb-src" di repository Main pada berkas /etc/apt/sources.list. Lalu eksekusi dengan:

mkdir ubuntu
cd ubuntu
apt-get source hello
cd ..
[Catatan]

Tidak seperti kebanyakan perintah apt-get, Anda tidak membutuhkan hak akses root untuk memperoleh paket source, karena paket tersebut di-download pada direktori tempat Anda berada sekarang. Malah, Anda disarankan untuk hanya menggunakan apt-get source sebagai pengguna biasa, karena dengan demikian Anda dapat menyunting berkas di paket source tanpa perlu hak akses root.

Yang dilakukan oleh perintah apt-get source adalah:

  1. Download paket source. Paket source umumnya mengandung berkas .dsc yang menjelaskan tentang paket dan memberikan md5sum untuk paket source, berkas .orig.tar.gz yang berisi source code dari pengembang, dan berkas .diff.gz yang berisi patch yang telah diterapkan di source code beserta informasi pembuatan paket.

  2. Untar berkas .orig.tar.gz ke dalam direktori saat ini.

  3. Terapkan berkas .diff.gz ke direktori source yang belum dibongkar.

Jika Anda men-download paket source (.dsc, .orig.tar.gz, and .diff.gz files) secara manual, Anda dapat membongkarnya dengan cara yang sama apt-get source lakukan dengan menggunakan dpkg-source seperti ini:

dpkg-source -x *.dsc

Hal pertama yang perlu Anda lakukan adalah membuat salinan dari tarball original (terkadang disebut "upstream") dengan format berikut: <packagename>_<version>.orig.tar.gz. Langkah ini melakukan dua hal. Pertama, membuat dua salinan dari source code. Jika Anda tidak sengaja mengubah atau menghapus salinan yang sedang Anda kerjakan maka Anda dapat menggunakan salinan yang telah Anda download. Kedua, akan dianggap praktik pembuatan paket yang tidak baik bila mengubah source tarball original kecuali benar-benar diperlukan. Lihat “Kesalahan Umum” untuk alasannya.

cp hello-2.1.1.tar.gz hello_2.1.1.orig.tar.gz
tar -xzvf hello_2.1.1.orig.tar.gz
[Awas]

Sangat penting untuk menggunakan garis, "_" daripada tanda penghubung "-" diantara nama paket (hello) dan versi (2.1.1). Apabila tidak menggunakannya paket Anda tidak akan dapat dibangun sempurna sebagan paket Debian.

Sekarang kita telah memiliki direktori hello-2.1.1 yang mengandung berkas source. Sekarang kita perlu membuat direktori kustom debian tempat dimana semua informasi tentang pembuatan paket disimpan, mengizinkan kita untuk memisahkan berkas paket dari berkas source aplikasi.

mkdir hello-2.1.1/debian
cd hello-2.1.1/debian/

Sekarang kita perlu membuat berkas penting untuk paket source Ubuntu apapun: changelog, control, copyright, and rules. Ini adalah berkas yang diperlukan untuk membuat paket binary (berkas .deb) dari source code original (upstream). Mari kita lihat isinya satu per satu.

changelog

Berkas changelog berisi, seperti namanya, daftar perubahan yang telah dilakukan di tiap versi. Berkas ini memiliki format khusus yang berisi nama paket, versi, distribusi, perubahan, dan siapa yang membuat perubahan beserta waktunya. Jika Anda memiliki GPG key, pastikan menggunakan nama dan alamat email yang sama antara changelog dengan key Anda. Berikut adalah templat changelog:

package (version) distribution; urgency=urgency

  * change details
    more change details
  * even more change details

-- maintainer name <email address>[two spaces]  date

Format (khususnya untuk tanggal) sangatlah penting. Tanggal harus dalam format RFC822, yang dapat diperoleh dari program 822-date.

Berikut adalah contoh berkas changelog untuk aplikasi hello:

hello (2.1.1-1) edgy; urgency=low

   * New upstream release with lots of bug fixes.

-- Captain Packager <packager@coolness.com>  Wed,  5 Apr 2006 22:38:49 -0700

Perhatikan bahwa versi tersebut memiliki -1 dibelakangnya, atau sering disebut revisi Debian, yang digunakan supaya pembuatan paket dapat di-update (untuk membenahi bug misalnya) dengan upload baru dalam versi rilis source yang sama.

[Catatan]

Ubuntu dan Debian memiliki skema pemberian nomor versi yang sedikit berbeda untuk menghindari konflik antar paket dalam versi source yang sama. Jika paket Debian telah diubah di Ubuntu, maka pake memiliki ubuntuX (dimana X adalah nomor revisi Ubuntu) yang ditambahkan di akhir nama versi Debian. Jadi jika paket hello Debian telah diubah oleh Ubuntu, maka versi string menjadi 2.1.1-1ubuntu1. Jika sebuah paket untuk aplikasi tidak ada di Debian, maka nama revisi Debian menjadi 0 (misalnya, 2.1.1-0ubuntu1).

Sekarang lihat changelog untuk Ubuntu paket source yang telah kita download sebelumnya:

less ../../ubuntu/hello-2.1.1/debian/changelog

Perhatikan bahwa dalam kasus ini distribusinya adalah unstable (cabang dari Debian), karena paket Debian belum diubah oleh Ubuntu. Perlu diingat untuk mengubah distribusi menjadi rilis distribusi target Anda.

Pada bagian ini silakan membuat berkas changelog dalam direktori debian yang sedang Anda masuki sekarang.

control

Berkas control mengandung informasi yang manajer paket (seperti apt-get, synaptic, dan aptitude) gunakan, build-time dependencies, informasi pengelola, dan banyak lagi.

Untuk paket hello Ubuntu berkas control terlihat seperti ini:

Source: hello
Section: devel
Priority: optional
Maintainer: Captain Packager <packager@coolness.com> 
Standards-Version: 3.6.1

Package: hello
Architecture: any
Depends: ${shlibs:Depends}
Description: The classic greeting, and a good example
 The GNU hello program produces a familiar, friendly greeting.  It
 allows non-programmers to use a classic computer science tool which
 would otherwise be unavailable to them.
 .
 Seriously, though: this is an example of how to do a Debian
 package.
 It is the Debian version of the GNU Project's `hello world' program
 (which is itself an example for the GNU Project).

Buat berkas control menggunakan informasi di atas (pastikan untuk menyediakan informasi Anda pada ruas Maintainer).

Paragraf pertama memberikan informasi mengenai paket source. Mari kita lihat satu persatu:

  • Source: Ini adalah nama dari paket source, pada kasus disini adalah hello.

  • Section: Repositori apt dibagi ke dalam beberapa bagian untuk mempermudah browsing dan penggolongan perangkat lunak. Dalam kasus ini, hello termasuk ke dalam bagian devel.

  • Priority: Seberapa penting paket ini terhadap pengguna. Harus salah satu dari di bawah ini:

    • Required - paket-paket yang sangat penting untuk sistem agar dapat bekerja dengan baik. Jika paket tersebut dihapus biasanya sistem Anda akan rusak dan sulit untuk dipulihkan kembali.

    • Important - kumpulan paket minimal untuk sistem yang dapat digunakan. Menghapus kumpulan paket ini tidak akan menyebabkan kerusakan yang tidak bisa diperbaiki pada sistem Anda, tapi kumpulan ini dianggap perkakas utama sehingga tanpanya instalasi Linux apapun tidak akan komplet. Catatan: Ini tidak termasuk program seperti Emacs atau bahkan X Window System.

    • Standard - Judul menjelaskan maksudnya.

    • Optional - intinya kategori ini adalah untuk paket yang tidak dibutuhkan, atau bulk paket. Tapi, paket-paket ini tidak boleh menimbulkan konflik satu sama lain.

    • Extra - paket yang berpotensi konflik dengan paket di salah satu kategori diatas. Juga digunakan untuk paket khusus yang mungkin hanya berguna bagi orang yang telah mengerti tujuan dari paket tersebut.

  • Maintainer: Nama pengeloa paket dengan alamat email.

  • Standards-Version: Versi dari Debian Policy yang melekat pada paket (dalam hal ini, versi 3.6.1). Cara mudah untuk mengetahui versi terkini adalah menggunakan apt-cache show debian-policy | grep Version.

  • Build-Depends: Salah satu bidang terpenting dan seringkali merupakan source dari bug, baris ini mendaftar paket binary (dengan nomor versi jika perlu) yang perlu diinstal untuk membuat paket binary dari paket source. Paket yang penting dibutuhkan oleh build-essential dan tidak perlu disertakan dalam baris Build-Depends. Dalam kasus ini, hello, semua paket yang dibutuhkan adalah bagian dari build-essential, jadi baris Build-Depends tidak dibutuhkan. Daftar paket dari build-essential dapat ditemukan di /usr/share/doc/build-essential/list.

Paragraf kedua adalah untuk paket binary yang akan dibangun dari source. Jika multiple paket binary dibangun dari paket source, akan ada satu bagian untuk setiap paket binary. Sekali lagi, mari kita lihat setiap baris:

  • Package: Nama untuk paket binary.Banyak kali untuk program sederhana (seperti hello), nama paket source dan binary adalah serupa.

  • Architecture: Arsitektur dimana paket binary tersebut dibangun. Contohnya adalah:

    • all - Source tidak bergantung pada suatu arsitektur. Program yang menggunakan Python atau bahasa pemrograman tafsiran lainnya akan mengunakan ini. Paket binary yang dihasilkan akan berakhiran dengan _all.deb.

    • any - Source adalah bergantung pada suatu arsitektur dan harus di-compile untuk seluruh arsitektur yang didukung. Akan ada berkas .deb untuk setiap arsitektur ( _i386.deb sebagai contohnya)

    • Subset dari arsitektur (i386, amd64, ppc, dll.) dapat dilihat untuk mengindikasikan bahwa source tersebut tergantung pada suatu arsitektur dan tidak bekerja diseluruh arsitektur yang didukung oleh Ubuntu.

  • Depends: Daftar paket yang paket binary tergantung padanya agar dapat berfungsi. Untuk aplikasi hello, kita lihat ${shlibs:Depends}, yang adalah variabel untuk mengganti share library yang dibutuhkan. Lihat halaman man dpkg-source untuk informasi lebih lanjut.

  • Recommends: Digunakan bagi paket yang sangat disarankan dan biasanya diinstal bersama paket. Beberapa manajer paket, khususnya aptitude, akan menginstal paket yang disarankan dengan otomatis.

  • Suggests: Digunakan bagi paket yang serupa atau berguna jika paket ini diinstal.

  • Conflicts: Digunakan untuk paket yang akan menimbulkan konflik dengan paket ini. Keduanya tidak diinstal secara bersamaan. Jika salah satu diinstal, maka yang lain akan dihapus.

  • Description: Keterangan singkat dan panjang yang digunakan oleh manajer paket. Formatnya adalah seperti berikut:

    Description: <single line synopsis>
     <extended description over several lines>

    Perlu dicatat bahwa ada satu spasi di tiap original baris dalam penjelasan panjang. Untuk informasi tentang cara membuat penjelasan yang baik dapat ditemukan di http://people.debian.org/~walters/descriptions.html.

copyright

Berkas ini memberikan informasi tentang hak cipta. Umumnya, informasi hak cipta ditemukan di berkas COPYING dalam direktori source program. Berkas ini harus menyertakan informasi seperti nama pencipta dan pemaket, URL dari mana source berasal, baris Hak Cipta dengan tahun dan pemegang hak cipta, dan teks tentang hak cipta itu sendiri. Contoh templatnya adalah:

This package was debianized by {Your Name} <your email address>
{Date}

It was downloaded from: {URL of webpage} 

Upstream Author(s): {Name(s) and email address(es) of author(s)}

Copyright:
	Copyright (C) {Year(s)} by {Author(s)} {Email address(es)}

License:

Seperti dibanyangkan, aplikasi hello dirilis dalam lisensi GPL. Pada kasus ini cara termudah adalah cukup menyalin berkas copyright dari paket Ubuntu:

cp ../../ubuntu/hello-2.1.1/debian/copyright .

Anda harus menyertakan hak cipta yang lengkap kecuali hak cipta tersebut adalah GPL, LGPL, BSD, atau Artistic License, dalam hal ini Anda dapat merujuk ke berkas yang dimaksud di direktori /usr/share/common-licenses/.

Perhatian bahwa berkas copyright paket Ubuntu menyertakan pernyataan lisensi untuk manual. Ini sangat penting agar seluruh berkas dalam source dilindungi oleh lisensi.

rules

Berkas rules adalah Makefile yang dapat dieksekusi yang memiliki aturan untuk membuat paket binary dari paket source. Untuk hello, akan lebih mudah untuk menggunakan rules dari paket Ubuntu:

#!/usr/bin/make -f
# Contoh berkas debian/rules - untuk GNU Hello.
# Copyright 1994,1995 by Ian Jackson.
# I hereby give you perpetual unlimited permission to copy,
# modify and relicense this file, provided that you do not remove
# my name from the file itself.  (I assert my moral right of
# paternity under the Copyright, Designs and Patents Act 1988.)
# This file may have to be extensively modified

package = hello
docdir = debian/tmp/usr/share/doc/$(package)

CC = gcc
CFLAGS = -g -Wall
INSTALL_PROGRAM = instal

ifeq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
  CFLAGS += -O2
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
  INSTALL_PROGRAM += -s
endif

build:
        $(checkdir)
        ./configure --prefix=/usr
        $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)"
        touch build

clean:
        $(checkdir)
        rm -f build
        -$(MAKE) -i distclean
        rm -rf *~ debian/tmp debian/*~ debian/files* debian/substvars

binary-indep:   checkroot build
        $(checkdir)
# There are no architecture-independent files to be uploaded
# generated by this package.  If there were any they would be
# made here.

binary-arch:    checkroot build
        $(checkdir)
        rm -rf debian/tmp
        instal -d debian/tmp/DEBIAN $(docdir)
        instal -m 755 debian/postinst debian/prerm debian/tmp/DEBIAN
        $(MAKE) INSTALL_PROGRAM="$(INSTALL_PROGRAM)" \
                prefix=$$(pwd)/debian/tmp/usr instal
        cd debian/tmp && mv usr/info usr/man usr/share
        cp -a NEWS debian/copyright $(docdir)
        cp -a debian/changelog $(docdir)/changelog.Debian
        cp -a ChangeLog $(docdir)/changelog
        cd $(docdir) && gzip -9 changelog changelog.Debian
        gzip -r9 debian/tmp/usr/share/man
        gzip -9 debian/tmp/usr/share/info/*
        dpkg-shlibdeps debian/tmp/usr/bin/hello
        dpkg-gencontrol -isp
        chown -R root:root debian/tmp
        chmod -R u+w,go=rX debian/tmp
        dpkg --build debian/tmp ..

define checkdir
        test -f src/$(package).c -a -f debian/rules
endef

binary: binary-indep binary-arch

checkroot:
        $(checkdir)
        test $$(id -u) = 0

.PHONY: binary binary-arch binary-indep clean checkroot

Mari kita lihat berkas ini untuk lebih rinci. Dibagian awal Anda akan melihat deklarasi dari beberapa variabel:

package = hello
docdir = debian/tmp/usr/share/doc/$(package)

CC = gcc
CFLAGS = -g -Wall
INSTALL_PROGRAM = instal

ifeq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
  CFLAGS += -O2
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
  INSTALL_PROGRAM += -s
endif

Bagian ini menetapkan CFLAGS untuk compiler dan juga menangani noopt dan nostrip DEB_BUILD_OPTIONS untuk debugging.

Selanjutnya adalah build rule:

build:
	$(checkdir)
	./configure --prefix=/usr
	$(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)"
	touch build

Aturan ini menjalankan ./configure dengan prefix yang tepat, menjalankan make, dan membuat berkas build yang berisi kesimpulan dari build yang baru saja dilakukan untuk menghindari berbagai masalah kompilasi.

Aturan berikutnya adalah clean, yang menjalankan make -i distclean dan menghapus berkas yang dibuat ketika membangun paket.

clean:
	$(checkdir)
	rm -f build
	-$(MAKE) -i distclean
	rm -rf *~ debian/tmp debian/*~ debian/files* debian/substvars

Selanjutnya kita lihaat rule kosong binary-indep, karena tidak ada file architecture-independent yang dibuat dalam paket ini.

Ada beberapa, banyak berkas yang tergantung arsitektur tertentu, jadi binary-arch akan digunakan:

binary-arch:    checkroot build
		$(checkdir)
		rm -rf debian/tmp
		instal -d debian/tmp/DEBIAN $(docdir)
		instal -m 755 debian/postinst debian/prerm debian/tmp/DEBIAN
		$(MAKE) INSTALL_PROGRAM="$(INSTALL_PROGRAM)" \
		prefix=$$(pwd)/debian/tmp/usr instal
		cd debian/tmp && mv usr/info usr/man usr/share
		cp -a NEWS debian/copyright $(docdir)
		cp -a debian/changelog $(docdir)/changelog.Debian
		cp -a ChangeLog $(docdir)/changelog
		cd $(docdir) && gzip -9 changelog changelog.Debian
		gzip -r9 debian/tmp/usr/share/man
		gzip -9 debian/tmp/usr/share/info/*
		dpkg-shlibdeps debian/tmp/usr/bin/hello
		dpkg-gencontrol -isp
		chown -R root:root debian/tmp
		chmod -R u+w,go=rX debian/tmp
		dpkg --build debian/tmp ..

Pertama, perhatikan bahwa aturan ini memanggil aturan checkroot untuk memastikan bahwa paket dibangun sebagai root dan memanggil aturan build untuk mengompilasi source. Lalu berkas debian/tmp/DEBIAN and debian/tmp/usr/share/doc/hello dibuat, dan skrip postinst dan prerm> diinstal di debian/tmp/DEBIAN. Lalu make instal dijalankan dengan prefix yang memerintahkan untuk menginstal di direktori debian/tmp/usr. Setelah itu berkas dokumentasi (NEWS, ChangeLog, dan changelog Debian) dikompres gzip dan diinstal. dpkg-shlibdeps dipanggil untuk mencari depedency shared library dari berkas yang dapat dieksekusi hello, lalu menyimpan daftar di berkas debian/substvars untuk variabel ${shlibs:Depends} di control. Kemudian dpkg-gencontrol dijalankan untuk membuat berkas pengendali untuk paket binary, dan membuat pengganti yang dibuat oleh dpkg-shlibdeps. Akhirnya, setelah hak akses dari debian/tmp telah diatur, dpkg --build dijalankan untuk membangun paket binary .deb dan menempatkannya di direktori utama.

postinst dan prerm

Berkas postinst dan prerm adalah contoh dari skrip pengelola. Berkas-berkas ini adalah skrip yang dapat dieksekusi setelah instalasi dan sebelum penghapusan paket. Dalam kasus paket hello Ubuntu, berkas-berkas ini digunakan untuk menginstal (dan menghapus) berkas info. Silakan lihat dan salin berkas-berkas ini ke direktori debian yang sekarang.

cp ../../ubuntu/hello-2.1.1/debian/postinst .
cp ../../ubuntu/hello-2.1.1/debian/prerm .

Membangun Paket Source

Sekarang kita telah melihat berkas-berkas yang ada di direktori debian untuk hello secara detail, kita dapat membangun paket source (dan binary). Pertama mari kita pindah ke root dari source yang telah diekstrak:

cd ..

Sekarang kita membangun paket source menggunakan dpkg-buildpackage:

dpkg-buildpackage -S -rfakeroot

Tanda -S memerintahkan dpkg-buildpackage untuk membangun paket source, dan tanda -r memerintahkan untuk menggunakan fakeroot supaya kita dapat memiliki hak akses root palsu ketika membuat paket. dpkg-buildpackage akan menggunakan berkas .orig.tar.gz dan membuat berkas .diff.gz (perbedaan antara tarball original dari pencipta dan direktori yang telah kita buat, debian/ beserta isinya) dan berkas .dsc yang berisi penjelasan serta md5sum dari paket source. Berkas .dsc dan *_source.changes (digunakan untuk meng-upload paket source) ditandatangani menggunakan GPG key Anda.

[Awas]

Jika Anda tidak memiliki gpg key yang telah dibuat maka Anda akan mendapatkan pesan kesalahan dari debuild. Anda dapat membuat gpg key atau menggunakan -us -uc key pada debuild untuk mematikan tandatangan. Tapi Anda tidak bisa meng-upload paket Anda ke Ubuntu tanpa menandatangani paket tersebut.

[Tip]

Untuk memastikan agar debuild mencari gpg key yang tepat maka Anda harus mengatur variabel lingkungan DEBFULLNAME dan DEBEMAIL (misalnya di berkas ~/.bashrc Anda) dengan nama dan alamat email yang Anda gunakan untuk gpg key di debian/changelog

Beberapa orang telah melaporkan bahwa mereka tidak dapat memerintahkan debuild untuk mencari gpg key dengan benar, bahkan setelah mereka mengatur lingkungan variabel seperti contoh diatas. Untuk mengatasi hal ini Anda perlu memberi tanda -k<keyid> pada debuild dimana <keyid> adalah ID gpg key Anda.

Sebagai tambahan dari paket source, Anda dapat juga membangun paket binary dengan pbuilder:

sudo pbuilder build ../*.dsc

Penggunaan pbuilder untuk membangun paket binary adalah sangat penting. Penggunaan ini menjamin bahwa depedency build benar, karena builder menyediakan hanya lingkungan minimal, jadi depedency selama build-time ditentukan oleh berkas control.

Anda dapat memeriksa paket sourace dari kesalahan umum dengan menggunakan lintian:

cd ..
lintian -i *.dsc