230 likes | 342 Views
제 16 강 : make. make automating compilation. 500 directories --- 8000 files. If I change a source file. 1. Modified z in a.c 2. Compile only a .c ? Compile all ? (several hours!!). Modified z in a.c Now Compile which files?. How other files should change. symbol table:.
E N D
제16강 : make make automating compilation
500 directories --- 8000 files If I change a source file 1. Modified z in a.c 2. Compileonly a .c? Compileall? (several hours!!) Modified z in a.c Now Compile which files?
How other files should change symbol table: • z was defined in a,c • other file (eg file.c) uses z Symbol Address Type file.c: file.o: add 077123 local x 12345 global y 67890 z777999extern add() { int x; char y; x++ y++ …. z-- …. z++ } add() { } z’s type z’s address • z is modified • in a.c file 074 777999 • Then follow link, modifying • instructions that use z • (address or opcode, …) • gcc ALL files which #include z 073 777999
Optimal compile procedure src --- (1) modify a.c (int z buf z;) (2) modify header file (extern buf z;) (3) gcc a.c (new a.o) (4) gcc all files #including this header file (z) (new *.o files) (5) re-link & re-build (new a.out) obj---- a.out---
recompile ALL files using extern z (files #including z) Modified z? Space is allocated for z Address binding -- z #include z.h; z =0; b.c: a.c: int z; #include z.h; z = z + 1; c.c #include z.h; z = z -1; d.c: dependency relation between files
dependency between files a.o | a.c a.out “a.o depends on a.c” a.o (younger than) a.c (a.c renewed?) (renew a.o) “action” to renew a (eg gcc) a.o b.o c.o b.c z.h a.c c.c notation -- makefile a.o : a.c tab action
makefile -- 2 kinds of lines (1) Dependency Condition colon(:) “a.out depends on a.o ” target must be younger than source “target” “source” makefile: • a.out: a.o b.o • ld a.o b.o TAB (2) Action [tab] run sh commands target becomes younger than source
automatic generation of makefile (1) gcc –M *.c generates dependency relation b.c: a.c dependency line gcc b.c action line a.out: a.o, b.o dependency line ld a.o b.o action line (3) After modifying source, run make command • make command checks makefile • recompiles minimum number of files • fastest build time (2) save it in makefile cd linux-practice cd make_ex rm *.o gcc –M *.c
a.out libmy.a a.o b.o c.o b.c z.h a.c c.c typical content of makefile • a.out: a.o b.o • gcc a.o b.o • a.o: a.c • gcc a.c • b.o: b.c z.h • gcc bc. z.h • libmy.a: a.o b.o • ar libmy.a a.o b.o TAB TAB TAB TAB
steps taken by make a.out a.o b.o b.h a.c a.h b.c • a.out: a.o b.o • gcc a.o b.o • a.o: a.c a.h • gcc a.c a.h • b.o: b.c b.h • gcc bc. b.h % make *** if target is specified, start from *** else, start from 1st (top) target a.out --- at a.out --- compare times between (target-source) what is time of source? (source - a.o…) --- at a.o --- compare times between (target-source) what is time of source? (source - a.c …) recursively repeat down the tree TAB TAB TAB starts from 1st target compare time what’ time of a.o? ex cd linux-practice cd make_ex make compare time what’s time of a.c?
Dummy Target makefile: Dummy target: targets which is not a file represent any activity names such as install, build, library … If you say eg “make do_this” Then start from “do_this” target Frequently used to install, library update, … • a.o: a.c • gcc a.c • do_this: • gcc x.c y.c ex make –f makefile_plain # 1st target make ldo_this–f makefile_plain
do-this x.o y.o x.c y.c lib a.out e.o f.o a.o b.o f.h e.c e.h f.c b.h a.c a.h b.c Multiple targets … a.out: a.o b.o a.o: a.c a.h b.o: b.c b.h do-this: gcc x.c y.c lib: ar rc libk.a e.o f.o % make default is 1st target (a.out) % make lib % make do-this
Implicit makefile: • a.out: a.o b.o • gcc a.o b.o • a.o: a.c a.h • gcc a.c a.h • b.o: b.c b.h • gcc bc. b.h can abbreviate this can abbreviate this TAB TAB makefile: TAB a.out: a.o b.o a.o: a.c a.h ex cd cd make_ex cat makefile_implicit touch div.c make –f makefile_implicit
Macro • OBJ= add.o sub.o mul.o main.o /*long string */ Example: all : $(OBJ) gcc -o all $(OBJ) Internal macro • Current target @ • all : $(OBJ) all : $(OBJ) • gcc -o all $(OBJ) gcc -o $@ $(OBJ) • Also • $? $< $* …. ==
special dependencies :: • If source 1 changes target is created (or updated) by action 1 • If source 2 changes target is created (or updated) by action 2 target :: source1 action1 target :: source2 action2
directory hierarchy & make • make usually works in a single directory • In large projects, source files occupy a tree • tree has many sub-directories … • let each sub-directory have its own Makefile src A B C Makefile Makefile a1.c a2.c Makefile b1.c b2.c
cd src make 1st target (final) depends on do_A do_A is not a file (dummy target) it has no corresponding source just take action in next line src A B C Makefile a1.c a2.c all: $(GCC) –c a1.c a2.c Makefile b1.c b2.c all: $(GCC) –c b1.c b2.c Makefile OBJ= A/a1.o A/a2.o B/b1.o B/b2.o final: do_A do_B $(GCC) -o final $(OBJ) do_A: cd A; make all; do_B: cd B; make all;
Examplerecursive make cd make_ex_recursive /* top level */ cat makefile make /* traverse below do_A, do_B see if any new files are found No new files are seen this time .. so ..*/ ls -R touch main_d/main.c make /* now this time -- gcc main.c */ Not just for build, but for library, source file, document, install managements
development platform environment PC PC PC PC PC PC PC compiler library header files environment variables
macro & coding style • Macro OBJ=add.o sub.o mul.o main.o /*long names*/ GCC=/usr/bin/gcc /*commands*/ PATH=/bin:/usr/bin:X11/bin /*environment*/ INCL=/usr/src/include /*directories*/ Example: all : $(OBJ) $(GCC) -o all $(OBJ) Never use simple command like “gcc” Always use full pathname for commands, directories. Also explicitly specify PATH within make if necessary Because directories, environments … can change so easily.
Makefile Macro & Software Quality Andrew Oram & Steve Talbott, Managing Projects with make, O’Reilly (p 65) • Watch environment variables, alias etc • they depend on userid, … • Use full pathname for every command in makefile • Also in shell script, crontab, …. • Different command may be invoked if • userid, PATH, PWD, host, …. • Provide full information for environments in makefile • PATH INCLUDE ….
Makefile MacroConditional Compile • Use single source file for many different situations? #ifdef SMP struct buf buf={3, 1,2} #else struct buf buf={4, 4, 1} #endif • To compile only those parts you want, • define compile time option in gcc command • By editing makefile as follows (to cc for different hardware): CFLAGS = -DSMP $(GCC) $(CFLAGS) $(SRC) Inside C source “if defined” makefile:
misc. • imake • If target systems differ (source code / build process) may be different • Indicate system differences in .cf files eg sun.cf : Coptions= … HasBSDsocket= … • Then imake generates platform specific makefile for SUN, … • imake use C preprocessor to edit makefile. • Other related topics: nmake, makedepend, ….