Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
1.2.2 Makefiles
Compilation from the command line is efficient when compiling only small numbers of files. The previous chapter has discussed the advantages of separate compilation but this would also be unwieldy without some form of management. This is provided by the UNIX make utility, which facilitates the compilation process and makes it more efficient for larger projects. The most common way of using make is to create a makefile which contains instructions on how to compile all of the files associated with a larger project. An example makefile is presented below.
############################## #This is a test makefile ############################### #Firstly we define the variables as follows # variablename=whatever #Text substitution is used in order to #replace occurrences of the variables #in the compilation rules CC=gcc #note makefile variables are accessed as $(variablename) #Next we define the rules for creating the executables # output file followed by a colon... # ...then all of the files that make the output file. # first we define the rule for creating the final executable myprog.exe: myprog.o mylibrary.o #NB the next line begins with a tab $(CC) -o myprog.exe myprog.o myobject.o #the next rules define how myprog.o and myobject.o are made myprog.o: myprog.c mylibrary.h $(CC) -c -o myprog.o myprog.c mylibrary.o: mylibrary.c mylibrary.h $(CC) -c -o mylibrary.o mylibrary.c #if you want you can add rules for the compilation of other objects here. # End of Makefile ############################################
The makefile is usually called \makefile", in which case when invoking make from the command line is simple. You type make. If however you want to call your makefile something other than makefile" you use the following version of the command. make -f WhateverYouCalledYourMakefile
Makefiles will be useful when compiling openGL programs because of the need to use a large number of different compiler tags and library functions, the meanings of which will become apparent as you become more and more familiar with Open GL and C programming under Unix systems.
If we called this program test.c and compiled it as follows: gcc -o test test.c The compilation would return an error along the lines of undefined reference to `sqrt'. This is because the linker has not been told where to find the function sqrt. An additional compilation tag is required -lm. This tag tells the linker look inside the library called libm.a (the mathematical functions library) for the code corresponding to any functions in the math.h library. As you may already know, most C header files are stored in a directory called include, and most library files in a directory called lib. The standard headers and libraries can be found in most UNIX systems in /usr/include and /usr/lib. The C compiler will search for libraries and header files in these directories automatically. Certain libraries and headers that do not come as part of the standard C compiler package can be found dotted all around the system (eg. /usr/local), and if you write your own libraries and headers, you will probably have lib and include directories in your own workspace.
When using libraries located outside of /usr the linker needs to be told where to find the headers and the archives. If your header files are stored in a directories called include and lib in /usr/local you need to tell the linker using the -I and -L tags.
gcc -o myprog myprog.c -I/usr/local/include -L/usr/local/lib -lmylib
For every different include directory a separate -I tag and location is needed, and similarly a separate -L tag is needed for each separate library directory. This can make the compilation line quite unwieldy, and so it is often convenient to use makefiles, and to have variables in which the I and -L tags are defined.
IFILES=-I/usr/local/include LFILES=-L/usr/local/lib LIBS=-lmylib -lm ... myprog: myprog.c myprog.h gcc -o myprog myprog.c $(IFILES) $(LFILES) $(LIBS)
Extra tasks 1. Recreate the compilation process using Visual Studio.net 2008 2. Implement the examples from the lecture slides under Unix or windows 3. Implement each of the following functions a) d) and write a testbed program to call each function. The testbed accepts a character to select a function, reads values required to test the function, calls the function which calculates the result, returning it to main() from where it is printed. This is performed repeatedly until q (for quit) is input. i. The testbed should be implemented first and should initially output function x not yet implemented for each valid selection x, or report erroneous selections. ii. Add the following functions one at a time to the testbed. Note that all input and output must occur in the testbed i.e. in main(). a) A function mult(x,y) which returns the value of x*y where x and y are integers. b) A function find_abs(x) which returns the absolute value of the double precision floating point argument x. e.g. find_abs(3.0) produces 3.0, find-abs(-3.0) gives 3.0 c) A function fact(x) which returns x! ( x factorial ) where x is an integer d) A function power(x,y) which returns x to the power of y, where x is a floating point and y is a positive integer e.g. power(3.0,4) gives 81.0 i.e. 3.04. Hint..use repeated multiplication. iii. Finally, add a function to print a menu for the selections and incorporate this in your program. You should incorporate the switch statement and take care when processing characters. You should refer to Lecture 3 to remind yourself of how to input and process characters, paying attention to the return key. Comments should be used throughout. Show your completed testbed to your tutor. 4. Write a program to take a set of 10 integers input by the user and use the values to draw a series of horizontal bars in stars to form a bar chart (on its side!). 5. Investigate drawing the same bar chart in the traditional vertical form