# Let us imagine that we have two files "main.c" and "phone.c" # Further let us assume that main.c depends on (#include) phone.h # The files main.c and phone.c are to be compiled and linked to form an # executable module (execution file) called "phone". # The commands to do this are: gcc -Wall -ansi -c main.c gcc -Wall -ansi -c phone.c gcc -Wall -ansi -o phone main.o phone.o # The first two compilations produce main.o and phone.o (because of the -c flag) # The -Wall flag will cause all warning messages to be displayed # The -ansi flag says that strict ANSI standard C will be required # C programs that are written to these standards will normally compile correctly # under the C++ compiler (later to be called g++) # From the above we may deduce that: # the file phone depends on files phone.o and main.o # the file main.o depends on phone.h and main.c # the file phone.o depends on phone.c # Further we note than main.c and phone.c are independent. For example, if we alter # the contents of main.c there is no need to re-compile phone.c # with this information we can now construct a makefile that will minimize the # amount of work needed to rebuild the phone executable. # Note, this is a quite minimal example, you will be building more elaborate # makefiles to support your assignments. # The next line states that phone is dependent on main.o and phone.o # and should either file phone.o or main.o be "newer" than file phone # then execute the command on the line after it. phone : main.o phone.o gcc -Wall -ansi -o phone main.o phone.o # The next line states that phone.o depends on phone.c # and the line after is the command to generate phone.o phone.o : phone.c gcc -Wall -ansi -c phone.c # The next lines states that main.o depends on both main.c and phone.h # and the line after is the command to generate main.o # Note that the file main.c starts with #include "phone.h" main.o : main.c phone.h gcc -Wall -ansi -c main.c # Once the makefile has been created a new command becomes available to you # In this case "make phone" will rebuild the executable file "phone" and in turn # it is execute with the command "phone" # Note there is a lot of repetition in the above make file. To reduce this, and to # help avoid minor errors, the make facility provides a macro (or define) facility. # Thus in practice the make file might really look like CREATOR = gcc -Wall -ansi phone : main.o phone.o $(CREATOR) -o phone main.o phone.o phone.o : phone.c $(CREATOR) -c phone.c main.o : main.c phone.h $(CREATOR) -c main.c # In the above the macro CREATOR is defined to be "gcc -Wall -ansi" # and the macro is expanded whenever $(CREATOR) appears. # The names you choose for macros are entirely yours. # See the assignment 1 statement for a different use of a makefile: # Namely to build and run a series of experiments, recompiling only those # that you modify. # One useful parameters that go with the "make' command is # -n # make -n phone # would display the actual commands that will be executed when you do "make phone" # Note, nothing changes it only tells you what will happen. This is extremely useful # when you have a complex makefile and you want to be sure that will be doing the # right thing # Finally, in case you have not guessed. In a makefile, any line that begins with a # # is treated as a comment. This notation is common in other unix-scripting languages # like shell scripts.