Compiling, make & lint |
Note: You need to know all of this material for exams.
#include <stdio.h> int main() { printf("Hello World!\n"); }
% cc -o executablename sourcename.c % gcc -o executablename sourcename.c
Usually executablename and sourcename are the same. Thus if the above program were in a file called myhello.c,
% gcc -o myhello myhello.c
would create a file called myhello. You could run the program just by invoking its name:
% myhello Hello World!
In case your C program uses a mathematical function, then on many systems you will need the additional -lm option to force the math library to be included in the compilation.
% gcc -o myFile myFile.c -lm
% lint sourcefilename.c
On the Sun systems, you should use the lint option: -Xarch=v9. The following shows the command and the output:
% lint -Xarch=v9 myhello.c (5) warning: Function has no return statement : main function falls off bottom without returning value (5) main function returns value which is always ignored printf
I've been trying the following options: -err=warn -Ncheck=%all -Nlevel=4 -Xarch=v9
Comments about the lint output:
#include <stdio.h> int main() { printf("Hello World!\n"); return 0; }
We can run lint on this:
% lint -Xarch=v9 myhello.c function returns value which is always ignored printf
When you execute make, it looks for a file called Makefile in the current directory. This Makefile describes the dependency relationships that exist between various program modules.
The dependencies have the following form:
target: components TAB rule
The first line is called a dependency and the second line is called a rule. Rule lines must start with a tab character. There may be more than one rule line for each dependency.
The rules are invoked if any of the components are newer than the target, or if the target does not exist. Here is a simple Makefile for myhello (the second line starts with a TAB):
myhello: myhello.c gcc -o myhello myhello.c
If myhello does not exist, then running make will compile myhello.c:
% make gcc -o myhello myhello.c %
If we do it again:
% make `myhello' is up to date. %
By default, make will look only at the first target in the makefile. If you give it an argument, it will look at the corresponding target.
Consider the following makefile:
myhello: myhello.c gcc -o myhello myhello.c lint: lint -Xarch=v9 myhello.c
Now typing make will do the same thing as before, but typing make lint will cause the rule for lint to be used. Since the file lint does not exist, the rule will always be executed:
% rm myhello % make gcc -o myhello myhello.c % make lint lint -Xarch=v9 myhello.c function returns value which is always ignored printf % make `myhello' is up to date. %
Sometimes you want to remove the executable and start again. Here is another useful Makefile. (Remember that each of the "rule" lines must start with a TAB.)
myhello: myhello.c gcc -o myhello myhello.c lint: lint -Xarch=v9 myhello.c clean: rm myhello
Now we can run make some more:
% ls -la total 8 drwxr-xr-x 2 mmaltrud staff 512 Aug 30 15:38 . drwxr-xr-x 4 mmaltrud staff 512 Aug 30 15:25 .. -rw-r--r-- 1 mmaltrud staff 89 Aug 30 15:36 makefile -rw-r--r-- 1 mmaltrud staff 76 Aug 30 15:25 myhello.c % make gcc -o myhello myhello.c % make `myhello' is up to date. % ls -la total 22 drwxr-xr-x 2 mmaltrud staff 512 Aug 30 15:38 . drwxr-xr-x 4 mmaltrud staff 512 Aug 30 15:25 .. -rw-r--r-- 1 mmaltrud staff 89 Aug 30 15:36 makefile -rwxr-xr-x 1 mmaltrud staff 6212 Aug 30 15:38 myhello -rw-r--r-- 1 mmaltrud staff 76 Aug 30 15:25 myhello.c % make clean rm myhello % ls -la total 8 drwxr-xr-x 2 mmaltrud staff 512 Aug 30 15:38 . drwxr-xr-x 4 mmaltrud staff 512 Aug 30 15:25 .. -rw-r--r-- 1 mmaltrud staff 89 Aug 30 15:36 makefile -rw-r--r-- 1 mmaltrud staff 76 Aug 30 15:25 myhello.c % make gcc -o myhello myhello.c %
make does more for you than might be obvious from the simple presentation above. It keeps track of the time each component has been altered. Then if it is properly set up, make will decide whether or not a C source file needs to be recompiled, based on information in a database about whether the source file has been modified since the last compile. Functionality such as this is also provided by modern IDEs (Interactive Development Environments) for languages (like JBuilder for Java or Visual Studio), but the much older make has been used very successfully for 30 years and is still in wide use by the Unix community.
The make utility also keeps a programmer from making mistakes. For example, beginning programmers (and others) who type the compile command directly might make the mistake:
% gcc -o myhello.c myhello.c %
In this case the compiled file will overwrite the original source, so that the source will be lost (unless you have another copy). A properly and carefully written Makefile will keep you from making this and other errors.