Hlavní navigace

Jednoduché vytvoření makefile pro aplikaci v C

13. 9. 2006 17:06 (aktualizováno) Murděj Ukrutný

Před pár měsíci jsem si do počítače v robotě nainstaloval hru Monster Masher, skvělá hra má jen jednu vadu – pomalost a to mě přivedlo k nápadu napsat si podobnou hru. Po čase se už počet zdrojových souborů blíží k 30 a ruční úprava makefile je peklo a proto přišel na řadu skript v bashi.

Princip je jednoduchý: Každý .cpp soubor se kompiluje samostatně jako samostatný modul.Ke každému modulu je třeba vyhledat includované soubory a rekurzivně soubory které se inkludují dotěchto inkludovaných souborů. Výsledek bude jeden spustitelný soubor který vznikne slinkováním skompilovaných modulů.

Skript getincludes.sh najde v zadaném souboru inkludované soubory a zavolá sám sebe pro každý nalezený soubor.

   #!/bin/bash

# Hledá výskyty #include "*" v souboru
files=`awk -F '"' '/#include *".*"/{print $2}'`
for file in $files
do
# Pro každý soubor zavolá sám sebe
files="$files `./getincludes.sh < $file`"
done

# Vypíše všechny nalezené soubory
echo $files

Skript buildmakefile.sh generuje výsledný makefile.

       # Vytvoří adresář pro dočasné soubory
tmp=./tmp
if [ ! -d $tmp ]
then
mkdir $tmp
fi

# Odstraní dočasné soubory z tmp
rm -f $tmp/*

# Načte názvy modoulů ze souboru
modules=`cat modules.lst`
ofiles=""

for module in $modules
do
# Najde všechny includované soubory
includes="`./getincludes.sh -R < $module.cpp`"

# Seřadí a soubory a vyřadí duplicity
# Kvůli formátování jsem musel nahradit zpětné lomítko normálním /n musí být ve skritu se zpětným lomítkem
includes=`echo $includes | tr " " "/n" | sort -u | tr "/n" " "`

# Vytvoří kód pro makefile
echo "$module.o: $module.cpp $includes" >> $tmp/modules
echo " $(CXXC) -c $(CXXFLAGS) $module.cpp" >> $tmp/modules

# A přidá do $tmp/modules
echo "" >> $tmp/modules

# Přidá soubor do seznamu .o souborů
ofiles="$ofiles $module.o";
done

# Zapíše .o soubory do $tmp/ofiles>
echo $ofiles > $tmp/ofiles

Teď mám v souboru $tmp/modules řádky které zkompilují jednotlivé moduly, v souboru
$tmp/ofiles .o soubory ktré se použíjí pro slinkování výsledného souboru.

         # Vyvtoření vysledného makefile
m4 < makefile.m4 > makefile

Soubor makefile.m4 obsahuje šablonu výsledného souboru makefile. V mém případě makefile vypadá takto:

   # protože znak ` dost často používám změní si nastavení uvozovek pro M4
changequote(<: , :>)

APPNAME=tuxxan
CXXFLAGS=`sdl-config --cflags` -O9 m4DEF
LINKFLAGS=`sdl-config --libs` -lSDL_image
CXXC=g++

main: include(tmp/ofiles)
$(CXXC) -o $(APPNAME) include(tmp/ofiles)

include(tmp/modules)

clean:
rm -f $(APPNAME) `ls *.o`

Teď stačí každý zdrojový soubor modulu zadat do modules.lst a spuštením ./buildmakefile.sh si vygenerovat nový makefile

Anketa

Jak zjednodušujute kompilaci