Está en la página 1de 10

UNAN-León

Sistemas Operativos
Practica
Herramientas para el Desarrollo
de programas
Nota: Para realizar esta práctica debe asegurarse de tener instalado el SW para el desarrollo de programas en
lenguaje “C”. La librería stdio.h debería estar en el directorio /usr/include.
$ls –l /usr/include/std*.h
Para saber si los paquetes están instalados, realice lo siguiente:
$ aptitude show gcc | grep Estado
$ aptitude show libc6 | grep Estado
$ aptitude show build-essential | grep Estado

Para saber si un paquete se encuentra instalado en nuestra máquina:


 Fedora: rpm -qa | grep paquete
 Debian/Ubuntu: dpkg -l | grep paquete

Si no están instaladas proceda a hacerlo, siguiendo la siguiente guía:


Que versión de Ubuntu utiliza?
$lsb_release -a

Luego para actualizar las fuentes escriba:


$ sudo apt-get update
$ sudo apt-get upgrade

Finalmente instale las librerías necesarias para el desarrollo de programas en “C”:


$ sudo apt-get install gcc libc6 build-essential
Listo!!!!!!

Ciclo de creación de un programa

1
Msc. Rina Arauz
UNAN-León
Sistemas Operativos
Para compilar y generar el ejecutable:
$ cc programa.c -o programa
Para ejecutarlo (si el programa reside en el directorio actual de trabajo (.)):
$ ./programa
O el camino absoluto:
$/home/usuario/programa

Si no específica el camino del archivo ejecutable sólo se buscará el programa en aquellos directorios
del sistema especificados en la variable de entorno PATH y por lo tanto el resultado será archivo no
encontrado.

Las opciones más frecuentes de cc son:


-g Generarse información de depuración.

-E Genera el fichero preprocesado (.i) hay que utilizar esta opción junto con la opción –o.
$ cc programa.c –E –o programa.i

-S Generar el fichero en código ensamblador (.s).


$ cc programa.c –S genera programa.s

-c Generar el fichero objeto (.o).


$ cc programa.c –c genera programa.o

Otras opciones son:


-o nombre Especificar el nombre del archivo de salida
-I directorio Incluir el directorio al buscar archivos .h
-L directorio Incluir el directorio al buscar bibliotecas
-lbiblioteca Usar la biblioteca “biblioteca”.

1) Ejercicio:
- Visualice y escriba en su cuaderno el valor de la variable PATH de su sistema. Para
que utiliza esta variable el sistema?
- Edite un fichero prog1.c en lenguaje “C” que sume dos números.
- Utilice la herramienta cc del Linux para comprobar que la sintaxis es correcta
(depurar).
- Utilice la herramienta cc del Linux para generar el fichero preprocesado (.i) del
fichero prog1.c.
- Utilice la herramienta cc del Linux para generar el fichero objeto (.o) del fichero
prog1.c.
- Utilice la herramienta cc del Linux para generar el fichero ensamblador (.s) del
fichero prog1.c.
- Utilice la herramienta cc del Linux para generar el fichero ejecutable del fichero
prog1.c y ejecútelo.

2
Msc. Rina Arauz
UNAN-León
Sistemas Operativos
Para el desarrollo de aplicaciones (múltiples archivos) en entorno UNIX:
- Dedicar un directorio central o principal al
proyecto.
 src, directorio donde residen los ficheros en código
fuente (.c)
 include, directorio donde residen los ficheros de
cabecera (.h)
 lib, directorio donde residen las bibliotecas (.a)
 bin, directorio donde residen los programas
ejecutables
- Dividir el programa fuente en módulos.

Fichero de cabecera: Extensión .h, Contiene la definición de los tipos de datos y la declaración de las
funciones (prototipo).

Los ficheros de cabecera NO deben tener asignaciones o reserva de memoria para variables.

Las funciones públicas aparecerán en el fichero cabecera, pero sólo debe aparecer la declaración, es decir,
la cabecera. La implementación de las funciones viene en el fichero de implementación.

En el fichero de implementación deberá agregarse un #include del fichero de cabecera del proyecto.

Conviene usar #ifndef ... #endif en el fichero cabecera, para evitar que un fichero se incluya varias veces

3
Msc. Rina Arauz
UNAN-León
Sistemas Operativos
La procedencia de los ficheros que aporta el sistema operativo es la siguiente:
Ficheros de cabecera Directorio /usr/include (ejemplo: stdio.h, stdlib.h, etc)
Bibliotecas Directorio /lib, /usr/lib

Gestión de bibliotecas de funciones


Una biblioteca es un fichero que está compuesto por una colección de otros ficheros llamados
miembros de la biblioteca.

El programa para gestionar bibliotecas es ar. Para la gestión de proyectos de programación, son los
ficheros objetos los que nos interesa incluir en las bibliotecas.

La sintaxis de ar es la siguiente:
$ ar [-]opciones [miembro] biblioteca [ficheros]

Cuando se emite una orden ar es necesario que haya una opción obligatoria y sólo una.
Opciones obligatorias:
d Borrar miembros de la biblioteca.
p Imprime los miembros de la biblioteca.
q Añadir ficheros al final de una biblioteca.
r Reemplazar ficheros en la biblioteca.
t Mostrar una tabla con el contenido de la biblioteca.
x Extraer miembros de la biblioteca.

Modificadores:
a Añadir nuevos ficheros detrás de un miembro existente en la biblioteca.
c Crear la biblioteca

Ejemplo de creación de una biblioteca en el proyecto Polinomios:


Aplicación Polinomios: Esta aplicación se compone de tres módulos: pol_es.c, pol_arit.c y pol.c. El
tercer modulo contiene la función main desde la que son invocadas las funciones de manipulación que hay en
los dos primeros módulos. Tanto pol_es.c como pol_arit.c contienen funciones que pueden ser utilizadas para
crear otros programas que manejen polinomio, por lo tanto crearemos la biblioteca libpol.a

La forma de crear la biblioteca es:


- Compilar los módulos pol_es.c y pol_arit.c
- $cd $HOME/polinomios /src
- $cc –c pol_es.c –I ../include
- $cc –c pol_arit.c –I ../include
- la opción –I se utiliza para indicar un nuevo camino de búsqueda de los ficheros de cabecera.
-
- Generar la biblioteca libpol.a
- $ar r ../lib/libpol.a pol_es.o pol_arit.o

Ejemplo para obtener el ejecutable del proyecto Polinomios, haciendo uso de las
cabeceras, librerías, bibliotecas y ficheros fuentes:
Generar el programa ejecutable pol
$cc pol.c –I ../include -L ../lib -lpol –o ../bin/pol

4
Msc. Rina Arauz
UNAN-León
Sistemas Operativos
–I ../include: indica una ruta en donde buscar los ficheros de cabecera
-L ../lib: indica un la ruta en donde buscar las bibliotecas
-lpol: indica una nueva biblioteca en donde buscar las referencias no resueltas
–o ../bin/pol: el programa ejecutable pol se deposita en un directorio distinto del directorio de trabajo actual.

Ejemplo completo de un proyecto:


Aplicación Enteros: Esta aplicación se compone de tres módulos: proges.c, prog_arit.c y prog.c. El
tercer modulo contiene la función main desde la que son invocadas las funciones de manipulación que hay en
los dos primeros módulos. Tanto proges.c como prog_arit.c contienen funciones que pueden ser utilizadas para
crear otros programas que manejen enteros, por lo tanto crearemos la biblioteca libprog.a

SOLUCION:
Ejemplo:
1) Crear la jerarquía de directorios para el proyecto:
mkdir principal
cd principal
mkdir src
mkdir include
mkdir lib
mkdir bin

2) Editar el archivo cabecera dentro del directorio include.


prog.h
#ifndef _LIB_PROG
#define _LIB_PROG
int suma(int,int);
int resta(int,int);
int multiplica(int,int);
int leer();
void imprimir(int);
#endif

 Editar los arch fuente (dentro del directorio src) y agregar #include del archivo de cabecera .h.
prog_arit.c proges.c prog.c
#include</home/rina/principal/include/prog.h> #include</home/rina/principal/include/prog.h> #include <stdio.h>
#include<stdlib.h>
int suma(int a, int b) int leer() #include</home/rina/principal/include/prog.h>
{ {
int resul=(a+b); int a; void main()
return resul; printf("\n Ingrese el entero:"); {
} scanf("%d",&a); int a,b,c;
return a; a=leer();
int resta(int a, int b) } b=leer();
{ c=suma(a, b);
int resul=(a-b); void imprimir(int a) imprimir(c);
return resul; { }
} printf("\n El valor es:%d \n",a);
return;
int multiplica(int a, int b) }
{
int resul=(a*b);
return resul;
}

5
Msc. Rina Arauz
UNAN-León
Sistemas Operativos

3) Depurar los archivos de errores de sintaxis:


cc prog_arit.c –g
cc prog_es.c –g

4) Crear la biblioteca (libprog.a)


- Genere los ficheros obj
cc –c prog_arit.c –I ../include
cc –c proges.c –I ../include

- Añadir los ficheros a la biblioteca


ar r ../lib/libprog.a prog_arit.o
ar r ../lib/libprog.a proges.o

5) Generar el archive ejecutable(binario) del proyecto:


cc prog.c –I ../include –L ../lib –lprog –o ../bin/prog

6) Ejecutar:
../bin/prog

2) Ejercicio:
- En qué directorio se encuentran stdio.h y stdlib.h? y string.h y math.h?
- Realice una aplicación para la gestión de fracciones. Esta aplicación se compone de
tres módulos con código: fraccion.c, frac_arit.c y frac_es.c. El módulo fraccion.c
contiene la función main desde la que son invocadas las funciones de manipulación
que hay en los dos primeros módulos. El fichero frac_es.c contendrá las funciones
leerfrac() y escribirfrac() y en el fichero frac_arit.c contiene la función
multiplicafrac(). Las funciones pueden ser utilizadas para crear otros programas
que manejen números fracción y por ello deberá crear la biblioteca libfrac.a.
(Genere el árbol de directorios necesarios).
- Compilar los módulos frac_es.c y frac_arit.c
- Genere la biblioteca libfrac.a
- Generar el programa ejecutable frac.

6
Msc. Rina Arauz
UNAN-León
Sistemas Operativos

Automatización del proceso de construcción: make


Compilación de varios archivos

Cuando el programa es más grande o tiene varias unidades lógicas, tiene sentido dividir el código fuente es
archivos separados .c más fáciles de manejar. En este caso el comando será: cc green.c blue.c

Compilación separada seria:


cc -c green.c
cc -c blue.c
cc green.o blue.o

El programa make sirve para automatizar la construcción de programas, y es especialmente útil cuando
un programa se compone de varios archivos fuente. El objetivo es sustituir múltiples invocaciones a cc y a otras
herramientas por una simple invocación a make, lo cual ahorra mucho tiempo y evita errores y molestias.

Para conseguir este objetivo, make emplea básicamente dos cosas: las fechas de modificación o creación
de los archivos y un archivo makefile, que le indica qué cosas hacer y cómo, en caso de detectar
modificaciones.

Elementos básicos de un Makefile


Un Makefile se compone básicamente de dos cosas:
• Definición de variables.
• Reglas, que especifican:
• Objetivo a construir
• De quién depende el objetivo
• Qué hay que hacer para construirlo

Las reglas son las que permiten la reconstrucción automática de un proyecto. Una regla en un
Makefile tiene la siguiente forma:

objetivo: [dependencia1] [dependencia2] ...


comando1
comando2
...

7
Msc. Rina Arauz
UNAN-León
Sistemas Operativos
Construcción del archivo Makefile

Grafo de dependencias

EL formato básico es:


target : archivos_fuente(s)
comando(s) (debe ser precedido por un tab)

Una vez construido, basta con invocar:


$make
make lee el archivo makefile o Makefile del directorio actual y lo procesa.

jemplo:
hellomake.c hellofunc.c hellomake.h
#include <stdio.h>
#include <hellomake.h> #include <hellomake.h>
/*
int main()
example include file
{ void myPrintHelloMake(void)
*/
myPrintHelloMake(); {
return(0); printf("HOLA makefiles!\n");
void myPrintHelloMake(void);
} return;
}

$cc hellomake.c hellofunc.c -o hellomake


Makefile
hellomake: hellomake.c hellofunc.c
gcc -o hellomake hellomake.c hellofunc.c –I

Un objetivo falso (“phony target” en inglés) es aquel que no es realmente un nombre de fichero, sino un
nombre descriptivo de alguna acción, por ejemplo:
clean: ; rm -f *.o core
Observe que faltan las dependencias y que hemos puesto la orden en la misma línea, separada por un punto y
coma. Como la orden de borrado claramente no crea ningún fichero que se llame clean, probablemente no
existirá tal fichero, por lo que rm se ejecutará cada vez que se dé la orden ‘make clean’. Este objetivo dejará de
funcionar si se crea un fichero que se llame clean en el directorio, por ello debe declararse explícitamente que el
objetivo es falso (phony, con punto inicial y en mayúsculas).

8
Msc. Rina Arauz
UNAN-León
Sistemas Operativos
.PHONY: clean
clean:
rm *.o
rm hello

Ejemplo:
Makefile
../bin/prog: ../include/prg.h ../lib/libprog.a prog.c
cc -g prog.c -I ../include -L ../lib -lprog -o ../bin/prog

../lib/libprog.a: proges.o prog_arit.o


ar r ../lib/libprog.a proges.o prog_arit.o

proges.o: ../include/prog.h proges.c


cc -c proges.c -I ../include

prog_arit.o: ../include/prog.h prog_arit.c


cc -c prog_arit.c -I ../include

.PHONY: clean
clean:
rm *.o
rm ../lib/l*.a
rm ../bin/p*

Para ejecutar el makefile debe utilizar:


$make

Para limpiar los directorios, recompilar de nuevo y hacer uso de :PHONY:clean debe
utilizar: $make clean y luego $make

Depurador (GDB)
Para poder depurar un programa es necesario contar con su archivo fuente y haber compilado el
mismo con la opción -g.
$ cc –g prog.c –o prog
Para depurar un programa, se invoca gdb simplemente pasándole el nombre del archivo ejecutable.
$ gdb prog
Algunas de las órdenes básicas de gdb para depurar un programa son:
run Ejecuta el programa.
break Coloca un punto de ruptura (breakpoint) en una línea o función
watch Genera una ruptura cuando se modifica una expresión vigilada
list Muestra las líneas de programa
step Ejecuta un paso de programa, entrando en las funciones
next Ejecuta un paso de programa, sin entrar en las funciones
9
Msc. Rina Arauz
UNAN-León
Sistemas Operativos
print Muestra el valor de variables
finish Continúa hasta el final
info Muestra información acerca de displays, breakpoints, etc.
quit Salir
3) Ejercicio:
- Utilice la herramienta GDB para depurar el programa de Números Fracciones del
ejercicio anterior. (visualice variables, ejecute paso a paso, etc)…
- Realice el makefile para su proyecto de Fracciones.

10
Msc. Rina Arauz

También podría gustarte