Makefile
Makefile on tiedosto, jonka perusteella make kääntää ohjelman lähdekoodin. Makefilet ovat käteviä etenkin ohjelmoijille, jotka voivat niiden avulla automatisoida ohjelman käännösprosessin.
Tiedoston rakenne
Makefilen rakenne on tarkasti määrätty seuraavanlaiseksi:
kohdetiedosto: lähdetiedosto1 lähdetiedosto2 lähdetiedosto3 <tabulaattori>kääntämiskomennot
Esimerkiksi hello.c-nimiselle C-kieliselle ohjelmalle voitaisiin luoda seuraavanlainen Makefile:
hello: hello.c gcc hello.c -o hello
Jonka jälkeen samassa hakemistossa ajettu komento make kääntäisi ohjelman.
Useampia kohteita
Samassa Makefilessä voi olla useampia käännöskohteita, joita voidaan kutsua joko pelkästään tai niitä voidaan hyödyntää toisesta kohteesta käsin. Esimerkiksi jos edellä käyttämäämme hello-ohjelmaan lisätään toinen tiedosto world.c, voitaisiin Makefilestä tehdä seuraavanlainen:
# Linkitys hello: hello.o world.o gcc hello.o world.o -o hello # Pelkkä käännös, ei linkitystä hello.o: hello.c gcc -c hello.c -o hello.o world.o: world.c gcc -c world.c -o world.o
Jolloin koko ohjelman kääntäminen sujuisi komennolla make. Jos makelle ei kerrota erikseen, mikä kohde halutaan käsitellä, make käsittelee ensimmäisen lohkon. Toisaalta pelkän world.c-tiedoston kääntäminen onnistuisi komennolla
make world.o
Tätä ominaisuutta hyödynnetään usein Makefileissä olevilla clean- ja install-kohteilla. Esimerkiksi Makefilen lopussa voisi olla seuraavanlainen clean-kohde:
clean: rm *.o hello
Joka poistaisi käännetyt objektitiedostot (hello.o ja world.o) ja käännetyn ohjelman (hello). Tätä kutsuttaisiin komentoriviltä komennolla
make clean
Muuttujat
Make tukee erilaisten muuttujien käyttöä Makefileissä, jolloin saadaan tiedostosta helpommin ylläpidettävä ja siirrettävä kun komentoja ja niiden parametreja ei tarvitse "kovakoodata".
Muuttujat määritellään yksinkertaisesti syntaksilla
muuttuja = arvo
Esimerkiksi C-kääntäjä on yleensä CC-nimisessä muuttujassa:
CC = gcc
Muuttujiin voi viitata koodissa syntaksilla $(muuttuja), esimerkiksi hello.c-tiedoston kääntävä osa edellisestä Makefilestä muuttuisi seuraavanlaiseksi
CC = gcc hello.o: hello.c $(CC) -c hello.c -o hello.o
Nyt kääntäjän vaihtaminen toiseksi onnistuu pelkkää muuttujaa muuttamalla, mistä on hyötyä Makefilen kasvaessa suuremmaksi. Vastaavalla tavalla muuttujina käytetään usein esimerkiksi käännösoptioita, jolloin kaikkiin tiedostoihin saadaan haluttaessa joko debug-käännösoptiot (-g, -O0) tai julkaisua varten tehokkaat optimoinnit (-O3).
Esimerkki
Esimerkki Makefilestä, jota käytetään kääntämään kahdesta C++-kielisestä lähdekooditiedostosta (src/main.cpp ja src/funktiot.cpp).
#Objektitiedostot PROJEKTI = src/main.o src/funktiot.o #Käännösasetukset LDFLAGS_CLIENT = -lm CXXFLAGS = -g #Oletuksena suoritetaan osio "softa" all: softa #Tiedot, mistä lähdekooditiedostoista objektitiedostot käännetään src/main.o: src/main.cpp src/funktiot.o: src/funktiot.cpp #Kääntö softa: g++ $(PROJEKTI) $(CXXFLAGS) $(LDFLAGS) -o ohjelma #Clean, joka poistaa tarpeettomat objektitiedostot clean: rm -f $(PROJEKTI)
Nyt projektin hakemistossa voidaan ajaa komento make, jolloin make kääntää projektin:
$make g++ -g -c -o src/main.o src/main.cpp g++ -g -c -o src/funktiot.o src/funktiot.cpp g++ src/main.o src/funktiot.o -g -o ohjelma
Huomaa, että jos nyt muokkaamme tiedostoa src/funktiot.cpp ja ajamme maken uudelleen, tiedostoa src/main.cpp ei käännetä uudestaan:
$touch src/main.cpp $make g++ -g -c -o src/main.o src/main.cpp g++ src/main.o src/funktiot.o -g -o ohjelma