Sei sulla pagina 1di 6

Tutorial 1: Compiling C Programs in UNIX

Section 1: Simple compilation 1.1.1 Introduction


This chapter is intended to provide an introduction to compiling C programs under UNIX operating systems for those who are unfamiliar with the process. The C compiler used will be the gcc compiler (which stands for GNU C compiler), which forms part of the GNU compiler collection. This collection of programming tools includes compilers for FORTRAN 77 (g77), prolog (gprolog), java (gcj-javac), and C++ (g++) as well as others. Most of these compilers share common features, and so much of the information about compilation will apply to these other compilers. A complete set of command line options for these compilers can be found from the appropriate UNIX manual pages (e.g. man gcc), additionally there is extensive documentation available on the web (try www.gnu.org for a full online manual for all of the available tools). This chapter will provide an introduction to the basic ways of using gcc, but will not attempt to provide comprehensive coverage, so refer to the online materials given above for further information if required.

1.1.2 Basic Compilation


Take a simple C++ program, such as the following. /* Hello.c */ #include <stdio.h> int main(){ printf(Hello World\n); return 0; } To compile this program using the gcc compiler, type the following command at the Unix prompt. gcc hello.c This will produce an executable file called a.out. All files compiled by the gcc compiler will produce a file with this name, so if you write more than one program this way remember to change the name of the output file using the UNIX command mv. This is not a particularly useful way of generating executable files, as confusion is likely to ensue if all executables have the same name. In order to create executable files with a more meaningful name, the -o tag is required by the compiler. The -o tag specifes the output file. gcc -o hello hello.c /*creates an executable called hello */ gcc -o myprog myprog.c /* creates an executable called myprog */

1.1.3 Separate Compilation


Invoking the gcc program starts of two processes: compiling and Linking. The compilation process converts programs into executable code, the linking process attaches functions from the appropriate libraries in order to create the final executable file. In the hello world" example above, the stdio.h library is used, and so when gcc is invoked, hello.c is converted into executable code, and then linked to the code for the printf function in stdio.h. The C and C++ programming languages use libraries of precompiled functions, and if you wish you can write your own. Library files do not normally have a main() function, and will return an error if compiled in the manner described above, because the linker expects to find a main function somewhere in all of the files it tries to link together. In order to avoid this problem the -c tag is used. This means compile only" and stops gcc invoking the linker. By convention all compiled, unlinked files have the suffix .o. Supposing we have a library called mylib.c, which contains a list of useful functions, but no main(). We store the function prototypes in a header file(mylib.h). We can compile it for use as follows. gcc -c -o mylib.o mylib.c Then if we wanted to use functions from this library, we include the header in the program as follows. /* my new program */ #include mylib.h int main(){ ... } Then we compile it separately using the -c ag as follows. gcc -c -o mynewprog.o mynewprog.c Then to produce the executable we run gcc on the object files. gcc -o mynewprog mynewprog.o myfunc.o mynewprog will now be the new executable. This process of separate compilation may appear fussy and difficult for small programs, but it does however afford a number of advantages when projects start to grow to any significant size and when used in combination with Makefiles (discussed in the next chapter), this can improve productivity.

Section 2: Make and Makefiles 1.2.1 Introduction


The previous chapter attempted to deal with some of the basic issues of compilation from the command line using gcc. This chapter is concerned with the management of potentially complicated programming projects, and discusses a means of managing compilation under UNIX. As with command line compilation, this is another of the mechanisms used by windows-based development environments such as JBuilder or Visual Studio, but again concealed from the user. Again Makefiles are used in VR programming to allow us to keep control of the compilation process.

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.

1.2.3 Using C Libraries


As you may be aware the C programming language has only a small number of reserved words, with the bulk of its functionality being provided by library functions. Associated with each library function is a header (.h) file, and a library file. On most systems there are static and dynamic libraries, and in the case of UNIX most static libraries take the form libXXX.a where the XXX is replaced by the library's name. So for example the library of C mathematical functions is given by libm.a. Dynamic libraries take a similar form, but have the suffix .so associated with them. Many of the commonly used libraries are bundled together into libc.a (eg stdio.h, stdlib.h, etc. Libraries are collections of functions bundled together in such a way that the code corresponding to a particular function can be extracted and linked to a program during compilation. In the case of many of the less commonly used functions certain compiler tags are required. In order to illustrate the point, type in the following program and compile it.
/* test.c */ #include <stdio.h> #include <math.h> int main(){ float f ; printf(``Enter a number: ``); scanf(``%f'',&f); printf(``Its square root is %.2f\n'',(sqrt(f)); return 0; }

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)

1.2.3.1 More about #include


At the top of most C programs is a compiler directive #include which is used to tell the compiler to include the header (.h) fileassociated with a set of library functions. You are probably aware that if you write part of a C program in a separate file, if you type #include myfunctions.h'' Using inverted commas, then the compiler will look in the directory in which it was called in order to find myfunctions.h. By using -I tags to tell the compiler where to find header files then one can use the angle braces <> to identify the file, as follows. #include <myfunctions.h> Although it is not essential for this course that you write your own libraries, you may find it useful to do so, and information on how to do this is given in Appendix A of the complete tutorial notes accessible from Blackboard

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

Potrebbero piacerti anche