Compiling

On many Unix platforms (and other), the C compiler has always been the command "cc", but the Gnu Free Software foundation has long provided a free, open-source C compiler known as "gcc", and that is the one that the Linux operating system uses. Even on Linux, you can type in "cc" and it will work, since there is a soft link (read your LUPT book to understand what this is) from the name "cc" to the binary executable named "gcc".

Different compilers on different operating systems will use different flags and have different options. The discussion below is specific to gcc, but the ideas are transportable to virtually all compilers.


Basic Compiling and Linking

If you have a single source code file, say "prog.c", and you just want to compile it, you can use

gcc prog.c
as the simplest possible compiling command. On most Unix platforms, if the program is syntactically correct and complete, this will produce in a binary executable file named "a.out". Yes, this is very strange, and it is a very old historical custom on Unix platforms, but that is what you have to live with. If you want the executable to be named something else, then use the "-o" option:
gcc prog.c -o prog
This will name the executable "prog". Note that on Unix platforms, it is customary for an executable to have no extension. On other platforms you might be used to seeing ".exe" or something like that, but on Unix (and thus Linux), an executable file should not have an extension.

The above commands actually do more than just compile. They also perform the step we call linking. The compile step really just takes the source code that you wrote and converts it to CPU instructions, which we call machine code or more usually object code. The compiler can do this for a whole program or for any partial piece of code (with at least complete functions). Object code by itself is not executable. On Unix platforms, object code files generally have a ".o" extension, while some other platforms might use ".obj". You can tell the C compiler to only do compilation by using the "-c" flag:

gcc -c prog.c
This will result in an object code file named "prog.o".

The linker is responsible for taking one or more object code files and linking them together to form an executable. Even if there is only one object code file, it still needs linked to libraries if it uses external functions (like printf(), for example). Even though you can use the Unix linker directly (it is the command "ld", and if you want more information, look at it's man page), normally we do not -- instead, we use the C compiler and let it invoke the linker for us.

We can make the C compiler do the linking step for us simply by giving it object code files instead of source code files:

gcc prog.o -o prog
The above command will only do linking, since the "prog.c" file was already compiled into the "prog.o" object code file. Gcc sees that it was given an object code file and so it skips the compile step and goes directly to the linker step. Note that you still need to tell it the output executable file name, or else it will generate "a.out" again!

The Complete Picture

Below is a diagram of the complete picture of what happens when you compile and link your program. The annotations on arrows in between steps are the gcc options that will stop the process at that step. (I.e., to stop after preprocessing, use "gcc -E", to stop after assembly code generation, use "gcc -S", etc.)

Compiling Options

There are many options that you can give compilers to change the way that your code is compiled, or to help you with developing your code. Here are a few popular "gcc" options (most compilers will have similar ones):