Este apartado es suficiente para dominar el uso básico del
compilador de lenguaje C, a través del programa cc
.
Para comprender este texto no tienen por qué estar familiarizados con el
C, aunque se precisan unas mínimas nociones de este lenguaje.
Además, deberían conocer conceptos básicos relacionados
con el desarrollo de programas, como programa fuente, objeto, enlace
(linking), etc.
Para compilar programas escritos en C, disponen de un compilador de
nombre cc
. Este compilador toma como parámetros los
ficheros fuentes de que consta el programa final y, tras una serie de pasos,
produce un fichero ejecutable. Si durante la compilación se produce un
error, no se genera el ejecutable.
Los pasos de compilación en UNIX son al menos estos tres:
* Preproceso (macros, inclusión de ficheros...)
* Compilación a objeto
* Enlace (linking) de objetos y bibliotecas
El preproceso interpreta las macros creadas con #define
y
expande los ficheros para incluir con #include
. No es de
mucho interés para ustedes.
Un fichero una vez preprocesado se compila a código máquina,
pero no se genera un ejecutable, sino un fichero objeto. Este estadio
intermedio es necesario por muchos motivos, entre ellos que las rutinas de
biblioteca, como printf
, tienen que ser "empotradas"
posteriormente para generar un ejecutable, y en general debido a que un
programa en C puede constar de varios ficheros compilados por separado.
Por eso existe un último paso, denominado enlace (linking en inglés), en el cual se recogen todos los ficheros objetos más las bibliotecas (que también residen en ficheros) necesarios para producir el fichero ejecutable.
Como se ha visto, en el transcurso de la ejecución del
cc
aparecen en escena varias clases de ficheros: fuentes, objetos,
bibliotecas, ejecutables... El compilador de C es capaz de distinguir la clase
de un fichero en base a sus últimos caracteres. La siguiente tabla
muestra las convenciones más habituales.
.c |
fichero
fuente en C
|
.h |
fichero
cabecera fuente en C (sólo útil para los
#include )
|
.s |
fichero
fuente en ensamblador (también reconocido)
|
.i |
fichero
fuente tras ser preprocesado (raramente empleado por el usuario)
|
.o |
fichero
objeto
|
.a |
fichero
de biblioteca
|
a.out
, aunque se le puede indicar que tenga otro nombre con la
opción -o
nombre_de_ejecutable.
El programa cc
se invoca desde el shell,
admitiendo como argumentos los ficheros empleados para construir el ejecutable
más una serie de opciones de compilación. Las opciones y
modalidades de uso del cc
son amplísimas, por lo que
en esta guía nos limitaremos a exponer las más comunes y
útiles.
Por omisión, el cc
genera un ejecutable llamado
a.out
. En la línea de órdenes pueden incluir
tanto ficheros fuentes en C como ficheros objeto, incluso fuentes en
ensamblador[1]. Los nombres de los ficheros
pueden aparecer en cualquier orden.
En el siguiente apartado aparece un resumen de opciones; antes de ello daremos algunos ejemplos.
Ejemplo 1:
cc pepe.c
Si pepe.c
es un fichero fuente en C, se compila y se enlaza
con las bibliotecas del sistema. Si no había errores sintácticos
ni referencias a funciones o variables inexistentes, se genera el ejecutable
a.out
.
Ejemplo 2:
cc -o pepe main.c utilidades.c pepe.o -lm
Éste es un ejemplo más complejo donde anticipamos el uso de un
par de opciones de compilación. La opción -o
pepe
sirve para que, en lugar de generar el fichero
ejecutable pepe
, en lugar de a.out
.
Para construir el ejecutable se hace uso explícito de cuatro
elementos:
* Un fuente main.c
(quizás con el programa
principal)
* Otro fuente, utilidades.c
(quizás con funciones
adicionales)
* Un objeto pepe.o
(tal vez con otras utilidades ya
compiladas)
* La biblioteca matemática estándar (con la
opción -lm
)
Con este ejemplo hacemos ver que un programa en C puede estar compuesto de
varios módulos en forma de ficheros fuentes. Y que si un módulo
ya está compilado, podemos pasar como argumento al compilador el
correspondiente .o
para ahorrar tiempo.
Como ya se dijo, existe una infinidad de opciones para controlar la
ejecución del cc
. Algunas de las opciones más
necesarias o comprensibles para ustedes son las siguientes:
|
compila
en C ANSI
|
-Ac
|
compila
en C de K&R
|
-c
|
sólo
compila, no hace el montaje
|
-I directorio
|
define
directorios para buscar los #includes
|
-l lib
|
monta
la biblioteca lib
|
-L directorio
|
define
directorios para buscar las bibliotecas
|
-o
fichero
|
establece
el nombre del ejecutable
|
-O
|
optimiza
el código
|
-O n
|
optimiza
el código hasta el nivel n
|
-S
|
genera
un fuente .s en ensamblador; no compila
|
-v
|
modo
locuaz: imprime todos los pasos
|
Las opciones del compilador de C pueden variar según la versión de UNIX que se utilice.
Laboratorio de operativos: El compilador de C está preparado para compilar en modo ANSI, con lo que no hace falta que escriban la opción -Aa.
Algunas bibliotecas útiles, para la opción
-l
lib, son:
|
biblioteca
estándar del C. No hace falta incluirla explícitamente
|
m
|
biblioteca
estándar matemática
|
termcap
|
contiene
rutinas de manejo de terminales
|
curses
|
contiene
rutinas de visualización con ventanas, etc.
|
l
|
biblioteca
para uso del lex y el yacc
|
Es muy probable que en la máquina en la que trabajen exista un compilador de C++. Describiremos brevemente las características de uno de los compiladores de C++ más difundidos, el de la casa GNU (software de distribución gratuita).
El compilador de la GNU se llama gcc
, aunque se le puede
invocar como gcc
o c++
. Es capaz de
reconocer tanto fuentes en C como en C++. El gcc
reconoce
como fuentes en C++ a los ficheros con extensión
.cxx
o .C
(letra "C" mayúscula).
Las opciones admitidas por el gcc
son más o menos
las mismas que acepta el compilador convencional de UNIX; aunque siempre es
recomendable consultar el manual en línea.
[ ] 1 De hecho el paso de compilación a objeto suele atravesar una fase intermedia en que se genera un fichero en lenguaje ensamblador y se invoca al programa ensamblador del sistema.