Felhasználói eszközök

Eszközök a webhelyen


oktatas:programozas:automatikus_forditas:make

< Automatikus fordítás

make

A make parancsról

A make egy parancssoros program, amely leegyszerűsíti, automatizálja a fordítási tevékenységet. A fordítási utasításokat egy Makefile nevű állományban írjuk le. A make parancs a Makefile alapján végez tevékenységeket. A make parancs képes függőségek feltérképezésére, a fordítási sorrend eldöntésére. Felismeri mely forrásokat kell lefordítani, és melyek nem változtak.

A make parancs beszerzése

Debian GNU/Linux, Ubuntu, Linux Mint rendszeren a make csomagban van. Telepítése:

apt install make

Win alapú rendszerekre a Source Forge webhelyről szerezhetjük be, vagy telepítsük a Cygwin vagy a MingW csomaggal.

A make program eredeti oldala:

A make fájl tartalma

  • megjegyzések
  • változók
  • célok
  • függőségek
  • parancssoros utasítások
# megjegyzés1
# megjegyzés2
VALTOZO=érték
 
 
cél1: függőség_1 függőség_2 ...
	parancs_1 $(VALTOZO)
	parancs_2
	parancs_n
 
 
cél2: függőség_3 függőség_4 ...
	parancs_1
	parancs_2
	parancs_n

A Makefile-ban egysoros megjegyzéseket helyezhetünk el, a „#” karakter után.

Változókat vehetünk fel, amelynek értéket adhatunk egyenlőség jellel. A változók felvétele nem kötelező, de célszerű. A fájlban bárhol felvehetünk változókat. Egy változó nevében ajánlott karakter a betű, a szám és az aláhúzás. A változókra a ${név} vagy $(név) formában hivatkozhatunk.

Több célt is megadhatunk. A make parancs kiadásakor megadhatjuk, hogy melyik cél hajtódjon végre. Ha egyet sem adunk meg, akkor az első cél hajtódik végre. A cél lehet egy fájl neve, amit elő kell állítani, de lehet egyszerűen egy tetszőleges szó. Konkrét cél helyett megadható változó is. Ha egy cél nem egy létrehozandó állományt takar, akkor hamis célról beszélünk. A hamis célokat megadhatjuk a .PHONY: kulcsszó után felsorolva. Például:

.PHONY: clean

A függőségek megadása nem kötelező. Ha cél egy fájl, akkor a fájl valamilyen forrásállományokból fog elkészülni. Ezeket a forrásállományokat érdemes felsorolni függőségként. A fordítás így csak akkor történik meg, ha az szükséges. A függőségek helyett megadható változó is.

A parancsok, az operációs rendszer szintjén végrehajtandó parancsok. A parancsokba is beágyazhatunk változókat. Egy parancs sikertelen végrehajtása megszakítja a make működését. Ha szeretnénk a megszakítást megakadályozni, akkor egy „-” karakterrel kezdjük a parancsot. Például:

clean:
    -rm *.class

Használat C nyelvvel

A következőkben a GNU Make használatát nézzük meg.

A Makefile tartalmazhat fájlfüggőségek leírását, shell parancsokat, változókat és megjegyzéseket.

Írjunk egy helló világ nevű programot:

main.c
#include <stdio.h>
 
main()
{
	printf("Valami\n");
 
}
Makefile
 
all: main
 
main: main.o
	gcc -o main main.o
 
main.o: main.c
	gcc -c main.c
 
clean:
	rm main.o main

A gcc és az rm sorok előtt tabulátor legyen, a szóköz nem jó.

A létrehozandó fájl: „main” (kiterjesztés nélkül).

A parancs általános alakja:

cél: függőség_1 függőség_2 ...
	parancs_1
	parancs_2
	parancs_n
  • A cél mindig egy fájl neve, amit elő kell állítani.
  • A függőség egy vagy több fájl, amelyből a célt előállítjuk.
  • A parancs egy olyan shell parancs, ami elvégzi cél előállítását.

Fontos, hogy a parancsok előtt pontosan egy tabulátor legyen.

A make parancs egy egész értékkel tér vissza. Sikeres végrehajtás esetén 0-val, sikertelenség esetén 1-nél nagyobb számmal.

A Makefile-ban használhatunk változókat is. Például megadjuk a fordítót:

CC=gcc

Az értékükre két módon hivatkozhatunk:

$(CC)

vagy:

${CC}

A Makefile-ban megadható egy fő cél. A fő cél megadása az all kulcsszóval történik:

all: main

Windowson:

all: main.exe

Ha nem határozzuk meg az all kulcsszóval a fő célt, akkor az elsőként megtalált cél lesz a fő cél.

Makefile
main: egy.o ketto.o
    gcc egy.o ketto.o -o main
 
egy.o:egy.h egy.c
    gcc -c egy.c
 
ketto.o:ketto.h ketto.c
    gcc -c ketto.c

Ha egyszer kiadtuk a make parancsot és létrejöttek a célfájlok, akkor a make parancs újbóli kiadási nem csinál semmit, ha nem változtattunk semmit a forrásfájlokon, mivel a forrásfájlok időbélyege és a célfájlok időbélyege megegyezik. Ha mégis szeretnénk újrafordítani, akkor törölni kell a célfájlokat.

A clean egy speciális cél, amely a létrejött célok törlését szokás megadni.

Használat C# nyelvvel

A mono rendszerrel készült két darab forrásfájllal rendelkezünk:

main.cs sajatc.cs

Ha két állományból bármelyik változik, akkor fordítani kell. A kimenet egy main.exe. A Mono 2.0 verzióját használjuk, melynek fordítója:

gmcs

Ezek után a Makefile tartalma a következő tartalommal rendelkezhet:

main.exe: main.cs sajatc.cs
        gmcs main.cs sajat.cs

A fenti Makefile-ban azt határoztuk meg, hogy a main.exe függ a main.cs és a sajatc.cs forrásfájloktól. Ha valamelyik változott, akkor futtatjuk a második sort. A második sor egy tabulátor karaktert tartalmaz a sor elején.

Ha hordozhatóbbá akarjuk tenni a Makefile-t akkor a fájlneveket érdemes változókban megadni. A fordítás parancsa is változóba tehető. Ezeket a változókat a fájl elején határozzuk meg. Ha valami változik, akkor csak ott kell változtatnunk.

FOFORRASFAJL=main
EGYEBFORRASFAJL=sajat.cs
FORDITO=gmcs

$(FOFORRASFAJL).exe: $(FOFORRASFAJL).cs $(EGYEBFORRASFAJL)
        $(FORDITO) $(FOFORRASFAJL).cs $(EGYEBFORRASFAJL)

Implicit szabályok

Ha van egy valami.o kiterjesztésű fájl ennek fordítását így írhatjuk explicit:

valami.o: valami.c
    gcc -c valami.c

Látható egy általános elv, amely szerint ha van egy valami.o nevű állomány, azt biztosan egy ugyanilyen nevű .c kiterjesztésű fájlból lehet létrehozni. Ezért az implicit szabályok használatával megengedett a szabályok egyszerűsítése:

%.o: %.c
    gcc -c -o $@ $<

Példa

C

Makefile
TARGET = program01
CC = gcc
RM = rm
CFLAGS = -Wall -g
LDFLAGS =
SOURCES = program01.c
OBJECTS = program01.o
HEADERS = program01.h
 
${TARGET} : ${OBJECTS}
	${CC} ${LDFLAGS} -o ${TARGET} ${OBJECTS}
 
${OBJECTS}.o : ${SOURCES} ${HEADERS}
	${CC} ${CFLAGS} -c ${SOURCES}
 
clean :
	${RM} ${OBJECTS} ${TARGET}
Makefile
TARGET = program01.exe
CC = "c:\Program Files (x86)\CodeBlocks\MinGW\bin\gcc"
CFLAGS = -Wall -g
LDFLAGS = -lmysql
SRCS = program01.c
OBJS = program01.o
 
MYSQLINCLUDE = -Ic:/Users/joska/mysql-connector-c-6.1.5-win32/include/
MYSQLLIB = -Lc:/Users/joska/mysql-connector-c-6.1.5-win32/lib/
 
STDINCLUDE = -I"c:/Program Files (x86)/CodeBlocks/MinGW/include/" 
STDLIB = -L"c:/Program Files (x86)/CodeBlocks/MinGW/lib/"
 
INCLUDES = ${STDINCLUDE} ${MYSQLINCLUDE}
LIBS = ${STDLIB} ${MYSQLLIB}
 
 
${TARGET}: ${OBJS}
	${CC} ${LDFLAGS} ${LIBS} -o ${TARGET} ${OBJS}
 
${OBJS}: ${SRCS}
	${CC} ${CFLAGS} ${INCLUDES} -c ${SRCS}
 
clean:
	rm ${OBJS} ${TARGET}
Makefile
SHELL = /bin/sh
 
OBJ =  main.o factorial.o hello.o
CFLAG = -Wall -g
CC = gcc
INCLUDE =
LIB = -lm
 
hello:${OBJ}
   ${CC} ${CFLAGS} ${INCLUDES} -o $@ ${OBJS} ${LIBS}
 
clean:
	-rm -f *.o core *.core
 
.c.o:
   ${CC} ${CFLAGS} ${INCLUDES} -c $<

C++

Makefile
TARGET = main
CXX = g++
RM = rm
CPPFLAGS = -Wall -g
LDFLAGS =
SRCS = main.cxx dolgozo.cxx
HEADS = dolgozo.h
OBJS = main.o dolgozo.o
 
${TARGET}: ${OBJS}
	${CXX} ${LDFLAGS} -o ${TARGET} ${OBJS}
 
${OBJS}.o:${SRCS} ${HEADS}
	${CXX} ${CPPFLAGS} -c ${SRCS}
 
clean:
	${RM} ${OBJS} ${TARGET}

Java konzolos

PROGRAM=Program01
JAVA = /usr/local/jdk1.6.0_21/bin/
JC = $(JAVA)javac
JR = $(JAVA)java
JFLAGS = -classpath .:sqlite-jdbc-3.7.2.jar
SOURCES = $(PROGRAM).java

CLASSES = $(PROGRAM).class

all: $(SOURCES)
	$(JC) $(SOURCES)
	xterm -e "$(JR) $(JFLAGS) $(PROGRAM) ; (echo 'Folytatáshoz nyomj egy Entert' && read)"

clean:
	rm $(CLASSES)
    

Java GUI

PROGRAM=jSajatProgram
JAVA = /mnt/tartaly/usr/local/jdk1.6.0_21/bin/
JC = $(JAVA)javac
JR = $(JAVA)java
JFLAGS = -classpath .:sqlite-jdbc-3.7.2.jar
SOURCES = \
	MainFrame.java \
	MasterPanel.java \
	SecPanel.java \
	$(PROGRAM).java

CLASSES = \
	MainFrame.class \
	MasterPanel.class \
	SecPanel.class \
	$(PROGRAM).class

all: $(SOURCES)
	$(JC) $(SOURCES)
	$(JR) $(JFLAGS) $(PROGRAM)

clean:
	rm $(CLASSES)
oktatas/programozas/automatikus_forditas/make.txt · Utolsó módosítás: 2023/08/03 09:34 szerkesztette: admin