Monday 10 April 2006

Steps to compile C / C++ programs using GNU compiler

Till a few years back, it was really difficult to obtain a free version of a compiler to run on ones machine to learn C or C++. And one had to resort to using a commercial compiler either by paying money and buying a licence or using a pirated copy of the same. I still remember, till a couple of years back, Borland C was considered to be the best compiler in the market for windows platform but later Microsoft's Visual-C usurped it to take the most popular position. Then GNU/Linux got wider acceptance and the rest as they say is history. Most GNU/Linux distributions ship with the gcc suite of compilers. GCC stands for GNU Compiler Collection. And it contains compilers for various languages such as C,C++,Java and so on. It is one of the most efficient free implementation of a compiler one can hope to get ones hands on and is available for multiple platforms and OSes including Windows.

Here I will list the basic steps needed to compile a C / C++ program using GCC. The first thing to do is find what version of gcc is installed on ones computer. This is achieved using the -v switch.
$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.0 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-awt=gtk-default --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.0-1.4.2.0/jre --enable-mpfr --disable-werror --with-tune=pentium4 --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.0.3 (Ubuntu 4.0.3-1ubuntu4)
This is important because depending upon the version of the GNU compiler, one can decide to use or ignore certain deprecated features.

In fact, viewing the man page of the compiler gcc, one realises that it has over a hundred different options for multiple architectures.

Lets say, I have a tiny C program as follows which I have written in a file called test.c .
/* FILE: test.c */
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv){
printf("Hello world\n");
system("cat test.c");
printf("\nEnd of program\n");
return 0;
}
Now once I have written the program, I have to compile it. Compilation is the process of converting human readable code into a form which the machine can understand. So to compile the above program, I give the command as follows:
$ gcc test.c
And if there are no syntax errors, the program will be successfully compiled and the compiler will create an executable file called a.out. Now to run our program, we have to execute a.out executable file.
$ ./a.out
As you can see I have used a ./ in front of a.out file. This is necessary if your current directory is not included in the PATH environment variable.

But if you want the compiler to give a different name to the executable file it generates, then you use the -o switch:
$ gcc -o test test.c
This will create an executable file by name 'test' instead of a.out .

But sometimes it is necessary to get an assembly code listing of ones program. This is desirable if we need to say, get an idea of the values stored in the registers. This is also possible in gcc using the '-S' switch.
$ gcc test.c -S -g
What it does is it creates a text file called test.s which contains the assembly code of our program. The -g flag is optionally used to produce debug symbols and line number information.

You can optimize the compiler using the -O flag followed immediately by a number (between 0 and 3) which states the level of optimization. It is good to optimize ones programs as it results in faster binaries.
$ gcc -O2 -o test test.c 
It is worth noting that one can turn off the optimization by using the -O0 switch.

For C++ programs, the gcc suite has another compiler by name g++. All the options which have been explained above works with the g++ compiler too.

Note: The steps detailed above are more useful for C/C++ developers and students interested in learning to program in C/C++ rather than users of Linux. This is because the compiling of source code is made simple in GNU/Linux by the use of the 'make' command.

No comments:

Post a Comment