In a number of previous C posts I have used more than one source code file, one for the main function and others for functions used by main. This is purely to make the source code easier to handle than would be the case if all the code were in one large source file.
In this project I will go beyond separating source code into different files by compiling the additional files into static libraries which can be copied to a central location along with their header files and used by many programs, in exactly the same way as the standard library is used.
Create a new folder somewhere convenient and within it create the following empty files. You can download the files as a zip or clone/download from Github if you prefer.
- main.c
- library.h
- library.c
Source Code Links
To concentrate on the central purpose of demonstrating how to create a static library I will keep the library's actual functionality trivial. It will contain one function which takes an int array as an argument and returns the total. Open library.h and enter or paste the following.
library.h
#include<stdlib.h> #include<stdbool.h> #include<stdio.h> #include<math.h> //-------------------------------------------------------- // FUNCTION PROTOTYPES //-------------------------------------------------------- int total(int* data, int size);
And now library.c.
library.c
//-------------------------------------------------------- // FUNCTION total //-------------------------------------------------------- int total(int* data, int size) { int t = 0; for(int i = 0; i < size; i++) { t+= data[i]; } return t; }
And finally main.c which simply creates an array of ints, calls the total function, and prints out the result.
main.c
#include<stdio.h> #include<stdlib.h> #include"library.h" //-------------------------------------------------------- // FUNCTION main //-------------------------------------------------------- int main(int argc, char* argv[]) { puts("------------------"); puts("| codedrome.com |"); puts("| Static Library |"); puts("------------------\n"); int data[] = {11,22,33,44,55,66,77,88,99}; int t = total(data, 9); printf("The total is %d\n", t); return EXIT_SUCCESS; }
We could now compile and run the code with this:
Don't bother running this!
gcc main.c library.c -std=c11 -o main ./main
but the purpose of this project is to compile library.c into a .o file: the first line of the following does this. The next lines compile and run the actual program.
Compile and run - do run this!
gcc -c library.c -std=c11 -o library.o gcc main.c library.o -std=c11 -o main ./main
The program output looks like this.
Program output
------------------ | codedrome.com | | Static Library | ------------------ The total is 495
It may seem that we have just introduced an intermediate stage of compiling library.c for no real purpose. However, you can copy the .h and .o files somewhere central for multiple use, or distribute them to other people to use in their projects.
Let's take a look at how to use .h and .o files stored in a common location in your projects.
Firstly you can copy the .h files to (on Linux) /usr/local/include, and the .o files to /usr/local/lib. (You will need root privileges to do this.) This is the easiest method as gcc will look in these locations by default so it's all you need to do. However, if you are actively developing the library you'll need to copy the file across every time you recompile them. To #include them use this syntax - note use of < and > as you would with standard library headers.
#including header files in /usr/local/include
#include<library.h>
Secondly, you may wish to have the .h and .o files in a different location, particularly if you are actively working on the library as it is being used by various projects. For example you might have the library source code, .h and .o files in /projectlibrary. To use them you can either type the full path like this - note use of quotes as with local header files:
#including header files in custom location
#include"/projectlibrary/library.h"
or add the location to the gcc command like this:Header file location in gcc command
gcc -I/projectlibrary
I would suggest that you use a combination of these options - start off with a custom location where you have your .h and .o files while you are working on them, and then save them to /usr/local/include and /usr/local/lib respectively for long-term use when they are finished.