Make dan Makefile: Tools Pengembangan Software

Dalam artikel berikut akan dibahas tentang tools pengembangan software di Linux yaitu program make dan Makefile. Program make dan Makefile digunakan untuk mengelola proyek software. Umumnya digunakan untuk mengontrol kompilasi dari source code, menyiapkan halaman manual, dan instalasi aplikasi ke direktori target. Program make menjalankan fungsinya berdasarkan Makefile yang berisi rule bagaimana aplikasi kita akan dibangun.

Makefile berisi rules dan set dependensi. Dependensi mempunyai sebuah target (file yang harus dibuat) dan set source file dependensinya. Rules mendeskripsikan bagaimana membuat target dari file dependensinya. Makefile ini dibaca oleh program make, yang akan menentukan target yang akan dibangun dan membandingkan waktu modifikasi dari source file untuk memutuskan rules mana yang akan dijalankan untuk membangun target.

Syntax Makefile:

# Ini merupakan comment
# Note: 
# 1. Tidak boleh ada spasi di awal baris (harus pakai tab untuk indent)
# 2. Baris perintah yang panjang dalam rules bisa dipecah dengan '\'
#    Namun, tidak boleh ada spasi setelah '\' tersebut
# 3. Perintah 'make ' akan menjalankan rules untuk membangun target tersebut
# 4. Perintah 'make' tanpa melewatkan parameter, akan menjalankan target yang
#    didefinisikan pertama. Jadi, target 'all' sebaiknya ada di barisan pertama

CC = gcc # Ini macro: MACRONAME=value
CFLAGS = -I. -g -Wall -ansi
all: $(target)
$(target):$(dependensi: object file{*.o}, source code{*.c,*.h})
	${rules} #Misalnya: $(CC) $(CFLAGS) -o $(target) $(dependensi)

Macro internal khusus:
$? : daftar prerequisite
$@ : nama current target
$< : nama current prerequisite
$* : nama current prerequisite tanpa akhiran

Karakter khusus di awal rules:
‘-‘ : ignore error saat eksekusi satu perintah
‘@’ : don’t print command to standar output

Sebenarnya program make mempunyai built-in rules yang dapat menyederhanakan Makefile. Perintah ‘make -p’ akan menampilkan daftar built-in rules yang tersedia. Misalnya built-in rules untuk compile dan linking:

CC = cc
OUTPUT_OPTION = -o $@
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)
%.o: %.c
	$(COMPILE.c) $(OUTPUT_OPTION) $<  #commands to execute (built-in)
%: %.o
	$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

Dan built-in rules menggunakan suffix yang diperlukan untuk membuat satu file dengan akhiran yang berbeda:

# Syntax:
# ..:
.SUFFIXES: .cpp
.cpp.o:
	$(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<
# Efeknya sama dengan
# %.o: %.cpp
# 	$(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<

Contoh Makefile yang menggunakan built-in rules:

CC=$(CROSS_COMPILE)gcc
PACKAGE="nettool"
VERSION="0.1"

JLEVEL=-j3 # Eksekusi 3 perintah/rules secara paralel
CFLAGS=$(JLEVEL) -Wall -DPACKAGE=$(PACKAGE) -DVERSION=$(VERSION) -g -I.

APPNAME=nettool
NETTOOLS_LIB = libnettool.a
NETTOOLS_LIB_SRCS = ethdetect.c ping.c

INSTDIR=$(DESTDIR)/usr/bin

all: $(APPNAME)

# memanaje library (statik) menggunakan built-in
$(NETTOOLS_LIB): $(NETTOOLS_LIB)(ethdetect.o ping.o)

$(APPNAME): main.o $(NETTOOLS_LIB)
	$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
	
install:
# Rule yang panjang dan eksekusi perintah secara berurutan 
# (dan harus perintah sebelumnya harus sukses)
	@if [ -d $(INSTDIR) ]; \
	then \
		cp -avf $(APPNAME) $(INSTDIR);\
		chmod a+x $(INSTDIR)/$(APPNAME);\
		chmod og-w $(INSTDIR)/$(APPNAME);\
		echo “Installed in $(INSTDIR)”;\
	else \
		echo “Sorry, $(INSTDIR) does not exist”;\
	fi

clean:;
	-rm -f *.o *.a
	-rm -f $(APPNAME)

Contoh perintah yang dijalankan cross-compiling untuk target arm adalah:
# make CROSS_COMPILE=arm-

Makefile dan Subdirektori

Untuk membangun suatu proyek yang besar, biasanya kita memisahkan beberapa file (misalnya source code untuk membangun library) ke direktori terpisah dari kode utama. Kita dapat memanajenya dengan 2 cara:

  1. Membuat Makefile di subdirektori untuk mengkompile, archieve ke library (atau membuat librari dinamik). Kemudian Makefile utama mempunyai rule untuk mengeksekusi rule Makefile di subdirektori
       
    	mylib.a:
    		(cd mylibdirectory;$(MAKE))
    
    
  2. Menggunakan macro @D untuk direktori dan @F untuk filename
        # Override .c.o suffix
        .c.o:
    		$(CC) $(CFLAGS) -c $(@D)/$(<F) -o $(@D)/$(@F)
    		
    	mylib.a: mydir/2.o mydir/3.o
    		ar -rv mylib.a $?	
    
    

Sources
Source file untuk mencoba Makefile ini dapat didownload di sini.

Referensi

  1. Beginning Linux Programming Books, John Wiley & Sons, 3rd Edition, 2004, p365-416

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

%d blogger menyukai ini: