Makefiles
Note: All the programs mentioned in this lecture are in:/home/cs352/SUMMER02/lecture17progs/
- How to write a simple makefile? - Simplest form (Inside a description file, named Makefile) program : main.o file1.o file2.o gcc -o program main.o file1.o file2.o main.o : main.c gcc -c main.c file1.o : file1.c gcc -c file1.c file2.o : file2.c gcc -c file2.c clean : /bin/rm -f *.o - 5 entries. Each entry has a line containing a colon(dependency line) One or more command lines starting with a tab. - To the left of the colon on the dependency line is 'target' To the right are the 'target's dependency files.(In this case the first target is 'program' for example.) - The command lines show how to build the targets out of their dependency files. - In general the command: make program looks for the dependency line with 'program' in the descr. file (Makefile), checks whether any of the dependency files are newer than target. (Do this recursively.) If at any line reached during this recursive checking, target is older than its dependency file execute the corr. commands. - In short, it does the compilation only when necessary.(if the target is not uptodate.) - Some simple syntax: - make will do the first target in the descr. file. - Every command begins with a tab, and only command do so. (not at the beginning of a comment or a dependency line, etc) - # for comments - can have targets without dependency files(The colon must still be there, see the target "clean" above.) - Every nonexistsent target is outofdate.(That's why the commands for "clean" gets executed whenever the command 'make clean' is issued. - can continue a long line with a backslash(\) at the end.(Right before the newline.) - see makefiles1/ - Macros in the makefiles - Entries of the form: identifier = token-string are macro definitions. - Further references to $(identifier) or ${identifier} are the same as token-string. - A macro must be defined before any dependency line in which it appears.(ow order doesn't matter.) - Macro String Substituion: Assume the definition: SRCS = calcmain.c calcgetop.c calcstack.c calcgetch.c then the definition: OBJS = ${SRCS:.c=.o} is equivalent to: OBJS = calcmain.o calcgetop.o calcstack.o calcgetch.o - Internal Macros for Dependency Files and Targets: - $@ refers to target (only in a command line) - $? refers to the list of dep. files that are newer than the target (only in a command line.) - $$@ refers to the target (only on a dependency line.) - see makefiles2/ - Suffix Rules - Unix can recognize suffixes(.o or .c or .h etc.) - The only compilation we needed to specify is: calculator : ${OBJS} ${CC} -o $@ ${OBJS} i.e. we don't specify anything on how to build the .o files. Why? - Because implicitly(predefined) there are the following suffix rules: .SUFFIXES : .o .c .c.o : $(CC) $CFLAGS -c $< - .SUFFIXES: Specify the suffixes that "make" considers significant. If a dependency file has such a suffix, but has no explicit commands make, looks for an applicable suffix rule(like the one given above) Steps that make take upon finding that no explicit command for, say calcmain.o : 1- Sees that .o is significant(implicitly defined) 2- Look for a file in the current directory that: - has the same name as the file(i.e. calcmain) - has a significant suffix(.c for example) - can be used according to a suffix rule. 3- The appropriate suffix rule is: .c.o : $(CC) $CFLAGS -c $< which describes how to make a .o file from a .c file. $< is the same as $? (But $< can only be used with the suffix rules.) In this case it evaluates to calcmain.c 4- If there are no further recursive checks and calcmain.o is outdated with respect to calcmain.c, executes the suffix rule: gcc -c calcmain.c - CFLAGS is a predefined macro, can overwrite it if necessary. - see makefiles3/ - More on gcc and its options: - preprocessing, compiling, assembly, and linking - Options: -c Compile or assemble the source files, but do not link. The ultimate output is in the form of an object file for each source file. (.o files) -o file Place output in file. -Wall Give All the warnings. -w Suppress all warnings -g Enable debugging -O Optimize(Also -O1, -O2, -O3) -D identifier=token-str define a constant -U identifier undefine -Idir Add the directory dir to the list of directories to be searched for header files. Directories named by -I are searched before the standard system include directories. -llibrary Search the library named "library" when linking. The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The directories searched include several standard system directories plus any that you specify with -L. -Ldir Add directory dir to the list of directories to be searched for -l.