Ero sivun ”Makefile” versioiden välillä

Linux.fista
Siirry navigaatioon Siirry hakuun
p Botti vaihtoi luokan Luokka:Ohjelmistokehitys
päivitys
 
(7 välissä olevaa versiota 6 käyttäjän tekeminä ei näytetä)
Rivi 1: Rivi 1:
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.
Makefile on tiedosto, jonka perusteella [[make]] [[kääntäminen|kääntää]] ohjelman [[lähdekoodi]]n. Makefilet ovat käteviä etenkin ohjelmoijille, jotka voivat niiden avulla automatisoida ohjelman käännösprosessin ja hallita tiedostojen riippuvuuksia.


== Tiedoston rakenne ==
== Tiedoston rakenne ==
Makefilen rakenne on tarkasti määrätty seuraavanlaiseksi:
Makefilen perusrakenne on tarkasti määrätty ja koostuu kohteesta (target), sen riippuvuuksista (prerequisites) ja komennoista (recipes).
kohdetiedosto''':''' lähdetiedosto1 lähdetiedosto2 lähdetiedosto3
  <tabulaattori>kääntämiskomennot


Esimerkiksi hello.c-nimiselle [[C]]-kieliselle ohjelmalle voitaisiin luoda seuraavanlainen Makefile:
Makefile
kohdetiedosto: lähdetiedosto1 lähdetiedosto2 lähdetiedosto3
<tabulaattori>kääntämiskomennot
 
{{Huomautus|Huomioitavaa: Komentorivi on pakko aloittaa tabulaattorimerkillä (ei välilyönneillä).}}
 
Esimerkki: hello.c-nimiselle C-kieliselle ohjelmalle voitaisiin luoda seuraavanlainen Makefile:
 
<syntaxhighlight lang="makefile">
  hello: hello.c
  hello: hello.c
     gcc hello.c -o hello
     gcc hello.c -o hello
</syntaxhighlight>


Jonka jälkeen samassa hakemistossa ajettu komento make kääntäisi ohjelman.
Jonka jälkeen samassa hakemistossa ajettu komento make kääntäisi ohjelman.


== Useampia kohteita ==
== Useampia kohteita (Targets) ==
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:
Samassa Makefilessä voi olla useampia käännöskohteita, joita voidaan kutsua erikseen tai hyödyntää toisesta kohteesta käsin.
# Linkitys
 
hello: hello.o world.o
Jos makelle ei kerrota erikseen, mikä kohde halutaan käsitellä, make käsittelee tiedoston ensimmäisen lohkon (joka on perinteisesti all).
      gcc hello.o world.o -o hello
 
# Pelkkä käännös, ei linkitystä
Esimerkki moduuleista: Jos edellä käyttämäämme hello-ohjelmaan lisätään toinen tiedosto world.c, voitaisiin Makefile tehdä seuraavanlaiseksi:
hello.o: hello.c
 
      gcc -c hello.c -o hello.o  
<syntaxhighlight lang="makefile">
world.o: world.c
# Linkityskohde
      gcc -c world.c -o world.o
hello: hello.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
    gcc hello.o world.o -o hello
  make world.o
 
Tätä ominaisuutta hyödynnetään usein Makefileissä olevilla clean- ja install-kohteilla. Esimerkiksi Makefilen lopussa voisi olla seuraavanlainen clean-kohde:
# Pelkkä käännös (Moduulit)
clean:
hello.o: hello.c
      rm *.o hello
    gcc -c hello.c -o hello.o  
Joka poistaisi käännetyt objektitiedostot (hello.o ja world.o) ja käännetyn ohjelman (hello). Tätä kutsuttaisiin komentoriviltä komennolla
world.o: world.c
    gcc -c world.c -o world.o
</syntaxhighlight>
 
Nyt koko ohjelman kääntäminen sujuisi komennolla make. Pelkän world.o-tiedoston kääntäminen onnistuisi komennolla:
  make world.o.
 
== Erityiskohteet ==
Tätä ominaisuutta hyödynnetään usein Makefileissä olevilla ''clean''- ja ''install''-kohteilla, joita kutsutaan pseudokohteiksi (phony targets), sillä ne eivät luo oikeita tiedostoja.
 
Makefile
<syntaxhighlight lang="makefile">
.PHONY: clean install
 
clean:
      rm -f *.o hello
</syntaxhighlight>
 
Yllä oleva clean-kohde poistaisi käännetyt objektitiedostot (''hello.o'' ja ''world.o'') ja käännetyn ohjelman (hello). Sitä kutsuttaisiin komentoriviltä komennolla:
  make clean
  make clean


== Muuttujat ==
== 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".
Make tukee erilaisten muuttujien käyttöä Makefileissä, jolloin tiedostosta saadaan helpommin ylläpidettävä ja siirrettävä.
 
Muuttujat määritellään syntaksilla:


Muuttujat määritellään yksinkertaisesti syntaksilla
  muuttuja = arvo
  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 ==
Muuttujiin viitataan koodissa syntaksilla $(muuttuja).
Esimerkki Makefilestä, jota käytetään kääntämään kahdesta [[C plus plus | C++]]-kielisestä lähdekooditiedostosta (<tt>src/main.cpp</tt> ja <tt>src/funktiot.cpp</tt>).
 
Esimerkki muuttujien käytöstä:
<syntaxhighlight lang="Makefile">
CC = gcc
CFLAGS = -g
 
hello.o: hello.c
    $(CC) $(CFLAGS) -c hello.c -o hello.o
</syntaxhighlight>


#Objektitiedostot
Nyt kääntäjän vaihtaminen (muuttamalla CC=...) tai kääntöoptioiden lisääminen (muuttamalla CFLAGS=...) onnistuu helposti yhdestä paikasta.
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:
== Oletussäännöt ==
$make
Make-työkalussa on sisäänrakennettuja oletussääntöjä yleisimpiin käännöstehtäviin, kuten C-koodin kääntämiseen.
g++ -g  -c -o src/main.o src/main.cpp
 
g++ -g  -c -o src/funktiot.o src/funktiot.cpp
Kun esimerkiksi ''hello.o''-tiedosto riippuu ''hello.c''-tiedostosta, Make tietää automaattisesti, että se tarvitsee C-kääntäjän. Jos käytetään yllä määriteltyjä muuttujia, Make käyttää oletussääntöä, joka on käytännössä:
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:
<syntaxhighlight lang="Makefile">
$[[touch]] src/main.cpp
%.o: %.c
$make
    $(CC) $(CFLAGS) -c $< -o $@
g++ -g  -c -o src/main.o src/main.cpp
</syntaxhighlight>
g++ src/main.o src/funktiot.o -g -o ohjelma
 
(missä $< on riippuvuustiedosto ja $@ on kohdetiedosto)
 
Tämän ansiosta monissa pienissä Makefilen kohdemäärityksissä tarvitsee määrittää vain riippuvuudet, eikä itse komentoja.
 
=== Esimerkki ===
Esimerkki Makefilestä, jota käytetään kääntämään kahdesta [[C++]]-kielisestä lähdekooditiedostosta (''src/main.cpp'' ja ''src/funktiot.cpp'').
 
Makefile<br>
<syntaxhighlight lang="Makefile">
# Objektitiedostot
PROJEKTI = src/main.o src/funktiot.o
 
# Käännösasetukset
LDFLAGS = -lm
CXXFLAGS = -g
 
# Oletuksena suoritetaan osio "softa"
all: softa
 
# Objektitiedostot käännetään C++-oletussäännöillä,
# mutta riippuvuus määritellään Makefilessa.
src/main.o: src/main.cpp
src/funktiot.o: src/funktiot.cpp
 
# Linkityskohde
softa: $(PROJEKTI)
    g++ $(PROJEKTI) $(CXXFLAGS) $(LDFLAGS) -o ohjelma
 
# Clean, joka poistaa tarpeettomat objektitiedostot
clean:
    rm -f $(PROJEKTI) ohjelma
</syntaxhighlight>
 
Nyt projektin hakemistossa voidaan ajaa komento make, jolloin make kääntää projektin:
 
<syntaxhighlight lang="Bash">
$ 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 -lm -o ohjelma
</syntaxhighlight>
 
Huomaa, että jos nyt muokkaamme tiedostoa ''src/main.cpp'' ja ajamme maken uudelleen, tiedostoa ''src/funktiot.cpp'' ei käännetä uudestaan, koska sen riippuvuus on jo ajan tasalla. Tämä on riippuvuuksienhallinnan ydin:
 
<syntaxhighlight lang="Bash">
$ touch src/main.cpp
$ make
g++ -g  -c -o src/main.o src/main.cpp
g++ src/main.o src/funktiot.o -g -lm -o ohjelma
</syntaxhighlight>


== Katso myös ==
== Katso myös ==
*[[Make]]
* [[Make]]
 
* [[CMake]]
== Linkkejä ==
* [[Autotools]]
*[http://www.flug.fi/ohjeita/linux-ohjelmointi.html#Makefile FLUG:in Linux-ohjelmointi]-opas.
* [[Jam]]
* [[SCons]]


[[Luokka:Kehitystyökalut]]
[[Luokka:Kehitystyökalut]]

Nykyinen versio 15. marraskuuta 2025 kello 01.33

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 ja hallita tiedostojen riippuvuuksia.

Tiedoston rakenne

[muokkaa]

Makefilen perusrakenne on tarkasti määrätty ja koostuu kohteesta (target), sen riippuvuuksista (prerequisites) ja komennoista (recipes).

Makefile

kohdetiedosto: lähdetiedosto1 lähdetiedosto2 lähdetiedosto3
<tabulaattori>kääntämiskomennot
Huomautus: Huomioitavaa: Komentorivi on pakko aloittaa tabulaattorimerkillä (ei välilyönneillä).


Esimerkki: 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 (Targets)

[muokkaa]

Samassa Makefilessä voi olla useampia käännöskohteita, joita voidaan kutsua erikseen tai hyödyntää toisesta kohteesta käsin.

Jos makelle ei kerrota erikseen, mikä kohde halutaan käsitellä, make käsittelee tiedoston ensimmäisen lohkon (joka on perinteisesti all).

Esimerkki moduuleista: Jos edellä käyttämäämme hello-ohjelmaan lisätään toinen tiedosto world.c, voitaisiin Makefile tehdä seuraavanlaiseksi:

# Linkityskohde
hello: hello.o world.o
     gcc hello.o world.o -o hello

# Pelkkä käännös (Moduulit)
hello.o: hello.c
     gcc -c hello.c -o hello.o 
world.o: world.c
     gcc -c world.c -o world.o

Nyt koko ohjelman kääntäminen sujuisi komennolla make. Pelkän world.o-tiedoston kääntäminen onnistuisi komennolla:

make world.o.

Erityiskohteet

[muokkaa]

Tätä ominaisuutta hyödynnetään usein Makefileissä olevilla clean- ja install-kohteilla, joita kutsutaan pseudokohteiksi (phony targets), sillä ne eivät luo oikeita tiedostoja.

Makefile

.PHONY: clean install

clean:
      rm -f *.o hello

Yllä oleva clean-kohde poistaisi käännetyt objektitiedostot (hello.o ja world.o) ja käännetyn ohjelman (hello). Sitä kutsuttaisiin komentoriviltä komennolla:

make clean

Muuttujat

[muokkaa]

Make tukee erilaisten muuttujien käyttöä Makefileissä, jolloin tiedostosta saadaan helpommin ylläpidettävä ja siirrettävä.

Muuttujat määritellään syntaksilla:

muuttuja = arvo

Muuttujiin viitataan koodissa syntaksilla $(muuttuja).

Esimerkki muuttujien käytöstä:

CC = gcc
CFLAGS = -g

hello.o: hello.c
     $(CC) $(CFLAGS) -c hello.c -o hello.o

Nyt kääntäjän vaihtaminen (muuttamalla CC=...) tai kääntöoptioiden lisääminen (muuttamalla CFLAGS=...) onnistuu helposti yhdestä paikasta.

Oletussäännöt

[muokkaa]

Make-työkalussa on sisäänrakennettuja oletussääntöjä yleisimpiin käännöstehtäviin, kuten C-koodin kääntämiseen.

Kun esimerkiksi hello.o-tiedosto riippuu hello.c-tiedostosta, Make tietää automaattisesti, että se tarvitsee C-kääntäjän. Jos käytetään yllä määriteltyjä muuttujia, Make käyttää oletussääntöä, joka on käytännössä:

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

(missä $< on riippuvuustiedosto ja $@ on kohdetiedosto)

Tämän ansiosta monissa pienissä Makefilen kohdemäärityksissä tarvitsee määrittää vain riippuvuudet, eikä itse komentoja.

Esimerkki

[muokkaa]

Esimerkki Makefilestä, jota käytetään kääntämään kahdesta C++-kielisestä lähdekooditiedostosta (src/main.cpp ja src/funktiot.cpp).

Makefile

# Objektitiedostot
PROJEKTI = src/main.o src/funktiot.o

# Käännösasetukset
LDFLAGS = -lm
CXXFLAGS = -g

# Oletuksena suoritetaan osio "softa"
all: softa

# Objektitiedostot käännetään C++-oletussäännöillä,
# mutta riippuvuus määritellään Makefilessa.
src/main.o: src/main.cpp
src/funktiot.o: src/funktiot.cpp

# Linkityskohde
softa: $(PROJEKTI)
    g++ $(PROJEKTI) $(CXXFLAGS) $(LDFLAGS) -o ohjelma

# Clean, joka poistaa tarpeettomat objektitiedostot
clean:
    rm -f $(PROJEKTI) ohjelma

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 -lm -o ohjelma

Huomaa, että jos nyt muokkaamme tiedostoa src/main.cpp ja ajamme maken uudelleen, tiedostoa src/funktiot.cpp ei käännetä uudestaan, koska sen riippuvuus on jo ajan tasalla. Tämä on riippuvuuksienhallinnan ydin:

$ touch src/main.cpp
$ make
g++ -g   -c -o src/main.o src/main.cpp
g++ src/main.o src/funktiot.o -g -lm -o ohjelma

Katso myös

[muokkaa]