CS107 Compilación de programas en C con GCC

Escrito por Chris Gregg, con modificaciones de Nick Troccoli

Haga clic aquí para ver un video de demostración.

El compilador que usaremos para CS107 se llama «GNU Compiler Collection» (gcc). Es uno de los compiladores más utilizados, y es a la vez Software Libre, y está disponible en muchas plataformas informáticas diferentes.

gcc realiza el paso de compilación para construir un programa, y luego llama a otros programas para ensamblar el programa y para enlazar las partes componentes del programa en un programa ejecutable que se puede ejecutar. Aprenderemos un poco sobre cada uno de esos pasos durante el CS107, pero lo bueno es que gcc puede producir todo el programa ejecutable (ejecutable) para ti con un solo comando.

En el CS107, usaremos predominantemente Makefiles para compilar, ensamblar y enlazar nuestro código, pero el Makefile ejecuta gcc para hacer el trabajo. This is just a quick overview on how to compile and run your own programs should you decide to do so without a Makefile.

The simplest way to run gcc is to provide gcc a list of .c files:

$ gcc hello.c$

Note that you do not put header files (.h) into the gcc command: it reads in the header files as it compiles, based on the #include statements inside .c files.

If the program compiled without errors or warnings, you don’t get any output from gcc, and you will have a new file in your directory, called a.out. To run this file, you need to tell the shell to run the file in the current directory, by using ./ before the name:

$ ./a.outHello, World!$

Generalmente no queremos que nuestros programas se llamen a.out, así que puedes darle a gcc una opción, -o programName, para indicarle el nombre del archivo ejecutable:

$ gcc hello.c -o hello$ ./helloHello, World!$

Nota: ten cuidado de no introducir accidentalmente un nombre de archivo ejecutable que sea el mismo que tu archivo de entrada – algo como:

$ gcc hello.c -o hello.c

En myth, tu perfil ha sido configurado para detectar el error y no compilarlo, dejando tu archivo fuente intacto. Este no es el caso en muchos otros sistemas Linux, ¡así que tenga cuidado! En otros sistemas, GCC sobrescribiría su archivo fuente con el nuevo ejecutable.

gcc toma muchas opciones de línea de comandos diferentes (banderas) que cambian su comportamiento. Una de las banderas más comunes es la bandera de «nivel de optimización», -O (mayúscula ‘o’). gcc tiene la capacidad de optimizar su código para diversas situaciones.

  1. -O o -O1: Optimizar. Optimizar la compilación toma algo más de tiempo, y mucha más memoria para una función grande. Con -O, el compilador trata de reducir el tamaño del código y el tiempo de ejecución, sin realizar ninguna optimización que lleve mucho tiempo de compilación.
  2. -O2: Optimiza aún más. GCC realiza casi todas las optimizaciones soportadas que no implican un compromiso de espacio-velocidad. En comparación con -O, esta opción aumenta tanto el tiempo de compilación como el rendimiento del código generado.
  3. -O3: Optimiza aún más. -O3 activa todas las optimizaciones especificadas por -O2 y también activa otras optimizaciones. Esta suele ser la mejor opción a utilizar.
  4. -O0: reduce el tiempo de compilación y hace que la depuración produzca los resultados esperados. Esta es la opción por defecto.
  5. -Os: Optimiza el tamaño. -Os habilita todas las optimizaciones -O2 que no suelen aumentar el tamaño del código. También realiza otras optimizaciones diseñadas para reducir el tamaño del código.
  6. -Rápido: Prescinde del cumplimiento estricto de los estándares. -Ofast habilita todas las optimizaciones -O3. También habilita optimizaciones que no son válidas para todos los programas que cumplen con los estándares.
  7. -Og: Optimiza la experiencia de depuración. -Og habilita optimizaciones que no interfieren con la depuración. Debería ser el nivel de optimización elegido para el ciclo estándar de edición-compilación-depuración, ofreciendo un nivel razonable de optimización mientras se mantiene una compilación rápida y una buena experiencia de depuración. Utilizaremos -Og en CS107 cuando estemos depurando.
    1. Ver la página de man para gcc para más detalles sobre la optimización (o ver aquí para más información sobre optimizaciones).

      Otra bandera común es la opción -std=gnu99, que indica a gcc que utilice la «versión gnu c del estándar c de 1999». El estándar proporciona una sintaxis como la de poder definir una variable dentro de una declaración de bucle for (por ejemplo, for (int i = ...). Utilizaremos este estándar en el CS107.

      También utilizaremos la bandera -g, que nos permite utilizar el depurador, gdb, para que nos dé los números de línea exactos en nuestro código cuando lo ejecutemos.

      Ejemplo:

      $ gcc -std=gnu99 -g -Og loop.c -o loop 

      Si te interesa aún más información sobre gcc, echa un vistazo a la sección 1 de este documento de Stanford Unix Programming Tools, así como al manual completo de gcc(GNU).