Compiling your program is easy when you’re working with one source and the standard libraries, but it gets more complex as you go along. That’s why God put “make” on this earth.
The First Makefile
…was created alongside the Earth. Every other makefile is derived from a previous one.
Jokes aside, the make program reads a makefile script to manipulate files and generate calls to your chosen compiler. The format for makefiles is similar to the format for bash scripting, with some subtle variations.
The key elements of a makefile are:
- Environment Variables – These store sections of code or names of files
- Tags – These store sections of code to perform
- default Tag – This tag instructs make to perform a standard operation when called (assuming no other commands called)
- clean Tag – This tag contains a simple script to undo all the work performed by the default operation
Note: The default name for a makefile is Makefile. If you want to use a different name, you will have to call it like this:
make -f File_Name
An Example: Makefile
It’s very difficult to explain, but reasonably easy to demonstrate. Assuming you’ve been keeping up with the code thus far, this makefile will build all of our sources in one go.
#The Compiler we will use CC=gcc #The flags we pass to the compiler # -g Compile with debugging flags # -Wall Compile and throw all warnings CFLAGS=-g -Wall #If we were using a set of libraries (OpenSSL, for example), we'd have something here #LIBS= #An Environment Variable with all the function names ALL=ae ap args bad_malloc char_string do_math file_io helloworld input linked_list llt loop new_record point precomp #If we don't call anything special, build all default: $(ALL) #The format for this is a bit particular # ae: The final name of the program (matches a name in ALL) # array_eg.c The source(s) from which we build this program # $(CC) Start the command with the contents of the variable CC # $(CFLAGS) Next part of the command is found in the contents of the variable CFLAGS # -o gcc tag -o, meaning that the next word of the command is the function name # $@ Get the name of the tag (in this case, ae) # $^ Get the source(s) from the line above (in this case, array_eg.c) ae: array_eg.c $(CC) $(CFLAGS) -o $@ $^ ap: arr_point.c $(CC) $(CFLAGS) -o $@ $^ args: args.c $(CC) $(CFLAGS) -o $@ $^ bad_malloc: bad_malloc.c $(CC) $(CFLAGS) -o $@ $^ char_string: char_string.c $(CC) $(CFLAGS) -o $@ $^ do_math: do_math.c $(CC) $(CFLAGS) -o $@ $^ -lm file_io: file_io.c $(CC) $(CFLAGS) -o $@ $^ helloworld: helloworld.c $(CC) $(CFLAGS) -o $@ $^ input: input.c $(CC) $(CFLAGS) -o $@ $^ linked_list: linked_list.c $(CC) $(CFLAGS) -o $@ $^ llt:linked_list_two.c $(CC) $(CFLAGS) -o $@ $^ loop: loop.c $(CC) $(CFLAGS) -o $@ $^ new_record: new_record.c person_record.c $(CC) $(CFLAGS) -o $@ $^ point: pointer_one.c $(CC) $(CFLAGS) -o $@ $^ precomp: precomp.c $(CC) $(CFLAGS) -o $@ $^ #When we say "make clean", this will remove all the files so we can recompile from scratch #These are basic commands clean: -rm -f *.o -rm -f $(ALL)
Using make looks something like this (click for enlarged view):