Bahasa: 日本語 | Español | Français | Português | 中文 | Bahasa Indonesia | English
Sebelumnya | Berikutnya | Daftar Isi | Versi asli bahasa Inggris (gnu.org)

16 Konvensi makefile

Bab ini menjelaskan konvensi untuk menulis makefile bagi program GNU. Menggunakan Automake akan membantu Anda menulis makefile yang mengikuti konvensi ini. Untuk informasi lebih lanjut mengenai makefile yang portabel, lihat standar POSIX dan bagian Portable Make Programming dalam manual Autoconf.

16.1 Konvensi umum untuk makefile

Setiap makefile sebaiknya memuat baris berikut ini:

SHELL = /bin/sh

Ini untuk menghindari masalah pada sistem yang variabel SHELL-nya mungkin diwariskan dari lingkungan (environment). (Hal ini sama sekali tidak menjadi masalah pada GNU make.)

Program make yang berbeda-beda memiliki daftar sufiks dan aturan implisit yang saling tidak kompatibel, dan hal ini terkadang menimbulkan kebingungan atau perilaku yang salah. Karena itu, sebaiknya Anda menetapkan daftar sufiks secara eksplisit, hanya dengan sufiks yang diperlukan dalam makefile tersebut, seperti berikut:

.SUFFIXES:
.SUFFIXES: .c .o

Baris pertama mengosongkan daftar sufiks, dan baris kedua memperkenalkan semua sufiks yang dapat dikenai aturan implisit dalam makefile ini.

Jangan berasumsi bahwa .(direktori saat ini) termasuk dalam path untuk eksekusi perintah. Ketika Anda perlu menjalankan program yang merupakan bagian dari paket Anda selama proses make berlangsung, pastikan program tersebut memakai ./ jika program itu dibangun sebagai bagian dari make, atau $(srcdir)/ jika file tersebut adalah bagian kode sumber yang tidak berubah. Tanpa salah satu awalan ini, path pencarian yang berlaku saat itu akan digunakan.

Perbedaan antara ./(direktori build) dan $(srcdir)/(direktori sumber) ini penting, karena pengguna dapat melakukan build di direktori terpisah dengan menggunakan opsi ‘--srcdir’ pada configure. Aturan dengan bentuk berikut,

foo.1 : foo.man sedscript
        sed -f sedscript foo.man > foo.1

akan gagal ketika direktori build berbeda dari direktori sumber, karena foo.man dan sedscript berada di direktori sumber.

Ketika menggunakan GNU make, mengandalkan ‘VPATH’ untuk menemukan file sumber akan berhasil dalam kasus ketika hanya ada satu file prasyarat, karena variabel otomatis make$<’ akan mewakili file sumber tersebut di mana pun letaknya. (Banyak versi make hanya menetapkan ‘$<’ dalam aturan implisit.) Target makefile seperti berikut,

foo.o : bar.c
        $(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o

sebaiknya ditulis sebagai berikut.

foo.o : bar.c
        $(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@

agar ‘VPATH’ berfungsi dengan benar. Ketika target memiliki beberapa prasyarat, menggunakan ‘$(srcdir)’ secara eksplisit adalah cara termudah agar aturan tersebut bekerja dengan baik. Sebagai contoh, target foo.1 sebelumnya sebaiknya ditulis sebagai berikut:

foo.1 : foo.man sedscript
        sed -f $(srcdir)/sedscript $(srcdir)/foo.man > $@

Distribusi GNU biasanya memuat beberapa file yang bukan file sumber — misalnya file Info, dan keluaran dari Autoconf, Automake, Bison, atau Flex. Karena file-file ini biasanya muncul di direktori sumber, file-file tersebut harus selalu berada di direktori sumber, bukan di direktori build. Oleh karena itu, aturan makefile yang memperbarui file-file ini harus menempatkan file hasil pembaruan di direktori sumber.

Namun, untuk file yang tidak termasuk dalam distribusi, makefile tidak boleh menempatkannya di direktori sumber, karena membangun program dalam keadaan normal tidak boleh mengubah direktori sumber sama sekali.

Usahakan agar setidaknya target build dan instalasi (beserta semua subtargetnya) bekerja dengan benar pada make paralel.

16.2 Utilitas yang dapat digunakan dalam makefile

Tulislah perintah makefile (dan skrip shell apa pun, seperti configure) agar berjalan di bawah sh(baik shell Bourne tradisional maupun shell POSIX), bukan csh. Jangan gunakan fitur khusus ksh atau bash, maupun fitur POSIX yang tidak didukung secara luas oleh sh Bourne tradisional.

Skrip configure serta aturan makefile untuk build dan instalasi sebaiknya tidak menggunakan utilitas lain secara langsung selain berikut ini:

awk cat cmp cp diff echo expr false grep install-info ln ls
mkdir mv printf pwd rm rmdir sed sleep sort tar test touch tr true

Program kompresi seperti gzip boleh digunakan dalam aturan dist.

Pada dasarnya, gunakan hanya opsi dan fitur yang didukung secara luas (biasanya ditetapkan oleh POSIX) dari program-program ini. Misalnya, jangan gunakan ‘mkdir -p’ meskipun praktis, karena beberapa sistem sama sekali tidak mendukungnya, dan pada sistem lain hal ini tidak aman untuk eksekusi paralel. Untuk daftar ketidakkompatibelan yang diketahui, lihat bagian Portable Shell Programming dalam manual Autoconf.

Sebaiknya hindari membuat tautan simbolik (symbolic link) di dalam makefile, karena sebagian kecil sistem file tidak mendukungnya.

Aturan makefile untuk build dan instalasi juga dapat menggunakan kompiler dan program terkait, tetapi sebaiknya digunakan melalui variabel make agar pengguna dapat menggantinya dengan program lain. Berikut beberapa program yang dimaksud:

ar bison cc flex install ld ldconfig lex
make makeinfo ranlib texi2dvi yacc

Gunakan variabel make berikut untuk menjalankan program-program tersebut:

$(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LDCONFIG) $(LEX)
$(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)

Ketika Anda menggunakan ranlib atau ldconfig, pastikan tidak ada masalah yang timbul jika sistem tidak memiliki program tersebut. Aturlah agar error dari perintah itu diabaikan, dan tampilkan pesan sebelum perintah dijalankan untuk memberi tahu pengguna bahwa kegagalan perintah ini bukan masalah. (Makro ‘AC_PROG_RANLIB’ pada Autoconf dapat membantu untuk hal ini.)

Jika Anda menggunakan tautan simbolik, sebaiknya sediakan mekanisme cadangan (fallback) untuk sistem yang tidak memiliki tautan simbolik.

Utilitas lain yang dapat digunakan melalui variabel make meliputi:

chgrp chmod chown mknod

Pada bagian makefile (atau skrip) yang memang ditujukan hanya untuk sistem tertentu, boleh menggunakan utilitas lain jika Anda tahu bahwa utilitas tersebut ada pada sistem itu.

16.3 Variabel untuk menentukan perintah

makefile sebaiknya menyediakan variabel agar perintah, opsi, dan sejenisnya tertentu dapat ditimpa (override).

Khususnya, sebagian besar program utilitas sebaiknya dijalankan melalui variabel. Sebagai contoh, jika Anda menggunakan Bison, sediakan variabel bernama BISON dengan nilai default yang ditetapkan melalui ‘BISON = bison’, dan rujuklah dengan $(BISON) setiap kali Anda perlu menggunakan Bison.

Utilitas manajemen file seperti ln, rm, dan mv tidak perlu dirujuk melalui variabel dengan cara ini, karena pengguna tidak perlu menggantinya dengan program lain.

Setiap variabel nama program sebaiknya disertai variabel opsi yang digunakan untuk memberikan opsi kepada program tersebut. Nama variabel opsi dibuat dengan menambahkan ‘FLAGS’ di akhir nama variabel nama program — misalnya BISONFLAGS. (Nama CFLAGS untuk kompiler C, YFLAGS untuk yacc, dan LFLAGS untuk lex merupakan pengecualian dari aturan ini, tetapi tetap dipertahankan karena sudah menjadi nama standar.) Gunakan CPPFLAGS dalam perintah kompilasi apa pun yang menjalankan praprosesor, dan gunakan LDFLAGS dalam perintah kompilasi yang juga melakukan penautan maupun dalam penggunaan ld secara langsung.

Jika ada opsi kompiler C yang harus digunakan agar file tertentu dikompilasi dengan benar, jangan masukkan opsi tersebut ke dalam CFLAGS. Pengguna berharap dapat menentukan CFLAGS secara bebas sesuai keinginan mereka sendiri. Sebagai gantinya, aturlah agar opsi yang diperlukan diteruskan ke kompiler C secara independen dari CFLAGS, dengan menuliskannya secara eksplisit dalam perintah kompilasi atau dengan mendefinisikan aturan implisit, seperti berikut:

CFLAGS = -g
ALL_CFLAGS = -I. $(CFLAGS)
.c.o:
        $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<

Sertakan opsi ‘-g’ ke dalam CFLAGS, karena opsi ini tidak wajib untuk kompilasi yang benar. Anggap saja opsi ini sebagai default yang sekadar direkomendasikan. Jika paket disiapkan agar dikompilasi dengan GCC secara default, Anda juga boleh menyertakan ‘-O’ dalam nilai default CFLAGS.

Letakkan CFLAGS di posisi terakhir dalam perintah kompilasi, setelah variabel lain yang berisi opsi kompiler. Dengan begitu, pengguna dapat menggunakan CFLAGS untuk menimpa opsi lainnya.

CFLAGS sebaiknya digunakan pada setiap pemanggilan kompiler C, baik saat melakukan kompilasi maupun penautan.

Setiap makefile sebaiknya mendefinisikan variabel INSTALL, yaitu perintah dasar untuk menginstal file ke dalam sistem.

Setiap makefile sebaiknya juga mendefinisikan variabel INSTALL_PROGRAM dan INSTALL_DATA. (Nilai default INSTALL_PROGRAM sebaiknya $(INSTALL); nilai default INSTALL_DATA sebaiknya ${INSTALL} -m 644.) Kemudian, gunakan kedua variabel ini sebagai perintah instalasi yang sebenarnya — variabel yang pertama untuk file executable, dan variabel yang kedua untuk file non-executable. Penggunaan minimal dari variabel-variabel ini adalah sebagai berikut:

$(INSTALL_PROGRAM) foo $(bindir)/foo
$(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a

Namun, sebagaimana dijelaskan pada bagian berikutnya, akan lebih baik jika Anda mendukung awalan DESTDIR pada file target.

Menginstal beberapa file sekaligus dalam satu perintah, dengan argumen terakhir berupa direktori, juga diperbolehkan (meskipun tidak wajib), seperti berikut:

$(INSTALL_PROGRAM) foo bar baz $(bindir)

16.4 DESTDIR: Dukungan untuk instalasi bertahap

DESTDIR adalah variabel yang ditambahkan di depan setiap file target yang diinstal, seperti berikut:

$(INSTALL_PROGRAM) foo $(DESTDIR)$(bindir)/foo
$(INSTALL_DATA) libfoo.a $(DESTDIR)$(libdir)/libfoo.a

Variabel DESTDIR ditentukan oleh pengguna pada baris perintah make sebagai nama file absolut. Sebagai contoh:

make DESTDIR=/tmp/stage install

DESTDIR sebaiknya hanya didukung pada target install* dan uninstall*, karena hanya target-target inilah yang membuat DESTDIR berguna.

Jika langkah instalasi Anda biasanya menginstal /usr/local/bin/foo dan /usr/local/lib/libfoo.a, maka instalasi yang dijalankan seperti pada contoh di atas akan menginstal /tmp/stage/usr/local/bin/foo dan /tmp/stage/usr/local/lib/libfoo.a sebagai gantinya.

Dengan menambahkan variabel DESTDIR di depan setiap target seperti ini, instalasi bertahap(staged install) menjadi mungkin dilakukan. Ini adalah cara menyalin file yang diinstal terlebih dahulu ke lokasi sementara (DESTDIR), alih-alih menempatkannya langsung di lokasi yang seharusnya. Meskipun begitu, struktur direktori relatif dari file yang diinstal tetap terjaga, dan nama file mana pun yang tertanam di dalam file tidak akan diubah.

Anda sama sekali tidak boleh menetapkan nilai DESTDIR di dalam Makefile; dengan begitu, secara default file akan diinstal ke lokasi yang seharusnya. Selain itu, penetapan DESTDIR tidak boleh mengubah operasi perangkat lunak dengan cara apa pun, sehingga nilainya tidak boleh dimasukkan ke dalam isi file apa pun.

Dukungan DESTDIR sering digunakan dalam pembuatan paket. Fitur ini juga berguna bagi pengguna yang ingin memahami apa yang akan diinstal oleh suatu paket dan ke mana, serta bagi pengguna yang tidak memiliki izin instalasi ke area yang dilindungi tetapi ingin menyelesaikan build dan instalasi terlebih dahulu sebelum memperoleh izin tersebut. Selain itu, fitur ini berguna untuk alat seperti stow, yaitu alat yang menginstal kode di satu lokasi tetapi membuatnya tampak terinstal di lokasi lain melalui tautan simbolik atau operasi mount khusus. Karena alasan-alasan ini, meskipun bukan persyaratan mutlak, kami sangat menganjurkan agar paket GNU mendukung DESTDIR.

16.5 Variabel untuk direktori instalasi

Direktori instalasi harus selalu diberi nama melalui variabel, agar mudah diinstal ke lokasi nonstandar. Nama standar untuk variabel-variabel ini, beserta nilai yang sebaiknya ditetapkan pada paket GNU, dijelaskan di bawah ini. Nama-nama ini didasarkan pada tata letak sistem file standar, yang variannya digunakan pada GNU/Linux dan sistem operasi modern lainnya.

Pengguna yang menginstal diharapkan dapat menimpa nilai-nilai ini saat memanggil make(misalnya, make prefix=/usr install) atau configure(misalnya, configure --prefix=/usr). Paket GNU tidak boleh berusaha menebak nilai yang cocok untuk variabel-variabel ini pada sistem tempat paket tersebut diinstal: gunakan pengaturan default yang ditentukan di sini, sehingga semua paket GNU berperilaku sama, dan pengguna yang menginstal dapat mencapai tata letak yang diinginkan.

Direktori instalasi beserta direktori induknya harus dibuat terlebih dahulu (jika perlu) sebelum melakukan instalasi ke dalamnya.

Dua variabel pertama menetapkan root (titik dasar) instalasi. Semua direktori instalasi lainnya sebaiknya berupa subdirektori dari salah satu dari kedua direktori ini, dan tidak boleh ada apa pun yang diinstal langsung ke kedua direktori ini.

prefix

Awalan (prefix) yang digunakan untuk menyusun nilai default variabel-variabel yang tercantum di bawah ini. Nilai default prefix sebaiknya /usr/local. Ketika membangun sistem GNU yang lengkap, prefix akan kosong dan /usr menjadi tautan simbolik ke /. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@prefix@’.)

Menjalankan ‘make install’ dengan nilai prefix yang berbeda dari nilai yang dipakai saat membangun program tidak boleh menyebabkan program dikompilasi ulang.

exec_prefix

Awalan yang digunakan untuk menyusun nilai default sebagian variabel yang tercantum di bawah ini. Nilai default exec_prefix sebaiknya $(prefix). (Jika Anda menggunakan Autoconf, tulis sebagai ‘@exec_prefix@’.)

Secara umum, $(exec_prefix) digunakan untuk direktori yang berisi file khusus mesin (seperti file executable dan pustaka (library) subrutin), sedangkan $(prefix) digunakan langsung untuk direktori lainnya.

Menjalankan ‘make install’ dengan nilai exec_prefix yang berbeda dari nilai yang dipakai saat membangun program tidak boleh menyebabkan program dikompilasi ulang.

Program yang dapat dieksekusi diinstal ke salah satu direktori berikut.

bindir

Direktori untuk menginstal program executable yang dapat dijalankan oleh pengguna. Biasanya /usr/local/bin, tetapi tulis sebagai $(exec_prefix)/bin. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@bindir@’.)

sbindir

Direktori untuk menginstal program executable yang dapat dijalankan dari shell, tetapi umumnya hanya berguna bagi administrator sistem. Biasanya /usr/local/sbin, tetapi tulis sebagai $(exec_prefix)/sbin. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@sbindir@’.)

libexecdir

Direktori untuk menginstal program executable yang dijalankan oleh program lain, bukan oleh pengguna. Biasanya /usr/local/libexec, tetapi tulis sebagai $(exec_prefix)/libexec. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@libexecdir@’.)

Definisi ‘libexecdir’ sama untuk semua paket, sehingga sebaiknya Anda menginstal data paket Anda ke dalam subdirektorinya. Sebagian besar paket menginstal datanya di bawah $(libexecdir)/package-name/, dan mungkin lebih jauh lagi ke dalam subdirektori tambahan, misalnya $(libexecdir)/package-name/machine/version.

File data yang digunakan program saat berjalan diklasifikasikan berdasarkan dua sudut pandang.

Ini menghasilkan enam kemungkinan. Namun, selain file objek dan pustaka, kami tidak menganjurkan penggunaan file yang bergantung pada arsitektur. Jauh lebih rapi untuk membuat file data lainnya tidak bergantung pada arsitektur, dan biasanya hal ini juga tidak terlalu sulit.

Berikut adalah variabel yang sebaiknya digunakan makefile untuk menentukan lokasi berbagai jenis file ini:

datarootdir

Root dari pohon direktori untuk file data yang bersifat baca-saja dan tidak bergantung pada arsitektur. Biasanya /usr/local/share, tetapi tulis sebagai $(prefix)/share. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@datarootdir@’.) Nilai default ‘datadir’ didasarkan pada variabel ini, begitu pula ‘infodir’, ‘mandir’, dan lainnya.

datadir

Direktori untuk menginstal file data yang bersifat baca-saja, tidak bergantung pada arsitektur, dan khas untuk program ini. Biasanya berada di lokasi yang sama dengan ‘datarootdir’, tetapi kedua variabel ini dipisahkan agar Anda dapat memindahkan file khas program ini tanpa mengubah lokasi file Info, halaman man, dan sejenisnya.

Biasanya /usr/local/share, tetapi tulis sebagai $(datarootdir). (Jika Anda menggunakan Autoconf, tulis sebagai ‘@datadir@’.)

Definisi ‘datadir’ sama untuk semua paket, sehingga sebaiknya Anda menginstal data Anda ke dalam subdirektorinya. Sebagian besar paket menginstal datanya di bawah $(datadir)/package-name/.

sysconfdir

Direktori untuk menginstal file data baca-saja yang berkaitan dengan satu mesin — yaitu, file untuk mengonfigurasi host. File konfigurasi mailer dan jaringan, /etc/passwd, dan sejenisnya termasuk di sini. Semua file dalam direktori ini sebaiknya berupa file teks ASCII biasa. Biasanya /usr/local/etc, tetapi tulis sebagai $(prefix)/etc. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@sysconfdir@’.)

Jangan instal file executable ke dalam direktori ini (file tersebut mungkin sebaiknya berada di $(libexecdir) atau $(sbindir)). Jangan pula instal file yang berubah dalam pemakaian normal (kecuali program yang memang bertujuan mengubah konfigurasi sistem). File semacam itu mungkin sebaiknya berada di $(localstatedir).

sharedstatedir

Direktori untuk menginstal file data yang tidak bergantung pada arsitektur dan diubah oleh program saat berjalan. Biasanya /usr/local/com, tetapi tulis sebagai $(prefix)/com. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@sharedstatedir@’.)

localstatedir

Direktori untuk menginstal file data yang diubah oleh program saat berjalan dan berkaitan dengan satu mesin tertentu. Pengguna sama sekali tidak boleh perlu mengubah file dalam direktori ini untuk mengonfigurasi operasi paket; letakkan informasi konfigurasi semacam itu dalam file terpisah di $(datadir) atau $(sysconfdir). $(localstatedir) biasanya /usr/local/var, tetapi tulis sebagai $(prefix)/var. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@localstatedir@’.)

runstatedir

Direktori untuk menginstal file data yang diubah oleh program saat berjalan, berkaitan dengan satu mesin tertentu, dan tidak perlu bertahan lebih lama daripada masa eksekusi program tersebut, yang umumnya berumur panjang — misalnya hingga reboot berikutnya. File PID untuk daemon sistem adalah contoh penggunaan yang khas. Selain itu, direktori ini sebaiknya tidak dibersihkan kecuali pada saat reboot, sedangkan /tmp(TMPDIR) yang umum boleh dibersihkan kapan saja. Biasanya /var/run, tetapi tulis sebagai $(localstatedir)/run. Variabel ini dipisahkan agar, misalnya, Anda dapat menggunakan /run jika diinginkan. (Jika Anda menggunakan Autoconf 2.70 atau yang lebih baru, tulis sebagai ‘@runstatedir@’.)

Variabel berikut menentukan direktori untuk menginstal jenis file tertentu, jika program Anda memilikinya. Setiap paket GNU sebaiknya memiliki file Info, sehingga setiap program memerlukan ‘infodir’, tetapi tidak semua program memerlukan ‘libdir’ atau ‘lispdir’.

includedir

Direktori untuk menginstal file header yang akan disertakan program pengguna melalui direktif praprosesor C ‘#include’. Biasanya /usr/local/include, tetapi tulis sebagai $(prefix)/include. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@includedir@’.)

Sebagian besar kompiler selain GCC tidak mencari file header di direktori /usr/local/include. Oleh karena itu, menginstal file header dengan cara ini hanya berguna jika menggunakan GCC. Kadang hal ini bukan masalah karena beberapa pustaka memang hanya ditujukan untuk bekerja dengan GCC. Namun, ada pula pustaka yang ditujukan untuk bekerja dengan kompiler lain. Pustaka semacam itu sebaiknya menginstal file headernya di dua tempat, yaitu tempat yang ditentukan oleh includedir dan tempat yang ditentukan oleh oldincludedir.

oldincludedir

Direktori untuk menginstal file header ‘#include’ yang digunakan dengan kompiler selain GCC. Biasanya /usr/include. (Jika Anda menggunakan Autoconf, dapat ditulis sebagai ‘@oldincludedir@’.)

Perintah makefile sebaiknya memeriksa apakah nilai oldincludedir kosong. Jika kosong, jangan mencoba menggunakannya; batalkan instalasi kedua file header tersebut.

Paket tidak boleh menggantikan header yang sudah ada di direktori ini, kecuali jika header tersebut berasal dari paket yang sama. Jadi, jika paket Foo Anda menyediakan file header foo.h, maka file header tersebut sebaiknya diinstal ke direktori oldincludedir hanya jika (1) belum ada foo.h di sana, atau (2) foo.h yang ada di sana berasal dari paket Foo.

Untuk mengetahui apakah foo.h berasal dari paket Foo, sisipkan string khusus penanda (sebagai bagian dari komentar) di dalam file tersebut, lalu cari string itu dengan grep.

docdir

Direktori untuk menginstal file dokumentasi (selain Info) untuk paket ini. Secara default sebaiknya /usr/local/share/doc/yourpkg, tetapi tulis sebagai $(datarootdir)/doc/yourpkg. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@docdir@’.) Subdirektori yourpkg(yang boleh menyertakan nomor versi) mencegah tabrakan antara file dengan nama umum seperti README.

infodir

Direktori untuk menginstal file Info paket ini. Secara default sebaiknya /usr/local/share/info, tetapi tulis sebagai $(datarootdir)/info. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@infodir@’.) infodir dipisahkan dari docdir demi kompatibilitas dengan praktik yang sudah ada.

htmldir
dvidir
pdfdir
psdir

Direktori untuk menginstal file dokumentasi dalam format tertentu masing-masing. Semuanya sebaiknya diset ke $(docdir) secara default. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@htmldir@’, ‘@dvidir@’, dan seterusnya.) Paket yang menyediakan beberapa terjemahan dokumentasinya sebaiknya menginstalnya di ‘$(htmldir)/ll, ‘$(pdfdir)/ll, dan seterusnya, dengan ll berupa singkatan locale seperti ‘en’ atau ‘pt_BR’.

libdir

Direktori untuk file objek dan pustaka kode objek. Jangan instal file executable di sini; file tersebut sebaiknya diletakkan di $(libexecdir). Nilai libdir biasanya /usr/local/lib, tetapi tulis sebagai $(exec_prefix)/lib. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@libdir@’.)

lispdir

Direktori untuk menginstal file Emacs Lisp dalam paket ini. Secara default sebaiknya /usr/local/share/emacs/site-lisp, tetapi tulis sebagai $(datarootdir)/emacs/site-lisp.

Jika Anda menggunakan Autoconf, tulis default sebagai ‘@lispdir@’. Agar ‘@lispdir@’ berfungsi, Anda memerlukan baris berikut dalam file configure.ac:

lispdir='${datarootdir}/emacs/site-lisp'
AC_SUBST(lispdir)
localedir

Direktori untuk menginstal katalog pesan khusus locale paket ini. Secara default sebaiknya /usr/local/share/locale, tetapi tulis sebagai $(datarootdir)/locale. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@localedir@’.) Direktori ini biasanya memiliki subdirektori untuk setiap locale.

Halaman man bergaya Unix diinstal ke salah satu dari berikut ini:

mandir

Direktori tingkat atas untuk menginstal halaman man (jika ada) paket ini. Biasanya /usr/local/share/man, tetapi sebaiknya ditulis sebagai $(datarootdir)/man. (Jika Anda menggunakan Autoconf, tulis sebagai ‘@mandir@’.)

man1dir

Direktori untuk menginstal halaman man bagian 1. Tulis sebagai $(mandir)/man1.

man2dir

Direktori untuk menginstal halaman man bagian 2. Tulis sebagai $(mandir)/man2

Jangan jadikan halaman man sebagai dokumentasi utama untuk perangkat lunak GNU mana pun. Sebagai gantinya, tulislah manual dalam Texinfo. Halaman man semata-mata untuk kepentingan orang yang menjalankan perangkat lunak GNU pada Unix, yang hanya merupakan aplikasi sekunder.

manext

Ekstensi nama file untuk halaman man yang diinstal. Ekstensi ini sebaiknya berupa titik yang diikuti oleh angka yang sesuai; biasanya ‘.1’.

man1ext

Ekstensi nama file untuk halaman man bagian 1 yang diinstal.

man2ext

Ekstensi nama file untuk halaman man bagian 2 yang diinstal.

Jika paket Anda perlu menginstal halaman man ke lebih dari satu bagian manual, gunakan nama-nama ini sebagai pengganti ‘manext’.

Dan terakhir, Anda sebaiknya menetapkan variabel berikut:

srcdir

Direktori tempat sumber yang akan dikompilasi berada. Nilai variabel ini biasanya disisipkan oleh skrip shell configure. (Jika Anda menggunakan Autoconf, gunakan ‘srcdir = @srcdir@’.)

Berikut contohnya:

# Common prefix for installation directories.
# NOTE: This directory must exist when you start the install.
prefix = /usr/local
datarootdir = $(prefix)/share
datadir = $(datarootdir)
exec_prefix = $(prefix)
# Where to put the executable for the command 'gcc'.
bindir = $(exec_prefix)/bin
# Where to put the directories used by the compiler.
libexecdir = $(exec_prefix)/libexec
# Where to put the Info files.
infodir = $(datarootdir)/info

Jika program Anda menginstal banyak file ke salah satu direktori standar yang ditentukan pengguna, mungkin akan berguna untuk mengelompokkannya ke dalam subdirektori khusus program tersebut. Jika Anda melakukan ini, sebaiknya tulis aturan install agar membuat subdirektori tersebut.

Jangan berharap pengguna menyertakan nama subdirektori dalam nilai variabel mana pun yang disebutkan di atas. Gagasan memiliki satu set nama variabel yang seragam untuk direktori instalasi adalah untuk memungkinkan pengguna menentukan nilai yang persis sama untuk beberapa paket GNU yang berbeda. Agar hal ini berguna, semua paket harus dirancang agar berperilaku secara masuk akal ketika pengguna melakukannya.

Rilis Autoconf dan Automake saat ini mungkin belum mengimplementasikan semua variabel ini. Namun, mulai Autoconf 2.60, kami yakin semuanya sudah diimplementasikan. Jika ada yang belum diimplementasikan, penjelasan di sini berfungsi sebagai spesifikasi tentang apa yang seharusnya diimplementasikan oleh Autoconf. Sebagai programmer, Anda dapat memilih untuk menggunakan versi pengembangan Autoconf, atau menghindari penggunaan variabel-variabel tersebut sampai tersedia rilis stabil yang mendukungnya.

16.6 Target standar untuk pengguna

Semua program GNU sebaiknya memiliki target berikut dalam makefile-nya:

all

Mengompilasi seluruh program. Ini sebaiknya menjadi target default. Target ini tidak perlu membangun ulang file dokumentasi apa pun; file Info biasanya disertakan dalam distribusi, dan file DVI (atau format dokumentasi lainnya) sebaiknya hanya dibuat ketika diminta secara eksplisit.

Secara default, aturan Make sebaiknya mengompilasi dan menautkan dengan ‘-g’, sehingga program executable memiliki simbol debug. Jika tidak, Anda pada dasarnya tidak berdaya ketika menghadapi crash, dan seringkali tidak mudah untuk mereproduksinya dengan build baru.

install

Mengompilasi program dan menyalin file executable, pustaka, dan sejenisnya ke nama file tempat file-file tersebut seharusnya berada untuk pemakaian sebenarnya. Jika ada tes sederhana untuk memverifikasi bahwa program terinstal dengan benar, target ini sebaiknya menjalankan tes tersebut.

Jangan men-strip (menghapus simbol) file executable saat menginstalnya. Ini membantu proses debug yang mungkin diperlukan nanti, dan lagi pula ruang disk sekarang murah, sementara loader dinamis umumnya memastikan bagian debug tidak dimuat selama eksekusi normal. Pengguna yang memerlukan biner yang sudah di-strip dapat menjalankan target install-strip.

Jika memungkinkan, tulislah aturan target install agar tidak mengubah apa pun di direktori tempat program dibangun, segera setelah ‘make all’ selesai dijalankan. Ini berguna untuk membangun program dengan satu nama pengguna dan menginstalnya dengan nama pengguna lain.

Perintah-perintah tersebut sebaiknya membuat semua direktori tempat file akan diinstal, jika direktori itu belum ada. Ini mencakup direktori yang ditentukan sebagai nilai variabel prefix dan exec_prefix, serta semua subdirektori yang diperlukan. Salah satu caranya adalah dengan menggunakan target installdirs yang dijelaskan nanti.

Tambahkan ‘-’ sebelum perintah untuk menginstal halaman man, agar make mengabaikan error apa pun. Ini untuk berjaga-jaga jika ada sistem yang tidak memiliki sistem dokumentasi halaman man Unix terinstal.

Cara menginstal file Info adalah dengan menyalinnya ke $(infodir) menggunakan $(INSTALL_DATA) (lihat Variabel untuk menentukan perintah), lalu menjalankan program install-info jika ada. install-info adalah program yang mengedit file dir Info untuk menambahkan atau memperbarui entri menu bagi file Info yang diberikan; program ini merupakan bagian dari paket Texinfo.

Berikut contoh aturan untuk menginstal file Info, yang juga berupaya menangani beberapa situasi tambahan, misalnya ketika install-info tidak ada.

do-install-info: foo.info installdirs
        $(NORMAL_INSTALL)
# Prefer an info file in . to one in srcdir.
        if test -f foo.info; then d=.; \
         else d="$(srcdir)"; fi; \
        $(INSTALL_DATA) $$d/foo.info \
          "$(DESTDIR)$(infodir)/foo.info"
# Run install-info only if it exists.
# Use 'if' instead of just prepending '-' to the
# line so we notice real errors from install-info.
# Use '$(SHELL) -c' because some shells do not
# fail gracefully when there is an unknown command.
        $(POST_INSTALL)
        if $(SHELL) -c 'install-info --version' \
           >/dev/null 2>&1; then \
          install-info --dir-file="$(DESTDIR)$(infodir)/dir" \
                       "$(DESTDIR)$(infodir)/foo.info"; \
        else true; fi

Saat menulis target install, Anda harus mengklasifikasikan semua perintah ke dalam tiga kategori, yaitu perintah normal, perintah pra-instalasi (pre-installation), dan perintah pasca-instalasi (post-installation). Lihat Kategori perintah instalasi.

install-html
install-dvi
install-pdf
install-ps

Target-target ini menginstal dokumentasi dalam format selain Info; target-target ini dimaksudkan untuk dipanggil secara eksplisit oleh orang yang menginstal paket, jika format tersebut diinginkan. GNU lebih menyukai file Info, sehingga Info harus diinstal melalui target install.

Jika Anda memiliki banyak file dokumentasi untuk diinstal, kami menyarankan agar target-target ini diatur untuk menginstal ke subdirektori dari direktori instalasi yang sesuai, seperti htmldir, guna menghindari tabrakan dan kekacauan. Sebagai contoh, jika paket Anda memiliki beberapa manual dan Anda ingin menginstal dokumentasi HTML dengan banyak file (misalnya keluaran mode “split” dari makeinfo --html), Anda hampir pasti ingin menggunakan subdirektori. Jika tidak, dua node dengan nama yang sama pada manual yang berbeda akan saling menimpa.

Buatlah target install-format ini memanggil perintah untuk target format, misalnya dengan menjadikan format sebagai prasyarat.

uninstall

Menghapus semua file yang terinstal — yaitu salinan yang dibuat oleh target ‘install’ dan ‘install-*’.

Aturan ini tidak boleh mengubah direktori tempat kompilasi dilakukan; aturan ini hanya boleh menyasar direktori tempat file diinstal.

Perintah uninstall diklasifikasikan ke dalam tiga kategori, sama seperti perintah instalasi. Lihat Kategori perintah instalasi.

install-strip

Sama seperti install, tetapi men-strip file executable saat menginstalnya. Dalam kasus sederhana, target ini dapat memanfaatkan target install dengan mudah seperti berikut:

install-strip:
        $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \
                install

Namun, jika paket menginstal skrip selain file executable sungguhan, target install-strip tidak bisa sekadar merujuk ke target install; target ini harus men-strip file executable tetapi tidak men-strip skrip.

install-strip tidak boleh men-strip file executable di direktori build yang sedang disalin untuk instalasi. Target ini hanya boleh men-strip salinan yang terinstal.

Umumnya kami tidak menyarankan men-strip file executable kecuali Anda yakin program tersebut tidak memiliki bug. Namun, cukup masuk akal untuk menginstal file executable yang sudah di-strip untuk eksekusi sesungguhnya sambil menyimpan file executable yang belum di-strip di tempat lain untuk berjaga-jaga jika ada bug.

clean

Menghapus semua file di direktori saat ini yang biasanya dibuat selama proses membangun program. Juga menghapus file di direktori lain jika file tersebut dibuat oleh makefile ini. Namun, jangan hapus file yang mencatat hasil konfigurasi (configure). Pertahankan juga file yang dapat dibuat melalui build tetapi biasanya tidak dibuat karena sudah disertakan dalam distribusi. Tidak perlu menghapus direktori induk yang dibuat dengan ‘mkdir -p’, karena direktori tersebut mungkin sudah ada sejak awal.

Hapus file .dvi di sini jika file tersebut tidak termasuk dalam distribusi.

distclean

Menghapus semua file di direktori saat ini (atau yang dibuat oleh makefile ini) yang dibuat oleh proses konfigurasi (configure) atau build program. Jika Anda mengekstrak sumber dan membangun program tanpa membuat file lain sama sekali, menjalankan ‘make distclean’ seharusnya hanya menyisakan file yang ada dalam distribusi. Namun, tidak perlu menghapus direktori induk yang dibuat dengan ‘mkdir -p’, karena direktori tersebut mungkin sudah ada sejak awal.

mostlyclean

Mirip dengan ‘clean’, tetapi boleh menahan diri untuk tidak menghapus beberapa file yang biasanya tidak ingin dikompilasi ulang oleh orang. Sebagai contoh, target ‘mostlyclean’ pada GCC tidak menghapus libgcc.a, karena file ini jarang perlu dikompilasi ulang dan memakan banyak waktu.

maintainer-clean

Menghapus hampir semua yang dapat dibangun ulang dengan makefile ini. Biasanya ini mencakup semua yang dihapus oleh distclean, ditambah lebih banyak lagi: file sumber C yang dihasilkan oleh Bison, tabel tags, file Info, dan sebagainya.

Alasan kami mengatakan “hampir semua” adalah karena menjalankan perintah ‘make maintainer-clean’ tidak boleh menghapus configure, meskipun configure dapat dibuat ulang melalui aturan dalam makefile. Secara lebih umum, ‘make maintainer-clean’ tidak boleh menghapus apa pun yang perlu ada agar configure dapat dijalankan dan pembangunan program dapat dimulai. Selain itu, tidak perlu menghapus direktori induk yang dibuat dengan ‘mkdir -p’, karena direktori tersebut mungkin sudah ada sejak awal. Ini adalah satu-satunya pengecualian; maintainer-clean sebaiknya menghapus semua yang lain yang dapat dibangun ulang.

Target ‘maintainer-clean’ dimaksudkan untuk digunakan oleh pemelihara (maintainer) paket, bukan oleh pengguna biasa. Anda mungkin memerlukan alat khusus untuk membangun ulang sebagian file yang dihapus oleh ‘make maintainer-clean’. Karena file-file ini biasanya sudah termasuk dalam distribusi, kami tidak berupaya membuatnya mudah dibangun ulang. Jika ternyata Anda perlu mengekstrak ulang distribusi lengkapnya, jangan salahkan kami.

Untuk membantu pengguna menyadari hal ini, perintah untuk target khusus maintainer-clean sebaiknya dimulai dengan dua baris berikut:

@echo 'This command is intended for maintainers to use; it'
@echo 'deletes files that may need special tools to rebuild.'
TAGS

Memperbarui tabel tags untuk program ini.

info

Menghasilkan file Info yang diperlukan. Cara terbaik menulis aturannya adalah sebagai berikut:

info: foo.info

foo.info: foo.texi chap1.texi chap2.texi
        $(MAKEINFO) $(srcdir)/foo.texi

Anda harus mendefinisikan variabel MAKEINFO dalam makefile. Variabel ini sebaiknya menjalankan program makeinfo, yang merupakan bagian dari distribusi Texinfo.

Biasanya, distribusi GNU disertai file Info, yang berarti file Info sudah ada di direktori sumber. Oleh karena itu, aturan Make untuk file Info sebaiknya memperbaruinya di direktori sumber. Ketika pengguna membangun paket, Make biasanya tidak akan memperbarui file Info karena file tersebut sudah mutakhir.

dvi
html
pdf
ps

Menghasilkan file dokumentasi dalam format yang ditentukan. Target-target ini sebaiknya selalu ada, tetapi boleh saja tidak melakukan apa-apa (no-op), sebagian atau seluruhnya, jika format keluaran tersebut tidak dapat dihasilkan. Target-target ini sebaiknya tidak dijadikan prasyarat target all. Biarkan pengguna menjalankannya secara manual.

Berikut contoh aturan untuk menghasilkan file DVI dari Texinfo:

dvi: foo.dvi

foo.dvi: foo.texi chap1.texi chap2.texi
        $(TEXI2DVI) $(srcdir)/foo.texi

Anda harus mendefinisikan variabel TEXI2DVI dalam makefile. Variabel ini sebaiknya menjalankan program texi2dvi, yang merupakan bagian dari distribusi Texinfo. (texi2dvi menggunakan TeX untuk melakukan pekerjaan penataan (typesetting) yang sesungguhnya. TeX tidak disertakan bersama Texinfo.) Sebagai alternatif, Anda cukup menuliskan prasyaratnya saja dan membiarkan GNU make menyediakan perintahnya.

Berikut contoh lain, untuk menghasilkan HTML dari Texinfo:

html: foo.html

foo.html: foo.texi chap1.texi chap2.texi
        $(TEXI2HTML) $(srcdir)/foo.texi

Dalam hal ini juga, definisikan variabel TEXI2HTML dalam makefile — misalnya agar menjalankan makeinfo --no-split --html (makeinfo adalah bagian dari distribusi Texinfo).

dist

Membuat file tar distribusi untuk program ini. File tar sebaiknya dibuat sedemikian rupa sehingga nama file di dalamnya diawali dengan nama subdirektori, yaitu nama paket yang didistribusikan. Nama ini boleh menyertakan nomor versi.

Sebagai contoh, file tar distribusi GCC versi 1.40 diekstrak ke dalam subdirektori bernama gcc-1.40.

Cara termudah melakukannya adalah dengan membuat subdirektori bernama sesuai, menggunakan ln atau cp untuk menempatkan file yang diperlukan di dalamnya, lalu mem-tar subdirektori tersebut.

Kompres file tar dengan gzip. Sebagai contoh, file distribusi sebenarnya untuk GCC versi 1.40 bernama gcc-1.40.tar.gz. Anda boleh mendukung format kompresi bebas lainnya juga.

Target dist sebaiknya secara eksplisit bergantung pada semua file non-sumber yang ada dalam distribusi, untuk memastikan file-file tersebut mutakhir di dalam distribusi. Lihat bagian Making Releases dalam GNU Coding Standards.

check

Menjalankan uji mandiri (self-test), jika ada. Pengguna harus membangun program sebelum menjalankan tes, tetapi tidak perlu menginstalnya. Uji mandiri sebaiknya ditulis agar tetap berjalan selama program sudah dibangun, meskipun belum diinstal.

Target berikut disarankan sebagai nama konvensional bagi program yang memerlukannya.

installcheck

Menjalankan uji instalasi (installation test), jika ada. Pengguna harus membangun dan menginstal program sebelum menjalankan tes ini. Jangan berasumsi bahwa $(bindir) termasuk dalam path pencarian.

installdirs

Berguna untuk menambahkan target bernama ‘installdirs’ guna membuat direktori tempat file diinstal beserta direktori induknya. Ada skrip praktis bernama mkinstalldirs untuk keperluan ini; skrip ini dapat ditemukan dalam paket Gnulib. Anda dapat menggunakan aturan seperti berikut:

# Make sure all installation directories (e.g. $(bindir))
# actually exist by making them if necessary.
installdirs: mkinstalldirs
        $(srcdir)/mkinstalldirs $(bindir) $(datadir) \
                                $(libdir) $(infodir) \
                                $(mandir)

Atau, jika Anda ingin mendukung DESTDIR(sangat dianjurkan),

# Make sure all installation directories (e.g. $(bindir))
# actually exist by making them if necessary.
installdirs: mkinstalldirs
        $(srcdir)/mkinstalldirs \
            $(DESTDIR)$(bindir) $(DESTDIR)$(datadir) \
            $(DESTDIR)$(libdir) $(DESTDIR)$(infodir) \
            $(DESTDIR)$(mandir)

Aturan ini tidak boleh mengubah direktori tempat kompilasi dilakukan. Aturan ini tidak boleh melakukan apa pun selain membuat direktori instalasi.

16.7 Kategori perintah instalasi

Saat menulis target install, Anda harus mengklasifikasikan semua perintah ke dalam tiga kategori, yaitu perintah normal, perintah pra-instalasi (pre-installation), dan perintah pasca-instalasi (post-installation).

Perintah normal memindahkan file ke lokasi yang seharusnya dan menetapkan mode (izin akses) file tersebut. Perintah ini tidak boleh mengubah file apa pun kecuali yang sepenuhnya berasal dari paket yang bersangkutan.

Perintah pra-instalasi dan pasca-instalasi boleh mengubah file lain. Khususnya, perintah ini dapat mengedit file konfigurasi global atau basis data.

Perintah pra-instalasi biasanya dijalankan sebelum perintah normal, dan perintah pasca-instalasi biasanya dijalankan setelah perintah normal.

Penggunaan paling umum untuk perintah pasca-instalasi adalah menjalankan install-info. Ini tidak dapat dilakukan dengan perintah normal, karena perintah ini mengubah file (direktori Info) yang tidak sepenuhnya dan semata-mata berasal dari paket yang sedang diinstal. Perintah ini menjadi perintah pasca-instalasi karena perlu dijalankan setelah perintah normal yang menginstal file Info paket tersebut.

Sebagian besar program tidak memerlukan perintah pra-instalasi, tetapi fitur ini disediakan untuk berjaga-jaga jika suatu saat diperlukan.

Untuk mengklasifikasikan perintah dalam aturan install ke dalam ketiga kategori ini, sisipkan baris kategori (category line) di antaranya. Baris kategori menentukan kategori untuk perintah yang mengikutinya.

Baris kategori terdiri atas tab, referensi ke variabel Make khusus, dan komentar opsional di akhir. Ada tiga variabel yang dapat digunakan, satu untuk setiap kategori; nama variabel menentukan kategorinya. Ketiga variabel Make ini biasanya tidak didefinisikan (dan Anda tidak boleh mendefinisikannya dalam makefile), sehingga baris kategori tidak melakukan apa-apa (no-op) pada eksekusi normal.

Berikut tiga kemungkinan baris kategori, masing-masing disertai komentar yang menjelaskan artinya:

        $(PRE_INSTALL)     # Perintah pra-instalasi berikut.
        $(POST_INSTALL)    # Perintah pasca-instalasi berikut.
        $(NORMAL_INSTALL)  # Perintah normal berikut.

Jika Anda tidak menempatkan baris kategori di awal aturan install, semua perintah sebelum baris kategori pertama akan diklasifikasikan sebagai perintah normal. Jika Anda tidak menggunakan baris kategori sama sekali, semua perintah akan diklasifikasikan sebagai perintah normal.

Berikut baris kategori untuk uninstall:

        $(PRE_UNINSTALL)     # Perintah pra-uninstall berikut.
        $(POST_UNINSTALL)    # Perintah pasca-uninstall berikut.
        $(NORMAL_UNINSTALL)  # Perintah normal berikut.

Biasanya, perintah pra-uninstall digunakan untuk menghapus entri dari direktori Info.

Jika target install atau uninstall memiliki prasyarat yang berfungsi sebagai subrutin instalasi, sebaiknya mulai perintah setiap prasyarat tersebut dengan baris kategori, dan mulai pula perintah target utama dengan baris kategori. Dengan begitu, Anda dapat memastikan bahwa setiap perintah ditempatkan pada kategori yang benar, apa pun prasyarat yang benar-benar dijalankan.

Perintah pra-instalasi dan pasca-instalasi sebaiknya tidak menjalankan program apa pun selain berikut ini:

[ basename bash cat chgrp chmod chown cmp cp dd diff echo
expand expr false find getopt grep gunzip gzip
hostname install install-info kill ldconfig ln ls md5sum
mkdir mkfifo mknod mv printenv pwd rm rmdir sed sort tee
test touch true uname xargs yes

Alasan membedakan perintah dengan cara ini adalah untuk keperluan pembuatan paket biner. Biasanya, paket biner memuat semua file executable dan file lain yang perlu diinstal, dan memiliki caranya sendiri untuk menginstalnya — sehingga tidak perlu menjalankan perintah instalasi normal. Namun, menginstal paket biner tetap perlu menjalankan perintah pra-instalasi dan pasca-instalasi.

Program yang membuat paket biner bekerja dengan mengekstrak perintah pra-instalasi dan pasca-instalasi. Berikut salah satu cara mengekstrak perintah pra-instalasi (opsi -s pada make diperlukan untuk menekan pesan tentang masuk ke subdirektori):

make -s -n install -o all \
      PRE_INSTALL=pre-install \
      POST_INSTALL=post-install \
      NORMAL_INSTALL=normal-install \
  | gawk -f pre-install.awk

Di sini, file pre-install.awk sebaiknya berisi hal berikut:

$0 ~ /^(normal-install|post-install)[ \t]*$/ {on = 0}
on {print $0}
$0 ~ /^pre-install[ \t]*$/ {on = 1}

Sebelumnya | Berikutnya | Daftar Isi | Versi asli bahasa Inggris (gnu.org)