C/C++ en GCC para GNU/Linux

Esta serie de entradas están dirigidas especialmente a aquellos amigos de uControl que usan GNU/Linux, aunque el excelente compilador gcc  puede ser utilizado también en las diferentes versiones de MS Windows. Los usuarios de Ubuntu, por ejemplo, lo tienen fácil ya que este compilador está incluido en el sistema operativo. Por supuesto, los conceptos que desarrollemos en esta serie de entradas no están ligadas a ninguna distribución de GNU/Linux en particular, ya que funciona igual en todas las distribuciones. Las capturas de pantalla y pruebas que veamos estarán hechas, al menos por ahora, en un ordenador que corre Ubuntu 13.04 con Gnome.

Tampoco vamos a escribir un manual de programación en si, ni un manual de C/C++, sino que intentaremos crear una guía de uso del GCC, y ver muchos ejemplos de programación como para poder dar nuestros primeros pasos con este lenguaje/compilador. Dicho todo esto, y para empezar, debemos asegurarnos que tenemos instalado el paquete gcc. Para comprobarlo basta con abrir una sesión de la terminal que utilicemos, escribir “gcc” y presionar la tecla Enter. Si el paquete está instalado obtendremos algo como esto:

gcc01

Si no lo tenemos instalado, podemos escribir en la misma consola
sudo apt-get install build-essential gcc
Introducimos nuestro password, y comenzará la descarga de paquetes necesarios y se efectuará la instalación. Si intentas instalarlo sin darte cuenta que ya lo tenias en el sistema no pasará nada, solo obtendrás un aviso como este:

gcc002

También necesitarás un editor de texto. Yo uso gedit, pero cualquier vale. Si quieres usar gedit, lo puedes instalar con
sudo apt-get install gedit
Con esas dos herramientas podemos escribir y compilar aplicaciones en C. Ya podemos empezar a escribir el código del programa que vayamos a crear. Suponemos que ya has hecho algún programa simple en C y que conoces su sintaxis, por lo que nos vamos a saltear el clásico “Hola Mundo” y vamos a escribir algo más complejo. Por ejemplo, un programa que liste los números enteros comprendidos entre un límite inferior y un límite superior.
Abrimos gedit y escribimos lo siguiente:
Nos quedará algo así:
gcc003

Lo guardamos en la carpeta que usaremos para nuestras pruebas como “programa01.c”, y nos situamos en ella para compilar el programa. Para compilarlo, utilizaremos el comando
gcc -o programa01 programa01.c
gcc es el comando que invoca al compilador, -o indica que a continuación viene el nombre que queremos tenga el programa ejecutable que el compilador creará, y programa01.c es el archivo que contiene el código fuente que queremos compilar.
El resultado no será muy espectacular:

gcc004

Si usamos el comando ls para listar el contenido de la carpeta veremos que se ha creado el archivo programa01 (en verde en nuestro caso):

gcc05

Para ejecutar el programa basta con escribir
./programa01
y presionar Enter. Aparecerá algo así:

gcc006

Ponemos el limite inferior, presionamos Enter, ponemos el limite superior, presionamos Enter, y veremos algo así:

gcc007

Yo puse como limite inferior 10 y como límite superior 55. Obviamente, con otros valores otro será el resultado. Puedes jugar un rato con programa01 y ver que pasa si el limite inferior es mayor que el superior o diferentes valores.

Luego puedes hacer algún cambio en el programa, guardarlo e intentar compilarlo. Cuanto más practiques, más fácil te resultará el aprendizaje.

Continuemos viendo las opciones y posibilidades del compilador gcc. Recuerda que hay una entrada anterior que puedes ver siguiendo este link. Vimos como hacer para compilar un sencillo programa y como el compilador mostraba una aburrida salida por la terminal luego de hacer su trabajo. Sin embargo, puede ocurrir (con frecuencia) que nuestro código fuente tenga algún error de sintaxis y que el compilador no pueda realizar su tarea.

Por ejemplo, si modificamos el ejemplo que vimos en la entrega anterior de forma que el “int” se convierta en un “nt” y lo guardamos como “programa02.c” veremos al intentar compilarlo que gcc nos advierte del error. Modifiquemos entonces el programa para que nos quede así:

gcc008

Si intentamos compilarlo escribiendo en la terminal el comando
gcc -o programa02 programa02.c
veremos que la pantalla muestra algo como esto:

gcc009

gcc nos está indicando que nuestro código fuente, en la tercer columna de la linea cinco (eso significa el 5:3: que se ve en el tercer renglón de la captura de pantalla anterior) hay un “nt” que no puede reconocer. Este tipo de mensaje, a pesar de lo escueto que pueda parecer, siempre proporciona pistas que nos permitirá encontrar y corregir el error.
Algo que no mencionamos es que puede ocurrir si intentamos compilar un archivo fuente sin incluir la opcion “-o” y el nombre del archivo de salida. En esos casos, gcc compila el programa pero no genera el ejecutable de salida. Si hacemos, por ejemplo
gcc programa01.c
Obtendremos una salida igual que la vista en la entrega anterior, pero no tendremos el ejecutable correspondiente:

gcc004

En proyectos extensos, el compilar sin generar el ejecutable puede ser algo más rápido, y aún podremos ver -en caso de que los haya- los errores de sintaxis que hemos cometido. Una vez que hemos depurado nuestro código podemos compilar nuevamente y esta vez si generar el archivo ejecutable correspondiente.

Hay que tener en cuenta que si bien gcc compilará y generará archivos con cualquier tipo de extensión (siempre que la indiquemos en la linea de comando (por ejemplo gcc programa.algo), es conveniente respetar ciertas convenciones. Las siguientes son las recomendadas:

.c fuente en C
.C .cc .cpp .c++ .cp .cxx  fuente en C++; se recomienda .cpp
.m fuente en Objective-C
.i C preprocesado
.ii C++ preprocesdo
.s fuente en lenguaje ensamblador
.o código objeto
.h archivo para preprocesador (encabezados), no suele figurar en la linea de comando de gcc

Además, existen varias opciones ademas de “-o”. Las siguientes son las más comunes:
- c : realiza el preprocesamiento y la compilación, obteniendo el archivo en código objeto; pero no realiza el enlazado.
- E : realiza solamente el preprocesamiento, enviando el resultado a la salida estándar.

gcc011

-o archivo : indica el nombre del archivo de salida, cualesquiera sean las etapas cumplidas.
-Iruta : especifica la ruta del directorio donde se encuentran los archivos marcados para incluir en el programa fuente. Importante: no lleva espacio entre la I y la ruta, debe escribirse todo “pegado”, como en   -I/usr/include

-L : especifica la ruta hacia el directorio donde se encuentran los archivos de biblioteca con el código objeto de las funciones referenciadas en el programa fuente. Al igual que en la opción anterior no lleva espacio entre la L y la ruta, como en  -L/usr/lib
-Wall : muestra todos los mensajes de error y advertencia del compilador:

gcc010

-g : incluye en el ejecutable generado la información necesaria para poder rastrear los errores usando un depurador, tal como GDB (GNU Debugger).

-v : muestra los comandos ejecutados en cada etapa de compilación y la versión del compilador. Es un informe muy detallado y útil.

gcc012

No temas en experimentar con estas opciones, y juega un poco con ellas hasta familiarizarte con cada una.