Automatyzacja zarządzania złożonymi programami

Podobne dokumenty
Make jest programem komputerowym automatyzującym proces kompilacji programów, na które składa się wiele zależnych od siebie plików.

Automatyzacja kompilacji. Automatyzacja kompilacji 1/28

Automatyzacja kompilacji. Automatyzacja kompilacji 1/40

Fragment wykładu z języka C ( )

Programowanie Proceduralne

Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania

Tworzenie oprogramowania

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

Programowanie w C++ Wykład 10. Katarzyna Grzelak. 21 maja K.Grzelak (Wykład 10) Programowanie w C++ 1 / 21

Kompilacja i scalanie programów w linii poleceń gcc i make

Systemy Operacyjne. Ćwiczenia

Podstawy programowania. Wykład 9 Preprocesor i modularna struktura programów. Krzysztof Banaś Podstawy programowania 1

Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych.

Plan wykładów. Oprogramowanie i wykorzystanie stacji roboczych. Wykład 1. Konkurs programistyczny. Literatura. Dr inż. Tomasz Olas

Trochę o plikach wsadowych (Windows)

Pobieranie argumentów wiersza polecenia

X P.I.W.O. Portowanie Tizena na nowe architektury na przykładzie ARMv6. Maciej Wereski Samsung R&D Institute Poland. 17 Maj Poznań, Polska

Wykład. Materiały bazują częściowo na slajdach Marata Dukhana

WPROWADZENIE DO INFORMATYKI

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Programowanie niskopoziomowe

Architektury Usług Internetowych. Laboratorium 2. Usługi sieciowe

Podstawy wykorzystania bibliotek DLL w skryptach oprogramowania InTouch

Niektóre katalogi są standardowymi katalogami zarezerwowanymi do użytku przez system. Znaczenie wybranych katalogów systemowych jest następujące:

Autotools. Bogdan Kreczmer. Katedra Cybernetyki i Robotyki Wydziału Elektroniki Politechnika Wrocławska

Laboratorium 3: Preprocesor i funkcje ze zmienną liczbą argumentów. mgr inż. Arkadiusz Chrobot

Instalacja środowiska MPI w systemie operacyjnym Linux

media Blitz wydajne sytemy szablonów

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 12 - sem.iii. M. Czyżak

IBM SPSS Statistics - Essentials for R: Instrukcje instalacji dla Linux

Laboratorium 2: Biblioteki statyczne i dynamiczne w języku C. mgr inż. Arkadiusz Chrobot

EaglePCB_2_FreeCAD (beta)

Programy użytkowe (utilities)

1 Zapoznanie się ze środowiskiem Xenomai.

Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w

Praktyka programowania projekt

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

System operacyjny Linux

Zbuduj mi ten projekt, prosz.

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Skrypty i funkcje Zapisywane są w m-plikach Wywoływane są przez nazwę m-pliku, w którym są zapisane (bez rozszerzenia) M-pliki mogą zawierać

Sieci i systemy operacyjne I Ćwiczenie 1. Podstawowe polecenia systemu Unix

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Zadanie programistyczne nr 3 z Sieci komputerowych

Tworzenie oprogramowania

System operacyjny Linux

GNU GProf i GCov. przygotował: Krzysztof Jurczuk Politechnika Białostocka Wydział Informatyki Katedra Oprogramowania ul. Wiejska 45A Białystok

Wstęp do programowania. Wykład 1

Rozdział 4 KLASY, OBIEKTY, METODY

Tworzenie oprogramowania

PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO

Rozdział 1. Informacje ogólne

Grzegorz Cygan. Wstęp do programowania mikrosterowników w języku C

MentorGraphics ModelSim

Programowanie w asemblerze Linkowanie

Python jest interpreterem poleceń. Mamy dwie możliwości wydawania owych poleceń:

Podstawy programowania - 1

Qmail radość listonosza. Autorzy: Bartosz Krupowski, Marcin Landoch IVFDS

Programowanie I. O czym będziemy mówili. Plan wykładu nieco dokładniej. Plan wykładu z lotu ptaka. Podstawy programowania w językach. Uwaga!

E.14 Bazy Danych cz. 18 SQL Funkcje, procedury składowane i wyzwalacze

Delphi Laboratorium 3

RPC. Zdalne wywoływanie procedur (ang. Remote Procedure Calls )

Wprowadzenie do biblioteki klas C++

Podstawy Kompilatorów

Wprowadzenie. Programowanie Obiektowe Mateusz Cicheński

Programowanie obiektowe

PARADYGMATY PROGRAMOWANIA Wykład 4

Język JAVA podstawy. wykład 1, część 2. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Zajęcia nr 1 Podstawy programowania. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

1 Podstawy c++ w pigułce.

Programy pomocnicze: diff, make, systemy rcs i cvs, debugger. Zarządzanie wersjami.

Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR

Praca w środowisku Visual Studio 2008, Visual C

USB firmware changing guide. Zmiana oprogramowania za przy użyciu połączenia USB. Changelog / Lista Zmian

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat

System operacyjny UNIX Ćwiczenie 1. Podstawowe polecenia systemu Unix

Programowanie obiektowe zastosowanie języka Java SE

Zaawansowane programowanie w (pakiecie) Delphi

Ćwiczenie 1. Przygotowanie środowiska JAVA

Egzamin pisemny z przedmiotu: Systemy operacyjne Semestr I

Podstawy informatyki

Bardzo krótki kurs Perla

Poprzedni wykład [ ] :

Laboratorium Projektowania Systemów VLSI-ASIC Katedra Elektroniki Akademia Górniczo-Hutnicza

Inżynieria Wytwarzania Systemów Wbudowanych

Programowanie w C. dr inż. Stanisław Wszelak

Mikrokontroler ATmega32. Język symboliczny

Użycie Visual Basic for Applications ("VBA")

TEMAT : KLASY DZIEDZICZENIE

Optymalizacja programów Open Source. Profilery wysokiego poziomu część 2. Krzysztof Lichota

Functionalization. Jeszcze o funkcjach i strukturze projektu. Marcin Makowski. 3 grudnia Zak lad Chemii Teoretycznej UJ

Java Podstawy. Michał Bereta

1 Przygotował: mgr inż. Maciej Lasota

#line #endif #ifndef #pragma

Co nie powinno być umieszczane w plikach nagłówkowych:

Powłoka I. Popularne implementacje. W stylu sh (powłoki zdefiniowanej w POSIX) W stylu csh. bash (najpopularniejsza) zsh ksh mksh.

TEMAT : System operacyjny MS DOS pliki wsadowe

Transkrypt:

Automatyzacja zarządzania złożonymi programami Zbigniew Jurkiewicz 13 lutego 2012 1 MAKE Na przykładzie narzędzia MAKE przedstawimy automatyzację zarządzania złożonymi programami. Cel: automatyzacja selektywnej kompilacji, linkowania itp. zmodyfikowanych modułów (fragmentów) złożonych programów komputerowych; wyeliminowanie doraźnie pisanych skryptów powłoki (plików wsadowych). Zasady są następujące: Programista określa reguły opisujące sposób budowy programu z plików źródłowych. Reguły te składają się na specjalny plik, tzw. makefile (o takiej właśnie domyślnej nazwie). Program MAKE na podstawie reguł steruje pracą kompilatorów, linkerów itp. narzędzi programisty. Może być też używany do sterowania pracą innych programów, np. programu TEX do składania tekstów. Wywołanie: $ make powoduje zbudowanie domyślnego obiektu (zob. poniżej), natomiast $ make prog1 powoduje zbudowanie obiektu prog1. Oba wywołania korzystają z domyślnego pliku reguł o nazwie makefile. Można to zmienić korzystając z opcji -f: 1

$ make -f moje.reguly $ make -f moje.reguly prog1 Inna użyteczna opcja to: -n Wyświetla polecenia do wykonania, ale ich nie wykonuje. Przydatna podczas tworzenia pliku z regułami do testowania go. Składowe pliku makefile: komentarze Rozpoczynają się znakiem #. makrodefinicje Wprowadzają symbole, które mogą być używane w regułach. reguły Określają zależności między produktami i surowcami oraz sposób tworzenia produktów z surowców. Dzielą się na jawne i domyślne. 1.1 Reguły Reguły jawne określają zależności pomiędzy obiektem docelowym (produktem) a obiektami, wymaganymi do jego skonstruowania (surowcami): Plik skompilowany w języku C zależy od odpowiadającego mu pliku źródłowego i być może jakichś plików nagłówkowych, np. prog1.o: prog1.c stale.h Reguła powyższa określa, że do zbudowania pliku prog1.o wymagane jest istnienie plików prog1.c oraz stale.h. Po uruchomieniu programu MAKE porównuje się daty ostatnich modyfikacji dla plików docelowych i źródłowych. Jeśli pliki źródłowe były modyfikowane później, plik docelowy jest regenerowany. Podobnie postępuje się, jeśli plik docelowy wogóle nie istnieje. Poznana reguła opisywała tylko zależności między plikami, nie określała natomiast sposobu regeneracji pliku docelowego. Przebieg regeneracji może być specyficzny dla danej reguły bądź też wspólny dla całej klasy reguł. W pierwszym przypadku przebieg regeneracji opisywany jest w kolejnych wierszach reguły jawnej. Wiersze te powinny rozpoczynać się znakiem tabulacji. W takim przypadku powyższa reguła przybrałaby postać 2

prog1.o: prog1.c stale.h cc -c prog1.c Polecenia występujące w regułach mogą być poprzedzane znakami specjalnymi. Poprzedzenie polecenia znakiem specjalnym @ zapobiega wyświetleniu polecenia podczas wykonania clean: @echo Usuwamy zbędne już pliki rm zbedny.o rm niepotrzebny.o @echo nawet jeśli ich nie ma. Polecenia w treści reguły wykonuje się w nowym shellu normalnie jest to /bin/sh, ale można na początku pliku określić inny, nadając wartość zmiennej SHELL. 1.2 Makra Makrodefinicje służą do zwięzłego nazywania ciągów symboli. Zdefiniowane nazwy, tzw. makra, mogą następnie być wystąpić w regułach i są wtedy zastępowane odpowiadającymi im ciągami symboli. Możemy np. zdefiniować # # Definicja makra INCLUDE # INCLUDE=stale.h prototypy.h Makra wołane w regułach poprzedza się znakiem $ (dolar) i otacza nawiasami (nie dotyczy to jednoznakowych makr systemowych). Tak więc zdefiniowane przez nas makro może być następnie użyte w regule w następujący sposób prog1.o: prog1.c $(INCLUDE) Reguła ta po rozwinięciu makra przyjmie postać prog1.: prog1.c stale.h prototypy.h Typowe makra: AR AS CC CFLAGS CXX CXXFLAGS LDFLAGS Program do budowy bibliotek (ar) Asembler (as) Kompilator języka C (cc) Flagi dla kompilatora C Kompilator języka C++ (g++) Flagi dla kompilatora C++ Flagi dla linkera ld Dodatkowo w makrowołaniu można użyć podstawienia. Podstawienie zastępuje podany po znaku : ciąg znaków innym, podanym po znaku =, ale jedynie na końcu symboli SRCS=glowny.c proc1.c proc2.c OBJS=$(SRCS:.c=.o) 3

1.3 Phony targets Obiekt docelowy w regule nie musi być plikiem. Takie obiekty określa się jako phony. Ponieważ w bieżącym katalogu może przypadkowo znaleźć się plik o takiej samej nazwie, obiekty takie można (i warto) deklarować.phony: clean Typowe obiekty, którym nie odpowiadają pliki, to: all Jego obiektami źródłowymi są wszystkie zwykłe obiekty docelowe. Akcje są na ogół zbędne. check Wykonuje testy akceptacyjne programu budowanego tym makefilem przed jego zainstalowaniem w docelowym miejscu. test Wykonuje testy akceptacyjne programu budowanego tym makefilem po jego zainstalowaniu w docelowym miejscu. clean Usuwa z bieżącego katalogu wszystkie robocze pliki pośrednie tworzone podczas budowy tego programu. Nie usuwa plików konfiguracyjnych. distclean Działa jak clean, ale dodatkowo usuwa pliki konfiguracyjne. dist Tworzy plik dystrybucyjny programu, np. typu tar albo skompresowany. Zaleca się, aby nazwy wszystkich plików rozpoczynały się podkatalogiem o nazwie takiej jak dystrybuowany pakiet. Warto, aby nazwa obejmowała numer wersji, np. plik dystrybucyjny tar kompilatora GCC w wersji 1.40 rozpakowuje się do podkatalogu gcc-1.40. Najprościej wykonać to tworząc odpowiednio nazwany podkatalog, a następnie kopiując do niego właściwe pliki i budując z niego archiwum. install Umieszcza binarny plik wykonywalny w systemowym katalogu z takimi plikami (np. /usr/bin oraz pliki pomocnicze w katalogach, w których powinny być przechowywane (np. /usr/lib). W przypadku braku odpowiednich katalogów tworzy je. uninstall Usuwa wszystkie pliki instalowane w tym pakiecie. print Drukuje wszystkie zmienione pliki źródłowe. Program MAKE wywołany bez argumentu próbuje zbudować obiekt domyślny docelowy obiekt pierwszej napotkanej reguły jawnej. Obiekt docelowe pozostałych reguł są budowane jedynie w miarę potrzeby. Często jako pierwszą regułę jawną podaje się regułę all: prog1 prog2 prog3 aby domyślnie zbudować wszystkie wymienione obiekty. Można też oczywiście wywołać MAKE, podając mu jawnie (jako argument) obiekt do zbudowania. 4

1.4 Błędy niefatalne Normalnie program MAKE przerywa pracę po napotkaniu pierwszego polecenia, którego wykonanie zakończy się błędem. Poprzedzenie polecenia przedrostkiem - zapobiega sprawdzaniu jego poprawności. Inaczej mówiąc, niezależnie od wyniku wykonania polecenia MAKE kontynuuje pracę prog1.o: prog1.c stale.h @echo Teraz będziemy kompilować -cc -c prog1.c 1.5 Przykład objects=main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o edit: $(objects) cc -o edit $(objects) main.o: defs.h kbd.o: defs.h command.h command.o: defs.h command.h display.o: defs.h buffer.h insert.o: defs.h buffer.h search.o: defs.h buffer.h files.o: defs.h buffer.h command.h utils.o: defs.h clean : -rm edit $(objects) 1.6 Reguły domyślne Często sposób regeneracji objektu nie zależy od konkretnych plików, lecz jest wspólny dla wszystkich plików tego samego typu. Można wtedy skorzystać z reguły domyślnej. Opisuje ona, jak plik o pewnym rozszerzeniu otrzymuje się z pliku o tej samej nazwie, różniącego się tylko rozszerzeniem. Oba rozszerzenia podaje się wtedy przed dwukropkiem, np..c.o: cc -c $< 1.7 Makra predefiniowane W regule powyższej wystąpiło systemowe makro $<, zastępowane podczas użycia reguły (pełną) nazwą pliku źródłowego. 5

Istnieją również inne predefiniowane makra systemowe, których nazwami są pojedyncze znaki przestankowe. Ich znaczenie podaje poniższa tabelka: Makro Znaczenie $* Bazowa nazwa pliku docelowego (bez rozszerzenia) $< Pełna nazwa pliku $: Katalog zawierający plik (odcięta ostatnia część pełnej nazwy, tzn. nazwa właściwa i rozszerzenie) $. Właściwa nazwa pliku wraz z rozszerzeniem $& Sama nazwa pliku (bez katalogu/ścieżki ani rozszerzenia) Jeśli pełną nazwą pliku jest /home/pjotr/projekt/prog1.c, to poszczególne makra oznaczać będą: $* /home/pjotr/projekt/prog1 $< /home/pjotr/projekt/prog1.c $: /home/pjotr/projekt/ $. prog1.c $& prog1 1.8 Zalecenia Gdy nasz program ma działać na wielu platformach (np. Linux i MS Windows), warto wydzielić w osobne pliki fragmenty zależne od środowiska. Dla prostego programu w pliku głównym pozostałoby tylko # Główny plik makefile all = program$(exe) include environ all : program$(obj) $(CC) $@ program$(obj) $(LIBS) natomiast zależny od platformy plik environ dla UNIXA miałby postać # Makra make specyficzne dla UNIXA OBJ=.o EXE= CC=cc -g -o LIBS=-lX11 -lm a dla MS Windows 6

# Makra make specyficzne dla MS Windows OBJ=.obj EXE=.exe CC=gcc -g -o LIBS=-lm 1.9 Przenośność Warto poprzedzać wszystkie odwołania do plików źródłowych prefiksem $(SRCDIR)/, na przykład ${SRCDIR}/parser.tab.c: ${SRCDIR}/parser.y ${YACC} -d ${SRCDIR}/parser.y mv y.tab.c ${SRCDIR}/parser.tab.c mv y.tab.h ${SRCDIR}/parser.tab.h Dzięki temu można wywołać make z katalogu innego niż żródłowy. Zwróćmy uwagę na plik parser.tab.c plik w języku C generowany przez $(YACC). Po utworzeniu przenosimy go do katalogu źródłowego. Podobnie dzieje się z plikiem y.tab.h. 1.10 Narzędzia Program makedepend w Unixie (pół)automatycznie generuje zależności. 1.11 Duży przykład Pora na większy przykład oryginalny makefile dla programu tar w wersji GNU. Domyślnym obiektem docelowym jest all. # Generated automatically from Makefile.in by configure. # Un*x Makefile for GNU tar program. # Copyright (C) 1991 Free Software Foundation, Inc. # This program is free software; you can redistribute # it and/or modify it under the terms of the GNU # General Public License......... SHELL = /bin/sh #### Start of system configuration section. #### srcdir =. # If you use gcc, you should either run the 7

# fixincludes script that comes with it or else use # gcc with the -traditional option. Otherwise ioctl # calls will be compiled incorrectly on some systems. CC = gcc -O YACC = bison -y INSTALL = /usr/local/bin/install -c INSTALLDATA = /usr/local/bin/install -c -m 644 # Things you might add to DEFS: # -DSTDC_HEADERS If you have ANSI C headers and # libraries. # -DPOSIX If you have POSIX.1 headers and # libraries. # -DBSD42 If you have sys/dir.h (unless # you use -DPOSIX), sys/file.h, # and st_blocks in struct stat. # -DUSG If you have System V/ANSI C # string and memory functions # and headers, sys/sysmacros.h, # fcntl.h, getcwd, no valloc, # and ndir.h (unless # you use -DDIRENT). # -DNO_MEMORY_H If USG or STDC_HEADERS but do not # include memory.h. # -DDIRENT If USG and you have dirent.h # instead of ndir.h. # -DSIGTYPE=int If your signal handlers # return int, not void. # -DNO_MTIO If you lack sys/mtio.h # (magtape ioctls). # -DNO_REMOTE If you do not have a remote shell # or rexec. # -DUSE_REXEC To use rexec for remote tape # operations instead of # forking rsh or remsh. # -DVPRINTF_MISSING If you lack vprintf function # (but have _doprnt). # -DDOPRNT_MISSING If you lack _doprnt function. # Also need to define # -DVPRINTF_MISSING. # -DFTIME_MISSING If you lack ftime system call. # -DSTRSTR_MISSING If you lack strstr function. # -DVALLOC_MISSING If you lack valloc function. # -DMKDIR_MISSING If you lack mkdir and # rmdir system calls. # -DRENAME_MISSING If you lack rename system call. # -DFTRUNCATE_MISSING If you lack ftruncate # system call. # -DV7 On Version 7 Unix (not # tested in a long time). 8

# -DEMUL_OPEN3 If you lack a 3-argument version # of open, and want to emulate it # with system calls you do have. # -DNO_OPEN3 If you lack the 3-argument open # and want to disable the tar -k # option instead of emulating open. # -DXENIX If you have sys/inode.h # and need it 94 to be included. DEFS = -DSIGTYPE=int -DDIRENT -DSTRSTR_MISSING \ -DVPRINTF_MISSING -DBSD42 # Set this to rtapelib.o unless you defined NO_REMOTE, # in which case make it empty. RTAPELIB = rtapelib.o LIBS = DEF_AR_FILE = /dev/rmt8 DEFBLOCKING = 20 CDEBUG = -g CFLAGS = $(CDEBUG) -I. -I$(srcdir) $(DEFS) \ -DDEF_AR_FILE=\"$(DEF_AR_FILE)\" \ -DDEFBLOCKING=$(DEFBLOCKING) LDFLAGS = -g prefix = /usr/local # Prefix for each installed program, # normally empty or g. binprefix = # The directory to install tar in. bindir = $(prefix)/bin # The directory to install the info files in. infodir = $(prefix)/info #### End of system configuration section. #### SRC1 = tar.c create.c extract.c buffer.c \ getoldopt.c update.c gnu.c mangle.c SRC2 = version.c list.c names.c diffarch.c \ port.c wildmat.c getopt.c SRC3 = getopt1.c regex.c getdate.y SRCS = $(SRC1) $(SRC2) $(SRC3) OBJ1 = tar.o create.o extract.o buffer.o \ getoldopt.o update.o gnu.o mangle.o OBJ2 = version.o list.o names.o diffarch.o \ port.o wildmat.o getopt.o OBJ3 = getopt1.o regex.o getdate.o $(RTAPELIB) OBJS = $(OBJ1) $(OBJ2) $(OBJ3) AUX = README COPYING ChangeLog Makefile.in \ 9

makefile.pc configure configure.in \ tar.texinfo tar.info* texinfo.tex \ tar.h port.h open3.h getopt.h regex.h \ rmt.h rmt.c rtapelib.c alloca.c \ msd_dir.h msd_dir.c tcexparg.c \ level-0 level-1 backup-specs testpad.c all: tar rmt tar.info tar: $(OBJS) $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) rmt: rmt.c $(CC) $(CFLAGS) $(LDFLAGS) -o $@ rmt.c tar.info: tar.texinfo makeinfo tar.texinfo install: all $(INSTALL) tar $(bindir)/$(binprefix)tar -test! -f rmt $(INSTALL) rmt /etc/rmt $(INSTALLDATA) $(srcdir)/tar.info* $(infodir) $(OBJS): tar.h port.h testpad.h regex.o buffer.o tar.o: regex.h # getdate.y has 8 shift/reduce conflicts. testpad.h: testpad./testpad testpad: testpad.o $(CC) -o $@ testpad.o TAGS: $(SRCS) etags $(SRCS) clean: rm -f *.o tar rmt testpad testpad.h core distclean: clean rm -f TAGS Makefile config.status realclean: distclean rm -f tar.info* shar: $(SRCS) $(AUX) shar $(SRCS) $(AUX) compress \ > tar- sed -e /version_string/!d \ -e s/[^0-9.]*\([0-9.]*\).*/\1/ \ -e q 10

version.c.shar.z dist: $(SRCS) $(AUX) echo tar- sed \ -e /version_string/!d \ -e s/[^0-9.]*\([0-9.]*\).*/\1/ \ -e q version.c >.fname -rm -rf cat.fname mkdir cat.fname ln $(SRCS) $(AUX) cat.fname -rm -rf cat.fname.fname tar chzf cat.fname.tar.z cat.fname tar.zoo: $(SRCS) $(AUX) -rm -rf tmp.dir -mkdir tmp.dir -rm tar.zoo for X in $(SRCS) $(AUX) ; do \ echo $$X ; \ sed s/$$/^m/ $$X \ > tmp.dir/$$x ; done cd tmp.dir ; zoo am../tar.zoo * -rm -rf tmp.dir 11