Jika melihat beberapa repositori di Github, misalnya Babel, kita akan menemui sebuah file dengan nama Makefile
. Makefile adalah file konfigurasi yang dibaca oleh GNU Make untuk menentukan langkah-langkah menghasilkan suatu output.
GNU Make pada dasarnya adalah sebuah perkakas untuk menghasilkan output berupa file atau direktori dari daftar perintah yang kita definisikan. Penggunaannya dengan menjalankan perintah make [rule]
. Contohnya seperti yang sering ditemui jika melakukan compiling kode sumber suatu program secara manual, biasanya akan diminta menjalankan perintah berikut:
./configure
make
sudo make install
Format Penulisan dalam Makefile
Makefile hanya berisi kumpulan kode yang disebut rule. Setiap rule harus memenuhi format:
1target: dependencies...
2 commands
3 ....
- target adalah output berupa file atau direktori yang diinginkan.
- dependencies adalah daftar rule lain yang harus dijalankan terlebih dahulu (opsional).
- commands adalah daftar perintah untuk menghasilkan target.
Coba buat sebuah file Makefile
dengan isi sebagai berikut:
1build/content.md: build
2 echo "Hello World" > build/content.md
3 echo "The world is awesome" >> build/content.md
4
5build:
6 mkdir build
Lalu jalankan
make
Maksud dari Makefile di atas adalah:
- Hasilkan target
build/content.md
dengan cara menjalankan command@echo "Hello World" > build/content.md
dan@echo "The world is awesome" >> build/content.md
, tapi tunggu hingga targetbuild
tersedia. - Hasilkan target
build
dengan cara menjalankan commandmkdir build
.
Hasil dari proses di atas adalah sebuah direktori build
berisi berkas content.md
. Berkas build/content.md
inilah yang kita sebut dengan target atau bisa kita sebut juga sebagai output.
GNU Make pada dasarnya adalah sebuah perkakas untuk menghasilkan output berupa file atau direktori dari daftar perintah yang kita definisikan.
GNU Make Tidak Menimpa Berkas
Dengan Makefile
yang barusan dibuat, coba jalankan lagi perintah make
, maka tidak akan ada proses yang dijalankan.
Hal ini karena GNU Make akan memeriksa ketersediaan target sebelum mengeksekusi rule pada Makefile
. Jika target yang diharapkan sudah tersedia maka tidak perlu diproses lagi. Jadi, kalau ingin proses build selalu terjadi setiap menjalankan perintah make
, mari kita ubah isi Makefile seperti berikut:
1build/content.md: clean build
2 echo "Hello World" > build/content.md
3 echo "The world is awesome" >> build/content.md
4
5clean:
6 rm -rf build
7
8build:
9 mkdir build
Lalu jalankan kembali perintah make
berulang kali, maka proses build akan selalu dilakukan walaupun target sudah tersedia.
Ini bisa terjadi karena hal berikut:
- Kita menambahkan rule
clean
sebagai dependency daribuild/content.md
, sehingga ruleclean
akan selalu dieksekusi terlebih dahulu (dependencies diperiksa sesuai urutan dari kiri ke kanan). - Rule clean hanya menjalankan command
rm -rf build
yang akan menghapus direktoribuild
beserta isinya jika sudah ada. - Karena direktori
build
selalu dihapus terlebih dahulu, maka rulebuild
akan selalu dieksekusi karena targetnya belum tersedia. - Karena rule
clean
tidak berisi perintah yang menyebabkan terbentuknya file/direktori bernamaclean
, maka rule ini akan selalu dieksekusi.
Coba buat direktori atau file bernama clean
touch clean
Lalu jalankan perintah make
beberapa kali, maka di percobaan ke-2 kita tidak akan melakukan proses build lagi.
Hal ini terjadi karena:
- Sudah terdapat file bernama
clean
sehingga ruleclean
sudah terpenuhi dan tidak dieksekusi lagi. - Karena rule
clean
tidak dieksekusi, maka direktoribuild
tidak dihapus, yang menyebabkan rulebuild
juga tidak dieksekusi.
PHONY
Untuk menandai bahwa rule tertentu tidak perlu menghasilkan file, kita bisa menambahkan PHONY
target di awal Makefile
:
1.PHONY: [rule1] [rule2] ...
Rule yang didaftarkan ke dalam PHONY
target ini memiliki karakteristik:
- rule tersebut tidak akan peduli terhadap keberadaan target
- karena tidak peduli dengan target, maka rule akan selalu dieksekusi walaupun terdapat berkas atau direktori sesuai dengan nama targetnya
Coba ubah Makefile
sebelumnya seperti berikut:
1.PHONY: help clean
2
3build/content.md: clean build
4 echo "Hello World" > build/content.md
5 echo "The world is awesome" >> build/content.md
6
7clean:
8 rm -rf build
9
10build:
11 mkdir build
12
13help:
14 @echo "---- Simple Make ----"
15 @echo "Usage: make <command>"
16 @echo ""
17 @echo "Available commands:"
18 @echo "build: Create content"
19 @echo "clean: Clean content"
20 @echo "help : This guide"
Kemudian buat kembali berkas bernama help
dan clean
dengan perintah touch help clean
dan jalankan perintah make
, make clean
dan make help
beberapa kali. Kali ini perintah-perintah tersebut akan selalu dijalankan walaupun target help
dan clean
sudah tersedia.
Ekstra
Apa perbedaan menggunakan perintah echo
dan @echo
?
Secara default setiap baris perintah yang kita cantumkan ke dalam rule di Makefile
akan ditampilkan ketika perintah tersebut dieksekusi. Dengan menambahkan @
, kita bisa mengeksekusi perintah tanpa menampilkannya (https://www.gnu.org/software/make/manual/html_node/Echoing.html#Echoing).