Introduction To Make: Example
Introduction To Make: Example
Introduction To Make: Example
Introduction to Make
Programs are made from separate source files, which correspond to different software modules of the overall program. Each of these files is then compiled into object code, by the compiler, and then linked in one executable, by the linker.
Linker (ld)
Executable
Example:
input.c
input.h
global.c
global.h
$gcc input.c c o input.o $gcc global.c c o global.o $gcc main.c c o main.o $gcc input.c global.c main.c -o prog
DEI-FCTUC
1/6
input.c #include "global.h" #include "input.h" void menu() { ... error = NO_SCREEN; } global.c #include "global.h" int error = NO_ERROR;
#ifndef _INPUT_H #define _INPUT_H extern void menu(); #endif global.h #ifndef _GLOBAL_H #define _GLOBAL_H #define NO_ERROR #define NO_SCREEN extern int error; #endif 0 1
input.h
Each module is defined in a .c file. Each function that is to be accessed externally has its interface in the corresponding .h file. Global variables are declared in .c files. Their existence is declared in .h files by using extern. By using #ifndef / #define , duplication of definitions is avoided during compilation.
Make
The purpose of the make utility is to determine automatically which pieces of a large program need to be recompiled, and issue the commands to recompile them. Special files (makefiles) describe the relationships among files in the program, and state the commands for updating each file. Only needed files (the ones that were modified and their dependencies) are compiled each time. Syntax: make [-f makefile] [target ...] If a makefile is not specified, make expects a file called Makefile or makefile to be used. If a target is not specified the first in the file is chosen.
DEI-FCTUC
2/6
Makefile prog:
To build this
main.o global.o input.o gcc main.o global.o input.o -o prog input.c input.h global.h gcc input.c -c input.o
input.o:
global.o: global.c global.h gcc global.c -c global.o main.o: main.c input.h global.h gcc main.c -c main.o
Figure 1 Direct Makefile Put a TAB between targets (e.g.: prog:) and the files on which they depend (e.g.: main.o global.o input.o). Put a TAB before the commands to execute. Leave a blank line between targets.
Makefile CC = gcc OBJS = main.o global.o input.o PROG = prog # GENERIC all: clean: ${PROG} rm ${OBJS} *~ ${PROG}
A macro
global.o: global.c global.h ${CC} global.c -c -o global.o main.o: prog: main.c input.h global.h ${CC} main.c -c -o main.o ${OBJS} ${CC} ${OBJS} -o prog
Figure 2 Introduction to macros
DEI-FCTUC
3/6
Special macros (see manual): o $@ Refers to the current target name o $< Represents the name of the component that is being used to make the target
Makefile CC = gcc OBJS = main.o global.o input.o PROG = prog # GENERIC all: clean: ${PROG} rm ${OBJS} *~ ${PROG}
global.o: global.c global.h ${CC} global.c -c -o global.o main.o: prog: main.c input.h global.h ${CC} main.c -c -o main.o ${OBJS} ${CC} ${OBJS} -o prog
Figure 3 Special macros
DEI-FCTUC
4/6
Makefile CC = gcc OBJS = main.o global.o input.o PROG = prog # GENERIC all: clean: ${PROG}: .c.o: ${PROG} rm ${OBJS} *~ ${PROG} ${OBJS} ${CC} ${OBJS} -o $@ ${CC} $< -c -o $@
Turns a .c into an .o
Dependencies list
DEI-FCTUC
5/6
global.c
global.h
Makefile CC = gcc OBJS = main.o global.o input.o PROG = prog # GENERIC all: clean: ${PROG}: .c.o: ${PROG} rm ${OBJS} *~ ${PROG} ${OBJS} ${CC} ${OBJS} -o $@ ${CC} $< -c -o $@
You only have to change the shadow parts to compile different projects, or to update your files during the same project! The project becomes up-to-date on every call to Make.
DEI-FCTUC 6/6