El soporte para la programación en Linux es muy amplio, tanto es así que en cualquier distribución podemos encontrar compiladores, depuradores o intérpretes de prácticamente la mayoría de los lenguajes de programación existentes. Además de la fiabilidad y robustez propias de Linux, también se nos proporcionan editores con funciones orientadas a la programación, así como potentes herramientas (como es el caso del comando make) para la gestión y compilación de nuestros proyectos.
En esta sección explicaremos cómo instalar y utilizar los compiladores de Ada y Haskell bajo linux, así como GtkAda, paquete necesario para compilar aplicaciones gráficas programadas en Ada.
El compilador de Ada viene en los cds de muchas de las distribuciones mas comunes de linux, en caso de no tenerlo tendremos que buscar las fuentes de internet (www.freshmeat.net p ej), bajárnoslas y compilarlas tal y como se describe más adelante.
En el caso de debian es muy sencillo instalar el gnat, simplemente ejecutaremos apt-get y el se encargará de buscarlo en su base de datos, pedirnos el cd correspondiente e instalarlo correctamente
[09:19pm]Andromeda:/instalando # apt-get install gnat
Reading Package Lists... Done
Building Dependency Tree... Done
The following NEW packages will be installed:
gnat
0 packages upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
Need to get 0B/7656kB of archives. After unpacking 29.5MB will be used.
Media Change: Please insert the disc labeled 'Debian GNU/Linux 2.2 r0 _Potato_
- Official i386 Binary-2 (20000814)' in the drive '/cdrom/' and press enter
Selecting previously deselected package gnat.
(Reading database ... 59113 files and directories currently installed.)
Unpacking gnat (from .../devel/gnat_3.12p-5.deb) ...
Setting up gnat (3.12p-5) ...
Si lo que tenemos es el gnat para otras distribuciones siempre lo podemos instalar ``a mano transformándolo previamente con alien a un paquete soportado por nuestra distribución y posteriormente instalándolo con dpkg (debian), rpm (redhat) ... En el siguiente ejemplo se transforma un paquete rpm de RedHat a un .deb y posteriormente lo instalamos con dpkg
[09:28pm]Andromeda:/instalando # alien gnat_3.13p-8_i386.rpm
95710 blocks
dh_testdir
# Nothing to do.
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
cp -a `ls |grep -v debian` debian/tmp
dh_installdocs
dh_installexamples
dh_installmenu
dh_installcron
dh_installchangelogs
utmp entry ("victor") does not match value of LOGNAME ("root");
using "root" at
/usr/lib/dpkg/controllib.pl line 47.
dh_compress
dh_suidregister
dh_installdeb
dh_shlibdeps
utmp entry ("victor") does not match value of LOGNAME ("root");
using "root" at
/usr/lib/dpkg/controllib.pl line 47. dpkg: not found.
dpkg-shlibdeps: warning: could not find any packages for
(libgnat-3.13p.so.1)
dpkg-shlibdeps: warning: unable to find dependency information for shared
library libgnat-3.13p (soname 1, path , dependency field Depends)
dh_gencontrol
utmp entry ("victor") does not match value of LOGNAME ("root");
using "root" at /usr/lib/dpkg/controllib.pl line 47.
utmp entry ("victor") does not match value of LOGNAME ("root");
using "root" at
/usr/lib/dpkg/controllib.pl line 47.
dh_makeshlibs
dh_md5sums
dh_builddeb
dpkg-deb: building package `gnat' in `../gnat_3.13p-8_i386.deb'.
-- Examining gnat-3.13p-7.i386.rpm
-- Unpacking gnat-3.13p-7.i386.rpm
/usr
-- Automatic package debianization
-- Building the package gnat_3.13p-8_i386.deb
Generation of gnat_3.13p-8_i386.deb complete.
-- Successfully finished
[09:29pm]Andromeda:/instalando # mount /dev/hdc /cdrom
[09:29pm]Andromeda:/instalando # cd
/cdrom/dists/potato/main/binary-i386/devel/
[09:30pm]Andromeda:/cdrom/dists/potato/main/binary-i386/devel #
dpkg -i gnat_3.12p-5.deb
Selecting previously deselected package gnat.
(Reading database ... 59113 files and directories currently installed.)
Unpacking gnat (from gnat_3.12p-5.deb) ...
Setting up gnat (3.12p-5) ...
[09:30pm]Andromeda:/cdrom/dists/potato/main/binary-i386/devel #
También podemos instalar el gnat a partir del tar.gz que contiene scripts para configurar e instalar el paquete según las opciones que les especifiquemos en doconfig y doinstall. Para ello lo primero que tenemos que hacer es descomprimir el archivo como sigue:
[09:36pm]Andromeda:/instalando # ls
gnat-3.13p-i686-pc-linux-gnu-bin.tar.gz
[09:36pm]Andromeda:/instalando # tar zxvf
gnat-3.13p-i686-pc-linux-gnu-bin.tar.gz
Una vez descomprimido nos situamos en el directorio creado y ejecutamos la herramienta de configuración 'doconfig' que preparara la instalación del programa
[09:37pm]Andromeda:/instalando/gnat-3.13p-i686-pc-linux-gnu-bin # ls
COPYING crtendS.o gnatbind gnatmem libpthread-2.0.a
Makefile doconfig gnatbl gnatprep limitx.h
README examples gnatchop gnatpsta limity.h
README.TASKING features gnatelim gnatpsys rts-fsu
README.gnatelim float.h gnatfind gnatstub rts-native
README.gnatstub gcov gnathtml.pl gnatxref specs
cc1 gdb gnatinfo.txt gsyslimits.h xgcc
cpp gdbtk gnatkr libaddr2line.a
crtbegin.o ginclude gnatlink libgcc.a
crtbeginS.o glimits.h gnatls libgthreads.a
crtend.o gnat1 gnatmake libmalloc.a
[09:37pm]Andromeda:/instalando/gnat-3.13p-i686-pc-linux-gnu-bin #
./doconfig
There are 2 options for installation:
2) Install GCC C compiler and GNAT files in the standard GNAT locations.
(Note: This includes directories under /usr/gnat. On most
systems, this requires root permission).
3) Install GCC C compiler and GNAT files in non-standard locations
that you will specify.
Options 2 provides simplest and most flexible use of GNAT.
Type 2, or 3 (then RETURN) to choose an option:
2
En este punto nosotros seleccionamos la opción 2 por lo que el gnat se instalará en la ruta por defecto, si quisieramos instalarlo en un directorio en concreto deberiamos elegir la opción 3
The installation in the GCC standard locations will install:
In /usr/gnat/bin :
gcc gnatbind gnatbl gnatchop gnatfind gnatkr gnatls gnatlink
gnatmake
gnatmem gnatprep gnatpsta gnatpsys gnatxref gcov gdb gdbtk
gnatelim gnatstub addr2line objdump
In /usr/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1 :
gnat1 cc1 cpp ld libgcc.a specs
and libgthreads.a
In /usr/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1/adainclude :
The source files of the RTL
In /usr/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1/adalib :
The object & ali files of the RTL
and libgnat.a
Configuration complete. Run doinstall to do the installation.
DO NOT FORGET: put /usr/gnat/bin at the front of your PATH
Con esto ya deberíamos tener configurado el programa de instalación, algo importante es que no olvidemos añadir en el PATH el directorio /usr/gnat/bin para que podamos ejecutar el compilador desde cualquier directorio, para ello modificaremos el archivo /etc/profile o el ~/.bash_profile y añadiremos al la linea donde se define el PATH=`... :/usr/gnat/bin`
Ahora solo queda ejecutar la instalación a través de ./doinstall
[09:42pm]Andromeda:/instalando/gnat-3.13p-i686-pc-linux-gnu-bin #
./doinstall
Una vez hecho esto ya tenemos disponible el compilador de Ada, pudiendo invocarlo en cualquier momento mediante el comando gnatmake
La sintaxis del comando es la siguiente:
gnatmake opciones nombre [-cargs opts] [-bargs opts] [-largs opts]
en donde nombre es el nombre del fichero a compilar
opciones es uno de los siguientes argumentos:
gnatmake switches:
-a Consider all files, even readonly ali files
-c Compile only, do not bind and link
-f Force recompilations of non predefined units
-i In place. Replace existing ali file, or put it with source
-jnum Use nnn processes to compile
-k Keep going after compilation errors
-m Minimal recompilation
-M List object file dependences for Makefile
-n Check objects up to date, output next file to compile if not
-o name Choose an alternate executable name
-q Be quiet/terse
-v Motivate all (re)compilations
-z No main subprogram (zero main)
--GCC=command Use this gnatgcc command
--GNATBIND=command Use this gnatbind command
--GNATLINK=command Use this gnatlink command
Gnat/Gnatgcc switches such as -g, -O, -gnato, etc.are directly passed
to gnatgcc
y -cargs opts, -bargs opts, -largs opts son opciones que se le pueden pasar directamente al compilador, al binder y al linkeador respectivamente.
Ejemplo
[06:26pm]victor@Orion:~/facultad/ed1/Practicas/Practica1 > ls
cadenas_entrada.adb colas.adb inf_postf.adb pilas.adb
prueba.adb tokens.ads
cadenas_entrada.ads colas.ads inf_postf.ads pilas.ads
tokens.adb
[06:26pm]victor@Orion:~/facultad/ed1/Practicas/Practica1 > gnatmake prueba
gnatgcc -c prueba.adb
gnatgcc -c cadenas_entrada.adb
gnatgcc -c colas.adb
gnatgcc -c inf_postf.adb
gnatgcc -c tokens.adb
gnatgcc -c pilas.adb
gnatbind -x prueba.ali
gnatlink prueba.ali
[06:26pm]victor@Orion:~/facultad/ed1/Practicas/Practica1 > ls
cadenas_entrada.adb colas.adb inf_postf.adb pilas.adb prueba
tokens.adb
cadenas_entrada.ads colas.ads inf_postf.ads pilas.ads prueba.adb
tokens.ads
cadenas_entrada.ali colas.ali inf_postf.ali pilas.ali prueba.ali
tokens.ali
cadenas_entrada.o colas.o inf_postf.o pilas.o prueba.o
tokens.o
[06:26pm]victor@Orion:~/facultad/ed1/Practicas/Practica1 >
También podemos bajar las fuentes de los programas que queramos instalar y compilarlas nosotros mismos, éste procedimiento está bastante estandarizado y la mayoría de las veces uno no tiene más que recordar 3 o 4 comandos para instalar cualquier programa que se baje a partir de las fuentes, claro que siempre pueden ocurrir problemas (programas que no compilan por estar todavía en desarrollo, dependencias a librerias que no tenemos instaladas...) por lo que siempre es recomendable instalar los programas a partir de los paquetes diseñados para las distribuciones, aun así hay programas que no se encuentran "empaquetados" para las distribuciones por lo que no nos quedará más remedio que abordar el tar.gz.
Éste es el caso del GtkAda, así que lo primero que haremos, como antes, será descomprimir el archivo con el comando tar:
[11:32pm]Andromeda:/instalando # ls
GtkAda-1.2.11.tgz gnat-3.13p-i686-pc-linux-gnu-bin.tar.gz
gnat-3.13p-i686-pc-linux-gnu-bin
[11:32pm]Andromeda:/instalando # tar zxvf GtkAda-1.2.11.tgz
Una vez descomprimidos nos situamos sobre el directorio que se ha creado y ejecutamos configure que se encargará de preparar el Makefile necesario para la posterior compilación
[11:33pm]Andromeda:/instalando # cd GtkAda-1.2.11
[11:33pm]Andromeda:/instalando/GtkAda-1.2.11 # ls
ANNOUNCE INSTALL aclocal.m4 configure docs
known-problems
AUTHORS Makefile.in config.guess configure.in examples src
COPYING README config.sub contrib install-sh testgtk
[11:33pm]Andromeda:/instalando/GtkAda-1.2.11 # ./configure
Llegado a este punto configure realizará una serie de comprobaciones para ver si se puede instalar el programa en cuestión, aquí pueden surgir problemas por no tener instaladas en el sistema librerias necesarias para que GtkAda funcione, a continuación se detalla un ejemplo de ejecución de configure en un sistema que no tiene la versión 1.2.2 de libgtk-dev o superior instalada.
checking for gtk-config... no
checking for GTK - version >= 1.2.2... no
* The gtk-config script installed by GTK could not be found
* If GTK was installed in PREFIX, make sure PREFIX/bin is in
* your path, or set the GTK_CONFIG environment variable to the
* full path to gtk-config.
configure: error: Test for GTK failed. See the file 'INSTALL' for help.
Para arreglar esto tendremos que instalar el paquete libgtk-dev con apt-get, dpkg, rpm ... con versión mayor o igual a la 1.2.2 y volver a ejecutar el configure, si todo ha ido bien debería acabar con unas lineas como éstas:
[...]
creating src/gtkada-config
creating src/gate
creating testgtk/Makefile
creating src/gtkextra/Makefile
creating src/opengl/Makefile
creating src/pixbuf/Makefile
creating src/glade/Makefile
creating src/gnome/Makefile
creating docs/gtkada_ug/Makefile
creating docs/gtkada_rm/Makefile
Ahora tendremos que compilar, para ello el configure habrá creado un Makefile de acuerdo a las características de nuestra máquina, por lo que simplemente tendremos que ejecutar `make` para que comience la compilación del gtkada
[11:34pm]Andromeda:/instalando/GtkAda-1.2.11 # make
Una vez que se ha compilado (siempre que no haya habido errores), procedemos a copiar el programa en los directorios que le corresponda, para ello ejecutaremos `make install` y con ello finalizara la instalacion.
[11:34pm]Andromeda:/instalando/GtkAda-1.2.11 # make install
[...]
A partir de ahora ya podremos usarlo, tal y como dice el archivo INSTALL
gnatmake <your\_application> <your\_switches> `gtkada-config`
Al igual que el gnat, la instalación del hugs a través del apt-get es sumamente sencilla, simplemente tendremos que ejecutar apt-get install hugs como root y apt-get se encargará de instalar el intérprete de haskell.
[11:21pm]Andromeda:/home/victor # apt-get install hugs
Reading Package Lists... Done
Building Dependency Tree... Done
The following NEW packages will be installed:
hugs
0 packages upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
Need to get 0B/416kB of archives. After unpacking 1561kB will be used.
Media Change: Please insert the disc labeled 'Debian GNU/Linux 2.2 r0 _Potato _
- Official i386 Binary-2 (20000814)' in the drive '/cdrom/' and press enter
Selecting previously deselected package hugs.
(Reading database ... 60297 files and directories currently installed.)
Unpacking hugs (from .../hugs_98.199911-1.deb) ...
Setting up hugs (98.199911-1) ...
Una vez instalado, para ejecutarlo sólo tendremos que teclear `hugs` en cualquier consola
[11:23pm]Andromeda:/home/victor # hugs
_ _
|| || || || || || || Hugs 98: Based on the Haskell 98 standard
||_|| |||| |||| || Copyright (c) 1994-1999
||
|| _|| World Wide Web: http://haskell.org/hugs
|| || Report bugs to: hugs-bugs@haskell.org
|| || Version: November 1999 _
Haskell 98 mode: Restart with command line option -98 to enable extensions
Reading file "/usr/share/hugs98/lib/Prelude.hs":
Hugs session for:
/usr/share/hugs98/lib/Prelude.hs
Type :? for help
Prelude>
Para instalar el paquete a mano seguiremos el mismo procedimiento que usamos para instalar el gnat, esto es, transformar el paquete a nuestra distribución con el comando `alien', e instalarlo posteriormente con dpkg, rpm ...
Los comandos más utilizados en el hugs son los siguientes:
:l nombre_archivo Carga el archivo indicado en el intérprete, si se detectan errores seran mostrados por el intérprete.
:r Vuelve a cargar el último archivo cargado (útil tras hacer modificaciones).
:t nombre_var Muestra el tipo al que pertenece la variable nombre_var.
:! comando Ejecuta el comando de shell que se haya indicado.
:q Sale del intérprete.
:? Lista los comandos disponibles.
El modo haskell para emacs permite trabajar más cómodamente en este editor cuando programamos en Haskell, esto se logra coloreando las palabras clave, gestionando las tabulaciones ... Este modo no viene por defecto con emacs pero afortunadamente podemos encontrar en internet un targz que contiene los archivos necesarios para su funcionamiento, este archivo es el haskell-mode.tar.gz y lo podéis encontrar en ``http://www.haskell.org/haskell-mode/''
Bien, una vez bajado el archivo a nuestro disco deberemos situarlo en la carpeta ~/lib/emacs de nuestro home y descomprimirlo ahí (si no tenemos dicho directorio lo crearemos con mkdir).
[07:41pm]victor@Andromeda:~ > mkdir lib
[07:41pm]victor@Andromeda:~ > cd lib
[07:41pm]victor@Andromeda:~/lib > mkdir emacs
[07:41pm]victor@Andromeda:~/lib > cd emacs
[07:41pm]victor@Andromeda:~/lib/emacs > cp
/instalando/haskell-mode.tar.gz .
[07:42pm]victor@Andromeda:~/lib/emacs > tar zxvf haskell-mode.tar.gz
haskell-mode.el
haskell-decl-scan.el
haskell-font-lock.el
haskell-indent.el
haskell-doc.el
haskell-hugs.el
haskell-simple-indent.el
[07:42pm]victor@Andromeda:~/lib/emacs > ls
haskell-decl-scan.el haskell-hugs.el haskell-mode.tar.gz
haskell-doc.el haskell-indent.el haskell-simple-indent.el
haskell-font-lock.el haskell-mode.el
[07:42pm]victor@Andromeda:~/lib/emacs > rm haskell-mode.tar.gz
[07:42pm]victor@Andromeda:~/lib/emacs >
Una vez hecho esto abriremos el fichero .emacs situado en nuestro home y le añadiremos las siguientes lineas:
(setq load-path (cons "~/lib/emacs" load-path))
(setq auto-mode-alist
(append auto-mode-alist
'(("\\.[hg]s$" . haskell-mode)
("\\.hi$" . haskell-mode)
("\\.l[hg]s$" . literate-haskell-mode))))
(autoload 'haskell-mode "haskell-mode"
"Major mode for editing Haskell scripts." t)
(autoload 'literate-haskell-mode "haskell-mode"
"Major mode for editing literate Haskell scripts." t)
(add-hook 'haskell-mode-hook 'turn-on-haskell-font-lock)
(add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
(add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)
(add-hook 'haskell-mode-hook 'turn-on-haskell-hugs)
Con esto simplemente emacs cargara el haskell-mode cada vez que abramos un archivo con extension hs, tambien podemos cargar este modo a mano con la siguiente combinacion: M-x haskell-mode
Un Makefile es un archivo de configuración que leerá el comando `make` cuando se le invoque, donde se pueden idicar archivos a compilar, dependencias de compilación, flags a pasarle al compilador ...
Los Makefiles pueden llegar a ser archivos grandes y complejos pero nosotros trataremos de explicar las nociones mas basicas de los mismos.
Proceso de creacion de un arcivo Makefile:
Nos situamos en el directorio donde esten contenidos los ficheros con el codigo a compilar
Creamos el fichero con nombre Makefile que estará estructurado de la siguiente manera:
identificador: lista de archivos a compilar
accion a realizar
Veamos esto con un ejemplo:
[07:42pm]victor@Andromeda:~/programacion/ada > cat Makefile
Interfaz: imagen.adb transformacion.adb nucleo.adb rle.adb qt.adb interf\
az.adb
gnatmake -g interfaz.adb `gtkada-config`
clean:
rm *.o *.ali *~ b~* interfaz
En este caso tenemos 2 posibles llamadas a make: make interfaz y make clean. En caso de hacer make interface el comando make ejecutara el gnatmake sobre cada uno de los archivos a compilar en el orden dado por el Makefile, esto es: imagen.adb, transformacion.adb, nucleo.adb...asi hasta interfaz.adb. El make clean lo que hará será borrar todos los archivos generados tras compilar ( .o, .ali y binario final), esto es útil para volver a dejar el directorio como antes de invocar make interfaz.