Menulis Makefile

Fungsi utama dari sebuah Makefile adalah untuk mempermudah proses kompilasi dari sebuah proyek. Namakan proyek tersebut adalah foo yang terdiri dari beberapa file kode sumber (.c) dan beberapa file header (.h). Permasalahan akan muncul ketika kita mulai mengompile program, kemudian mengubah kode sumber, kemudian mengompilenya lagi. Secara manual, setiap kali kita akan mengompile kode sumber, maka setiap file kode sumber pun akan dikompile (meskipun tidak ada perubahan di dalamnya).

Program make hanya akan mengompile kode sumber yang berubah. Setiap kali perintah `make’ dipanggil, maka hanya kode sumber yang berubah saja yang akan dicompile. Berikut adalah contoh sebuah Makefile paling sederhana untuk membangun kode (sumber.c) menjadi target (sumber)

sumber:sumber.c

Contoh di atas cukup untuk membangun sebuah executable `sumber’ dari kode sumber `sumber.c’ dengan memanggil perintah `make’ dari dalam direktori tempat kode sumber berada. Makefile memiliki struktur sebagai berikut:

target:dependencies
< tab >rules # hanya gunakan <tab>, atau make akan complain!
       rules # perintah ...

Comment dan Sambung Baris

Comment adalah baris dalam Makefile yang berfungsi sebagai komentar. Baris tidak akan digunakan oleh `make’. Comment diawali oleh karakter `#’.

# Ini adalah comment

Perhatikan kode berikut:

$OBJECTS = satu.o 
           dua.o 
           # tiga.o 
           empat.o

Akan sama seperti satu baris berikut:

$OBJECTS = satu.o dua.o empat.o

Macro

Macro dalam Makefile sama seperti variable. Makro ditandai dengan VALUE diikuti tanda `=’ dan nilai. Untuk mengakses makro, dapat menggunakan notasi $(VALUE). Berikut contoh pemakaian macro; CC, CFLAGS, OBJS:

# Makefile
CC = gcc
CFLAGS = -Wall
OBJS = main.o app.o

all:main

main: $(OBJS)
        $(CC) $(CFLAGS) $(OBJS) -o $@

main.o:main.c
        $(CC) $(CFLAGS) -c $<

app.o:app.c
        $(CC) $(CFLAGS) -c $<

$(OBJS):app.h

clean:
        rm -f *.o
        rm -f ~*

Pada contoh di atas, kita pakai notasi `$@’ dan `$<‘. Notasi tersebut adalah redirection dari target dan dependency.

Ada kalanya kita hanya ingin membangun object file saja (*.o) untuk digunakan lebih lanjut. Dengan mendeklarasikan object apa saja yang akan kita buat dari file-file sumber, berarti hanya file tersebut yang akan dibangun pada saat proses kompilasi. Mari kita perhatikan kode berikut:

CC=gcc
CFLAGS=-O2 -Wall
OBJS=app.o main.o

all:$(OBJS)

$(OBJS):%.o:%.c
        $(CC) $(CFLAGS) $< -c

Wildcard

Bayangkan jika sebuah project terdiri dari ratusan file kode sumber, seberapa banyak file kode sumber anda maka sebanyak itulah isi dari macro OBJS. Tentunya hal ini telah dipikirkan oleh pembuat program `make’. Ada satu solusi selain mendeklarasikan macro OBJS yaitu $(wildcard). Mari kita pelajari kode di bawah:

# Makefile
CC=gcc
CFLAGS=-O2 -Wall
FILES=$(wildcard *.c)

all:main

main:$(FILES)
        $(CC) $(CFLAGS) $(FILES) -o $@

Kode di atas menggunakan $(wildcard *.c) yang bertujuan untuk memerintahkan program `make’ untuk membangun semua file .c yang ada di dalam direktori yang sama, kemudian membentuk file eksekutabel dengan nama main. “main” adalah target dengan dependency semua file .c output dari $(FILES).

Tips kosmetik: Gunakan `@’ di awal perintah untuk mode silence, output dari perintah tidak akan ditampilkan. contoh: @ rm -f *.o

Menggunakan output dari perintah shell sangat dibutuhkan dalam banyak kasus. Misalkan, kita akan membangun out-of-tree driver linux untuk host yang sedang berjalan. Pada kasus ini kita akan membutuhkan versi kernel yang sedang berjalan dan header file yang biasanya diletakkan di filsystem dengan nama tertentu.

Saya akan ambil contoh dari host yang sedang saya gunakan, yaitu sebuah Ubuntu box dengan versi kernel 2.6.24-25-generic. Biasanya, header file tersedia di /usr/src/linux-headers-(versi kernel). Mari kita perhatikan kode berikut:

HEADERS := /usr/src/linux-headers-$(shell uname -r)
obj-m   += toshiba_acpi.o
EXTRA_CFLAGS += -I $(HEADERS)/include

.PHONY: all
all:
        $(MAKE) -C $(HEADERS) M=$(shell pwd) modules

.PHONY: clean
clean:
        $(MAKE) -C $(KDIR) M=$(shell pwd) clean
        rm -f modules.order Module.markers *~

Kita manfaatkan output dari $(shell uname -r) dan $(shell pwd) sebagai parameter dari perintah make. Keduanya berisi: `2.6.24-25-generic’ dan `/home/user/codes/’ yaitu output dari perintah `pwd’.

Phony Target

Pada contoh di atas, kita jumpai .PHONY. Phony target adalah target yang tidak berbentuk file, semacam temporary file yang digunakan oleh program `make’. Tujuan utama dari phony target adalah untuk menghindari konflik antara file yang bernama sama.

Pos ini dipublikasikan di Embedded dan tag , , , . Tandai permalink.

Satu Balasan ke Menulis Makefile

  1. teguhginanjar berkata:

    thanks banget ya….

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s