C Compiler Basics (GCC)

Main Page
Helpful Links
Downloads
Tutorials
Grades
Syllabus
Contact Me
This tutorial covers the basics you need to know about using the GNU C Compiler Collection.  There are many, many more options than what I cover here (just enter man gcc and see what I mean), but this covers everything you should need to know, for now.


The Compilation Process

   All programs start as text files of human readable instructions.  But a computer can't understand these.  They don't make any sense to it.  The job of the compiler is to take these files and compile them into machine code.  Sensible text like "print(sum)" becomes gibberish like 11001001.  The machine code a compiler creates is placed into an object file.
   It's still not ready yet, though.  The next phase is linking.  The object file by itself is incomplete.  It still needs to be joined with other libraries and object files.  This is done by the linker.  The end result is an executable file.  Fortunately, by default, GCC pretends like it's just one phase.


Using GCC

   For the sake of demonstration, let's use a file, hello1.c.  Here's a listing of it:

#include<stdio.h>

int main()
{
     printf("Hello World\n");
     return 0;
}

   This program simply prints "Hello World" to the screen, along with a newline character, and exits.
Interestingly, almost all languages have tutorials that start with this exercise, and it's almost always Hello World.  I don't know why.

   But how would we compile it?  This is where GCC comes in.  We can simply enter this command:

gcc hello1.c

   This gives us an executable file.  Unfortunately, it calls it a.out.  This is the default executable name for GCC.  We can use the -o flag to specify a more meaningful one.

gcc -o hello hello1.c

   This gives us an executable file named hello.  Now, let's run it.  You would think just typing hello would do it right?  Well, you would be wrong.  For security reasons, most UNIX systems don't list your current directory on the $PATH variable that says where to look for executable files.  This is so someone can't plant bogus commands in your system and trick you into running the fake.
  
   This simply means we have to specify the command like this:

./hello

   The . is actually UNIX shorthand for "current directory", in the same way .. is for "parent directory".  So, what we're saying here is that we specifically want to run the program called hello, in the currect directory.

   So unsurprisingly, it gives us the output "Hello World".  So, let's move on to a slightly trickier example.  This is the listing for hello2.c:

#include<stdio.h>
#include<math.h>   /* Include the standard math library */


int main()
{
   int x = 25;
   /* Use a math library function. */
   int squareRoot = (int)sqrt(x);
   printf("%d is the square root of %d.\n", squareRoot, x);
   return 0;
}


Let's try to compile it like this:

gcc -o hello hello2.c

Here's what I get back:

avisvan> gcc -o hello hello2.c
/tmp/cc4k5Enn.o: In function `main':hello2.c:(.text+0x44): undefined reference to `sqrt'
collect2: ld returned 1 exit status



   This seems intimidating, but let's take it apart.  It's complaining that in our main function in hello2.c, we made an undefined reference to "sqrt".  It's viewing this in 
/tmp/cc4k5Enn.o which is actually the object file hello2.c was compiled into.  ld (the linker) returned an exit status of 1, indicating failure.   So this is what's called a linker error.  Compilation was already successful, but it can't link because it doesn't have a clue where "sqrt" is coming from.
   What we need to do is tell gcc where the "sqrt" function comes from.  We need to tell it to use the math library when linking. 
We do this using the -l (library) flag.

gcc -lm -o hello hello2.c

     The m is actually short for math.  The way the -l flag works is you follow it with the name of the library, without any extension.  For example, if you wanted to use a library named super.a  you would use -lsuper.
On my machine, the math library is /usr/lib/libm.a, so I use -lm.  Of course, this only works because gcc knows what directories to search for libraries.  If you wanted to use some extra, custom library, you would need to tell it where to look.
     When we run the output file, hello , we get "5 is the square root of 25."


For a more in depth tretise on the compilation process, try this link
GCC  - the root of all

Here is the official page for GCC, including its documentation:
GCC, the GNU Compiler Collection