|
|
Now let's look at how this process works
for a C language program to print the words hello, world
.
Here is the source code for the program, which
we have written in the file hello.c:
#include <stdio.h> main() { printf("hello, world\n"); }As indicated in ``Using programming tools'', the UNIX operating system command to create an executable program from C language source files is cc:
$ cc hello.c
The source files
to be compiled must have names that end in
the suffix .c.
Because there aren't any syntactic or semantic errors in the source code, the above command will create an executable program in the file a.out in the current directory:
$ ls -1
a.out
hello.c
Note that a .o file is not created
when you compile a single source file.
Execute the program by entering its name after the system prompt:
$a.out
hello, world
Because the name a.out is only of temporary usefulness,
we'll rename the executable to hello:
$ mv a.out hello
You can also give the program the name hello when
you compile
it, with the -o option to the cc command:
$ cc -o hello hello.c
In either case, execute the program by entering its name after the
system prompt:
$ hello
hello, world
Now let's look at how the cc command controls the four-step process described in the previous section. When you specify the -P option to cc, only the preprocessor component of the compiler is invoked:
$ cc -P hello.c
The preprocessor's output -- the source code
plus the preprocessed
contents of stdio.h -- is left in the file hello.i
in our current directory:
$ ls -1
hello.c
hello.i
That output could be useful if, for example, you received a compiler
error message for the undefined symbol ``a''
in the following fragment of source code:
if (i > 4) { /* declaration follows int a; /* end of declaration */ a = 4; }The unterminated comment on the third line will cause the compiler to treat the declaration that follows it as part of a comment. Because the preprocessor removes comments, its output:
if (i > 4) {will clearly show the effect of the unterminated comment on the declaration. You can also use the preprocessed output to examine the results of conditional compilation and macro expansion.a = 4; }
If you specify the -S option to the cc command, only the preprocessor and compiler phases are invoked:
$ cc -S hello.c
The output -- the assembly language code
for the compiled source -- is
left in the file hello.s in our current directory.
That output could be useful if you were writing
an assembly language routine and wanted to see how the compiler
went about a similar task.
If, finally, you specify the -c option to cc, all the components but the link editor are invoked:
$ cc -c hello.c
The output -- the assembled object code for the program --
is left in the object file hello.o in the current directory.
You would typically want this output when using
make(CP).
See
``make''
for further information regarding make.
Enter the command:
$ cc hello.o
to create the executable object file a.out. By default, the link editor ld(CP) arranges for the standard C library function that was called in your program -- printf -- to be linked with the executable at link editing time. In the default arrangement described here, the standard C library is an archive library.
The outputs described above are, of course, inputs to the components of the compilation system. They are not the only inputs, however. The link editor, for example, supplies code that runs just before and just after your program to do startup and cleanup tasks. This code is automatically linked with your program only when the link editor is invoked through cc. Therefore, cc hello.o was specified in the previous example rather than ld hello.o. For similar reasons, you should invoke the assembler through cc(CP) rather than as(CP):
$ cc hello.s
The compilation process is largely
identical if your program is in multiple source files.
The only difference is that the
default cc
command line creates
object files, as well
as the executable object file a.out, in your current directory:
$ cc file1.c file2.c file3.c
$ ls -1
a.out
file1.c
file1.o
file2.c
file2.o
file3.c
file3.o
If one of your source files fails to compile,
you need not recompile the others.
If you receive a compiler error diagnostic
for file1.c in the above command line,
your current directory looks like this:
$ ls -1
file1.c
file2.c
file2.o
file3.c
file3.o
Compilation proceeds but linking is suppressed.
Assuming you have fixed the error, the following command:
$ cc file1.c file2.o file3.o
creates the object file file1.o
and links it with file2.o and file3.o
to
produce the executable program a.out.
As the example suggests, C source
files are compiled
separately and independently.
To create an executable program, the link editor
ld(CP)
must connect the definition of a symbol in one source file
with external references to it in another.
Note that not all the cc command line options discussed are compiler options. The -o option is actually an ld option that is accepted by the cc command and passed to the link editor which creates the executable program. See the cc(CP) and ld(CP) manual pages for more information.