Classwork 9: Libraries (optional)

Objectives

To practice placing your functions in your own library.

The Assignment

So, you want to make your own library. Here's how it's done.

Step 1


The first step is to create some functions. However, unlike previous assignments, you will place your functions in separate files. Write three simple functions named add1, add2 and add3. Each function should be placed in its own file. Let's call these files add1.c, add2.c and add3.c just to make instructions simpler. There should be nothing else in these files (in particular, no main() function).

Each of these functions should take one int parameter and return an int value. The function add1() should return the value of its parameter plus 1, add2() should add 2, ...

You can compile each file separately:

gcc -Wall -c add1.c
gcc -Wall -c add2.c
gcc -Wall -c add3.c

Notice that you did not create an a.out file with these gcc commands. This is good, because you don't have a main program. Instead you created 3 files: add1.o, add2.o and add3.o. These files contain the object code compiled from your files.

Use the ls command to check that you did indeed create these .o files.

Step 2


The next step is to create a main program that uses the add1, add2 and add3 functions. (Henceforth, let's call these the add? functions.) Create a file called main1.c and write a main program that gets an integer from the user and prints out the number plus 1, 2 and 3 by calling the add? functions. A sample run of the program might look something like:

linux1% ./a.out
t = ? 25
t = 25
t + 1 = 26
t + 2 = 27
t + 3 = 28
linux1% 

Your main1.c program must not have the definitions of the add? functions. However, it must have function prototypes of these functions. When you are done coding the main() function, compile it using the -c option:

gcc -Wall -c main1.c

Use the ls command to check that you once again did not create an a.out file. Instead, there should be a file called main1.o. This is the object code for your main program.

Now you can combine all your object code together and create an executable program:

gcc -Wall main1.o add1.o add2.o add3.o

This last gcc command should have created an a.out file that you can run. Run your program a few times to make sure that it is working correctly.

Note: you can better appreciate the advantage of compiling your program separately if you suspend your disbelief briefly and pretend that the add? functions are really complicated pieces of code that take several minutes to compile. If you make changes to your main program, then you would only have to recompile main1.c. It is much faster for gcc to take the .o files and turn them into a.out, since it does not have to work with the source code. (This is the linking/loading phase of compiling.) So, instead of spending several minutes recompiling the entire program, you can take just several seconds to recompile main1.c.

Step 3


First, delete the a.out file you created in Step 2. This is to ensure that any a.out file that appear from now on is actually created in this step.

Assuming that your separate compilation in Step 2 worked correctly, now you can put your add? functions in a library:

ar -r libmine.a add1.o add2.o add3.o

This should create a library called libmine.a. Use ls to verify this. You can also check that your object files have been added to the library:

linux1% ar -t libmine.a
add1.o
add2.o
add3.o
linux1% 

Now you can link your main1.o object code to the library with:

gcc -Wall main1.o -L. -lmine

The -lmine flag tells the linking loader that there's a library named libmine.a that holds some of the functions you are using in the main program. The -L. tells the compiler that the library is in the current directory.

You should get an a.out that works exactly as before. Run it a few times to make sure that it works.

Note: You did not have to use the -L flag previously because gcc knows where the standard libraries are located. Also, you did not need to use the -l flag when you used functions like printf() from the standard library, because gcc automatically checks the standard library. However, you did need to use the -lm flag to use functions in the math library.

Step 4


Once again, delete the a.out file, if you have one.

If you used the add? functions a lot, then typing in their function prototypes might get tedious. This problem is remedied through the use of header files.

Make a copy of your main1.c and call it main2.c. In main2.c remove all of the add? function prototypes. Now, edit a new file called add.h and place the three add? function prototypes in this header file. Finally, edit main2.c and add the following line near the top:

#include "add.h"

Now, you are ready to compile your second main program:

gcc -Wall main2.c -L. -lmine

This should create an executable program called a.out. Run the program, it should behave the same way as before.

Note: header files like add.h usually have lines like these at the top:

#ifndef __ADD_H_
#define __ADD_H_

and, near the bottom,

#endif

These lines are called "guards" and keep a header file from being included more than once.

Step 5


Use the script command to record yourself compiling and running the second version of your program. Finally, submit the second version of your program using:

submit cs104_chang cw09 main2.c
submit cs104_chang cw09 add1.c
submit cs104_chang cw09 add2.c
submit cs104_chang cw09 add3.c
submit cs104_chang cw09 add.h
submit cs104_chang cw09 libmine.a
submit cs104_chang cw09 typescript


Be sure to logout completely when you have finished!