Zadání: http://cw.felk.cvut.cz/courses/a4m33pal/task.php?task=makefile_refactoring
Úloha: Jednoduchý makefile refactoring
Uvažujte zjednodušenou verzi známé utility make. Takový jednoduchý make vypisuje posloupnost příkazů nutných k dosažení prvního cíle (prvního ve smyslu prvního ve vstupním souboru) podle níže popsaných pravidel, která se budou nacházet ve vstupním souboru. Každé pravidlo má následující tvar:
cíl: podcíl1 podcíl2 …
<TAB>příkaz1
<TAB>příkaz2 …
Kde cíl je jméno cíle, k jehož provedení je třeba nejprve provést všechny jeho podcíle. Podcíle jsou uvedeny za dvojtečkou a jsou oddělené mezerami. Pořadí, ve kterém se provedou, je libovolné. Po provedení podcílů se na standardní výstup vypisuje posloupnost příkazů pravidla. Před každým příkazem příkaz je tabulátor a je na samostatném řádku. Každý příkaz se vypíše na nový řádek bez počátečního tabulátoru z původního pravidla. Podcíle se vykonávají stejným postupem jako cíl. Pro každý cíl platí, že nemusí obsahovat ani podcíle ani příkazy. Každý cíl v pravidle musí být zakončený dvojtečkou.
Napište program pro údržbu zdrojových souborů (které jsou často označovány názvem makefile) výše popsané utility make, který bude zakomentovávat „mrtvý“ kód.
Vstup pro tento program bude stejný jako pro make. Výstup bude stejný jako vstup, ale s tím rozdílem, že řádky, které nejsou potřeba k dosažení prvního cíle budou ve výstupu zakomentovány. Zakomentování řádku vznikne tak, že se na začátek takového řádku přidá znak #.
Pokud by utilita make nemohla provést první cíl nebo některý jeho podcíl v konečném čase, vypíše program pro údržbu zdrojových souborů na výstup pouze jednořádkovou chybovou zprávu následujícího tvaru:
ERROR
Přepokládejte, že formát vstupního souboru pravidel je syntakticky korektní.
Příklad:
Vstup:
all: hello hello: main.o hello.o g++ main.o hello.o -o hello main.o: main.cpp functions.h g++ -c main.cpp hello.o: hello.cpp functions.h g++ -c hello.cpp hello2.o: hello2.cpp functions.h g++ -c hello2.cpp hello.cpp: echo '#include ' > hello.cpp echo '#include "functions.h"' >> hello.cpp echo 'void print_hello(void){ cout << "Hello World!"; }' >> hello.cpp main.cpp: echo '#include ' > main.cpp echo '#include "functions.h"' >> main.cpp echo 'int main() { print_hello();' >> main.cpp echo 'cout << endl; return 0; } ' >> main.cpp hello2.cpp: echo '#include ' > hello2.cpp echo '#include "functions.h"' >> hello2.cpp echo 'void print_hello(void){ cout << "Hello All!"; }' >> hello2.cpp functions.h: echo 'void print_hello(void);' > functions.h
Výstup:
all: hello hello: main.o hello.o g++ main.o hello.o -o hello main.o: main.cpp functions.h g++ -c main.cpp hello.o: hello.cpp functions.h g++ -c hello.cpp #hello2.o: hello2.cpp functions.h # g++ -c hello2.cpp hello.cpp: echo '#include ' > hello.cpp echo '#include "functions.h"' >> hello.cpp echo 'void print_hello(void){ cout << "Hello World!"; }' >> hello.cpp main.cpp: echo '#include ' > main.cpp echo '#include "functions.h"' >> main.cpp echo 'int main() { print_hello();' >> main.cpp echo 'cout << endl; return 0; } ' >> main.cpp #hello2.cpp: # echo '#include ' > hello2.cpp # echo '#include "functions.h"' >> hello2.cpp # echo 'void print_hello(void){ cout << "Hello All!"; }' >> hello2.cpp functions.h: echo 'void print_hello(void);' > functions.h
Ilustrativní výstup z utility make:
echo '#include ' > main.cpp echo '#include "functions.h"' >> main.cpp echo 'int main() { print_hello();' >> main.cpp echo 'cout << endl; return 0; } ' >> main.cpp echo 'void print_hello(void);' > functions.h g++ -c main.cpp echo '#include ' > hello.cpp echo '#include "functions.h"' >> hello.cpp echo 'void print_hello(void){ cout << "Hello World!"; }' >> hello.cpp g++ -c hello.cpp g++ main.o hello.o -o hello