Más grande será la caída

Aquella noche, estando plácidamente tumbado en su playa privada, volvió a
jugar a darle la vuelta al mundo, imaginando que contemplaba el universo
mirando hacia abajo en lugar de hacia arriba. Al poco rato le pareció
notar algo así como una ligera sensación de vértigo, provocada sin duda por el
titilante brillo de las estrellas en las ilimitadas profundidades del
cosmos. La ligera sensación de vértigo parecía ir en aumento de manera
casi imperceptible, y empezó a pensar, no sin cierta inquietud, que se estaba
imaginando cosas raras. Era como si pesara cada vez menos, como si la arena
fuese disminuyendo lentamente la presión sobre su dorso, como si su cuerpo
se estuviera apartando de la Tierra, irremediablemente atraído por el
magnetismo del espacio. Un momento más tarde se dio cuenta de la realidad y
chilló con todas sus fuerzas mientras agitaba los miembros con desesperación
infinita tratando de agarrase a algo, porque estaba cayendo. Y cayó y cayó
hasta perderse en las ilimitadas profundidades del cosmos, fuertemente asido a
un par de menguantes puñados de arena.

Publicado en Uncategorized | Deja un comentario

Problema

-Maestro:

Pastor de las veinte ovejas: Con éstas, y éstas, y otras tantas como éstas, más la mitad de éstas y la cuarta parte de éstas, ¿cuántas ovejas tienes?

-Pastor:

Veinte, señor, por mucho que las recuente.

Publicado en Microrrelatos | Deja un comentario

Intuición

Un escalofrío le recorrió la espalda mientras notaba su nuca traspasada por una mirada de intensidad tal que parecía tender hacia infinito. Se azoró de abajo a arriba, como un dibujo animado cambiando de color, sintiendo, más que adivinando, la salvaje atracción que despertaba en el desconocido que sin duda se hallaba tras ella. Adoptó su expresión más coqueta mientras se alisaba el pelo con la mano, y se giró de repente para cazar infraganti al dueño de esos ojos que la atravesaban. Pero se llevó una inesperada e inmensa decepción porque, sorprendentemente, no vio a nadie que pudiese estar mirándola. Entonces se fijó en el león del zoológico, que meneaba su melenuda cabeza con un gesto que sugería una mezcla de resignación y abatimiento.

Publicado en Microrrelatos | Deja un comentario

Atreviéndome con las GNU Autotools (a las dos…)

Atreviéndome con las GNU Autotools (a la una…)

 
 

Como continuación a la anterior entrada acerca de las autotools, vamos a ver en ésta como se haría para incluir otro paquete de forma que se configure, compile e instale como si formase parte de nuestro proyecto. También se intentará dar alguna idea acerca de la manera de añadir opciones al configure para que el usuario pueda habilitarlas o desabilitarlas a su gusto utilizando ./configure – -enable-cosa o ./configure – -disable-cosa, pero no contentos con eso, además intentaremos dar alguna pista sobre cómo podríamos buscarnos la vida para chequear en el configure algo que no utilice pkg-config.

Reiteramos que ésto en ningún modo pretende ser un manual exaustivo ni mucho menos, sino simplemente unos apuntes personales compartidos a través de la Red con la idea de dar algunas pistas a quién quiera y no sepa muy bien por donde empezar a “meterle mano” al bicho. En la Red hay mucha e infinitamente mejor información que lo que aquí ofrezco, aunque recomiendo buscarla en inglés.

Incluyendo otro paquete dentro del nuestro

Supongamos que, por la razón que sea, nos vendría bien hacer uso de un determinado programa con licencia GPL y queremos que se instale como si formase parte de nuestro proyecto (se da por supuesto que el programa a añadir contiene sus propios configure.ac y Makefile(s).am). La manera de proceder sería:

Primeramente descomprimir el paquete dentro de nuestro dirbase (ver la primera parte) y seguidamente tomar buena nota del nombre de la carpeta donde se ha descomprimido.
A continuación añadiríamos la siguiente línea a nuestro configure.ac a partir del punto donde esté situada la macro AC_CONFIG_HEADERS.

AC_ARG_ENABLE(progExterno, [--disable-progExterno no incluye progExterno])

Con la anterior línea habilitamos la opción ./configure –disable-progExterno, por lo que más adelante tendremos que tener en cuenta que la opción por defecto sea incluir progExterno. La expresión “no incluye progExterno” será lo que aparecerá, al efectuar un ./configure – -help, como explicación a la opción que desabilita la inclusión de progExterno en la compilación e instalación de nuestro proyecto.

Luego, antes de la macro AC_CONFIG_FILES pondríamos:

if test "x$enable_progExterno" = "xno"; then SUBDIRS_VALIDOS="src imgs doc" else SUBDIRS_VALIDOS="src imgs doc directorio_progExterno" AC_CONFIG_SUBDIRS(directorio_progExterno) fi AC_SUBST(SUBDIRS_VALIDOS)

Pero aquí hemos introducido una modificación a la forma en que tratábamos los subdirectorios a incluir en los Makefile.am de la primera parte. Es lo que pasa con GNU/Linux, que raramente hay una única manera de hacer las cosas.
La modificación consiste en exportar los subdirectorios (o carpetas) válidos a través de la variable SUBDIRS_VALIDOS, por lo que en el Makefile.am, en lugar de las líneas:

SUBDIRS = src imgs DIST_SUBDIRS = src imgs doc

pondremos simplemente:

SUBDIRS = @SUBDIRS_VALIDOS@

y listo. Nuestro paquete compilará e instalará por defecto progExterno y dará al usuario la opción de desabilitar esta acción ejecutando:

~/dirbase$ ./configure - -disable-progExterno

También podría ser necesario ejecutar dentro de directorio_progExterno su propio autogen.sh, o incluso crearlo si no existiera y distribuirlo junto con nuestro proyecto. Para asegurarnos de que se ejecuta y tratar de ahorrarle algo de trabajo al usuario final, bien podríamos añadir al autogen.sh de nuestro dirbase algunas líneas extras como:

cd directorio_progExterno
./autogen.sh
cd ../

Comprobando algo que no utiliza pkg-config

Para el caso vamos a suponer que queremos utilizar en nuestra aplicación las funciones de base de datos de PostgreSQL, los archivos de cabecera de CUPS, para localizar las impresoras del sistema, y los paquetes latex2html y pdflatex para generar los achivos de ayuda al usuario que hemos decidido crear con LaTeX (no los de documentación técnica de desarrollo, ya que éstos los creamos con Doxygen), en html y pdf y que se generen al momento de compilar, asegurándonos de esa forma de que el html y el pdf generados estén siempre al día y, de paso, ahorrando algo de espacio y de tiempo al enviar nuestras actualizaciones al repositorio.

Inmediatamente antes de las macros AC_SUBST(dependPKG_CFLAGS) y
AC_SUBST(dependPKG_LIBS), escribiríamos las siguientes líneas:

# Comprobación de que los archivos de cabecera de postgre y cups # están instalados:
AC_CHECK_HEADERS(postgresql/libpq-fe.h, [dependPKG_CFLAGS+="-I$(pg_config --includedir) "], [AC_MSG_ERROR([No se encuentra libpq-fe.h ¿libpq-dev no instalado?])], []) AC_CHECK_HEADERS(cups/cups.h, [dependPKG_CFLAGS+="$(cups-config --cflags) "], [AC_MSG_ERROR([No se encuentra cups.h ¿libcups2-dev no instalado?])], [])

# Comprobación de que también están los binarios
AC_CHECK_LIB(pq, main, [dependPKG_LIBS+="-L$(pg_config --libdir) -lpq "], [AC_MSG_ERROR([No se encuentra libpq ¿libpq no instalado?])], []) AC_CHECK_LIB(cups, main, [dependPKG_LIBS+="$(cups-config --libs) "], [AC_MSG_ERROR([No se encuentra libcups ¿libcups2 no instalado?])], [])

Aunque las bibliotecas no contengan la función main(), si la misma se le pasa como argumento a la macro AC_CHECK_LIB ésta se contentará con buscar si el paquete existe.

A continuación irían las macros:

AC_SUBST(dependPKG_CFLAGS) AC_SUBST(dependPKG_LIBS)

Y ahora tocaría comprobar que están instalados latex2html y pdflatex, que serán los que utilicemos para compilar la ayuda escrita en LaTeX.

# Comprueba la existencia de latex2html
printf "checking for latex2html... " if test -e /usr/bin/latex2html; then printf "yes\n" else printf "AVISO: No hallado /usr/bin/latex2html\n" printf "La documentación de ayuda no podrá compilarse ni instalarse.\n" fi

# Comprueba la existencia de pdflatex (pdftex)
printf "checking for pdflatex (pdftex)... " if test -e /usr/bin/pdflatex || test -e /usr/bin/pdftex; then printf "yes\n" else printf "no\n" printf "configure: AVISO: No hallado /usr/bin/pdflatex o /usr/bin/pdftex\n" printf " ¿texlive-latex-base no instalado?\n\n" printf " La ayuda no podrá compilarse en formato pdf.\n" printf " Esto no tiene importancia.\n" printf " Puede ignorar los errores de Make a este respecto.\n\n" fi

La utilidad de las macros AC_CHECK_HEADERS y AC_CHECK_LIB queda patente en el ejemplo: La primera se encarga de comprobar la existencia de los archivos de cabecera y la segunda de los binarios. No creo que haga falta decir (pero lo digo por si acaso) que al incluir en nuestra aplicación funciones de una biblioteca (o librería) externa, necesitamos tanto los archivos llamados de cabecera (los .h) para incluirlos en nuestros fuentes y poder así hacer uso de las funciones de la biblioteca, como los binarios, que son necesarios para enlazar nuestro ejecutable con la biblioteca en cuestión.

Pero tal vez alguien se pregunte: ¿De dónde salen pg_config y cups-config?
Pues de aquí: http://www.postgresql.org/docs/9.0/interactive/app-pgconfig.html
y de aquí: http://www.cups.org/documentation.php/doc-1.4/man-cups-config.html

En cada uno de esos enlaces vemos los parámetros a utilizar según lo que queramos hacer, en este caso chequear la instalación de las cabeceras (- -includedir y - -cflags) y de las bibliotecas (- -libdir y – -libs), según las especificaciones de la documentación de cada paquete.

Pensamos que queda suficientemente claro la importancia de leerse la documentación de todo aquello que vayamos a necesitar para completar nuestro proyecto, y que cuando nos dicen: “lee, lee, y lee“, no lo dicen por gusto ni por dar una cómoda respuesta aleccionadora, sino que, realmente, hay que leer documentación si uno quiere tener algunas posibilidades de llevar a buen puerto cualquier cosa que intente hacer con estas, y otras muchas, herramientas, y nadie hará el trabajo duro por nosotros. Nos darán más o menos pistas o podrán ser más o menos generosos, pero el aprendizaje hay que currárselo :-) .

Por el contrario, lo de latex2html y pdflatex se ha puesto para buscarlos pura y duramente en el directorio /usr/bin, por lo que habrá que adaptar esos trozos de código si tuviésemos que localizarlos en ubicaciones distintas.

Ya que hemos decidido añadir documentación para el usuario final, podemos situarla en un nuevo directorio llamado, por ejemplo, ayuda, así que habrá que crearle su propio Makefile.am destinado a conseguir los objetivos de generar la documentación en html y pdf y de instalarla allí donde podamos localizarla en nuestro programa cuando el usuario dé un clic en el botón “Ayuda” o lo que hayamos dispuesto al efecto. También hemos decidido que el formato por defecto de la ayuda sea html, dejando el pdf como opcional, por lo que situaremos los archivos html directamente en dirbase/ayuda, guardando los fuentes latex en dirbase/ayuda/LaTeX y el resultado en pdf en dirbase/ayuda/pdf.

Creamos los directorios a partir de dirbase:

~/dirbase$ mkdir -p ayuda/LaTeX ayuda/pdf

Creamos el Makefile.am para ayuda:

SUBDIRS = LaTeX ayudadir = $(datadir)/@PACKAGE@/ayuda ayuda_DATA = *.html *.png *.css EXTRA_DIST = ./LaTeX/*.tex ./LaTeX/imagenes/* ./pdf/*.pdf

Hemos incluido el directorio imagenes (dirbase/ayuda/LaTeX/imagenes) porque es muy normal que tengamos alguna captura de pantalla en la documentación de ayuda. El incluirlo de ésta forma hará que todo su contenido pase a formar parte del paquete, no siendo necesario crear un Makefile.am en él. (Sí, hay varias formas de hacer las cosas en GNU/Linux, ya lo hemos dicho antes).

El de ayuda/LaTeX:

# Genera la ayuda en html con latex2html y en pdf con pdflatex.
ARCH_PRAL = gfc.tex CC_HTML = latex2html CC_PDF = pdflatex OPCI_HTML = -split +2 -iso_language ES.ES -toc_stars -dir ../ OPCI_PDF = -output-directory ../pdf all: html pdf clean: rm -f ../*.html rm -f ../*.png rm -f ../*.css rm -f ../*.pl rm -f ../images.* rm -f ../WARNINGS rm -f ../pdf/* html: $(CC_HTML) $(OPCI_HTML) $(ARCH_PRAL) > /dev/null rm -f ../*.old

# Se compila dos veces para generar el índice correctamente.
pdf: $(CC_PDF) $(OPCI_PDF) $(ARCH_PRAL) > /dev/null $(CC_PDF) $(OPCI_PDF) $(ARCH_PRAL) > /dev/null

El anterior es un típico archivo Makefile, por lo que hay que tener en cuenta que cada comando ejecutable debe ir precedido de una tabulación (no de espacios en blanco), y las demás reglas de sintaxis de los archivos Makefile, las cuales pueden ser fácilmente encontradas en la Red y por tanto no nos vamos a extender con más explicaciones acerca de ellas.

Y no nos olvidemos de actualizar los cambios en el configure.ac:

SUBDIRS_VALIDOS="src imgs doc ayuda"

..//..

SUBDIRS_VALIDOS="src imgs doc ayuda directorio_progExterno"

y también:

AC_CONFIG_FILES([Makefile doc/Makefile doc/html/Makefile doc/html/search/Makefile imgs/Makefile src/Makefile ayuda/Makefile ayuda/Latex/Makefile])

El directorio_progExterno no se incluye en AC_CONFIG_FILES, puesto que ya lo está a través de AC_CONFIG_SUBDIRS.

Tampoco nos olvidamos de ejecutar:

~/dirbase$ ./autogen.sh
~/dirbase$ ./configure
~/dirbase$ make

Y por último make install en el caso de que queramos instalar la ayuda para localizar los archivos desde nuestros fuentes y make dist-bzip2 si queremos comprobar que todo lo que tiene que funcionar funciona.

Para terminar, veamos cómo quedarían nuestros archivos configure.ac y Makefile.am una vez aplicadas las modificaciones propuestas en esta segunda parte (pero ya sin comentarios):

El configure.ac

AC_INIT(miprograma, 0.1.9) AC_CONFIG_AUX_DIR(config) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_HEADERS([config.h]) AC_ARG_ENABLE(progExterno, [--disable-progExterno no incluye progExterno]) AC_PROG_CC AM_INIT_AUTOMAKE AM_SANITY_CHECK PKG_PROG_PKG_CONFIG PKG_CHECK_MODULES(dependPKG, [gtk+-3.0 libxml-2.0]) AC_CHECK_HEADERS(postgresql/libpq-fe.h, [dependPKG_CFLAGS+="-I$(pg_config --includedir) "], [AC_MSG_ERROR([No se encuentra libpq-fe.h ¿libpq-dev no instalado?])], []) AC_CHECK_HEADERS(cups/cups.h, [dependPKG_CFLAGS+="$(cups-config --cflags) "], [AC_MSG_ERROR([No se encuentra cups.h ¿libcups2-dev no instalado?])], []) AC_CHECK_LIB(pq, main, [dependPKG_LIBS+="-L$(pg_config --libdir) -lpq "], [AC_MSG_ERROR([No se encuentra libpq ¿libpq no instalado?])], []) AC_CHECK_LIB(cups, main, [dependPKG_LIBS+="$(cups-config --libs) "], [AC_MSG_ERROR([No se encuentra libcups ¿libcups2 no instalado?])], []) AC_SUBST(dependPKG_CFLAGS) AC_SUBST(dependPKG_LIBS) printf "checking for latex2html... " if test -e /usr/bin/latex2html; then printf "yes\n" else printf "AVISO: No hallado /usr/bin/latex2html\n" printf "La documentación de ayuda no podrá compilarse ni instalarse.\n" fi printf "checking for pdflatex (pdftex)... " if test -e /usr/bin/pdflatex || test -e /usr/bin/pdftex; then printf "yes\n" else printf "no\n" printf "configure: AVISO: No hallado /usr/bin/pdflatex o /usr/bin/pdftex\n" printf " ¿texlive-latex-base no instalado?\n\n" printf " La ayuda no podrá compilarse en formato pdf.\n" printf " Esto no tiene importancia.\n" printf " Puede ignorar los errores de Make a este respecto.\n\n" fi AC_CHECK_HEADERS([stdlib.h string.h]) AC_FUNC_MALLOC AC_CHECK_FUNCS([floor modf pow]) if test "x$enable_progExterno" = "xno"; then SUBDIRS_VALIDOS="src imgs doc ayuda" else SUBDIRS_VALIDOS="src imgs doc ayuda directorio_progExterno" AC_CONFIG_SUBDIRS(directorio_progExterno) fi AC_SUBST(SUBDIRS_VALIDOS) AC_CONFIG_FILES([Makefile doc/Makefile doc/html/Makefile doc/html/search/Makefile imgs/Makefile src/Makefile ayuda/Makefile ayuda/LaTeX/Makefile]) AC_OUTPUT

El Makefile.am  de dirbase:

SUBDIRS = @SUBDIRS_VALIDOS@ EXTRA_DIST = \ Changelog \ doc/html/* \ doc/html/search/* \ autogen.sh

A lo que añadimos los nuevos de dirbase/ayuda y dirbase/ayuda/LaTeX y el resto se quedan igual que en la primera parte.

Publicado en GNU/Linux | 2 comentarios

Sistematizando

Opciones, alternativas, fichas clasificadas,
encuadres, estadísticas, gente condicionada
para encasillarlo todo de una manera ordenada.
La persona ya no es un nombre sobre una vida
que responde con sus hechos y con palabras amigas.
Tiene que pertenecer, de alguna forma cualquiera,
a un grupo de pensamiento, a una secta religiosa,
a determinada clase de una sociedad obsesa
por difinirse a sí misma sin comprenderse siquiera.

Abogo por un resquicio en la maraña de listas
para el ser que no se enrole en ninguna de sus filas.
Bastaría con abrir, en una carpeta nueva,
un expediente que diga: inclasificados, fuera.
Aunque también es verdad que está resuelto el problema:
se les llama marginados y después se les ignora.

Es bueno que siempre haya alguien que en nada encaje.
También habrá que mirar desde fuera el engranaje.

Publicado en Versos | Deja un comentario

Instalar Drupal 7 (y en español)

Lo básico no tiene ningún misterio: Preparas tu base de datos MySQL, anotas el nombre del usuario y la contraseña, descomprimes el paquete de Drupal 7, que puedes descargar de aquí, lo subes y entras a tu sitio por la url para empezar la instalación. Sobre lo básico hay mucha información en la Red.

Pero pueden surgir un par de problemillas que desde aquí vamos a tratar de ayudarte a solucionar y que son el motivo principal de esta entrada: uno es configurarlo para el idioma español y el otro un mensaje de error que puede dar una vez instalado, diciendo que no puede guardar unos archivos en sites/default/files/tmp.

Instalando en español

Una vez que hayas subido el core y antes de empezar la instalación propiamente dicha, tienes que descargar el archivo de la traducción de aquí (al menos a la fecha en que escribo esto). Pincha en el “Download” que hay a continuación del “Drupal core 7.0″ y en la misma línea. Súbelo a la carpeta profiles/standard/translations y ya está todo listo para que te presente la opción de instalar en español.

Hay que tener presente que, cuando la instalación llegue a “Configurar traducciones” puede que se quede ahí “pillada”. En local no me lo ha hecho, pero en remoto sí. Si se queda, pues nada, a prepararse tranquilamente una infusión dándole su tiempo, y después recargar la página e ir al enlace de la página de error. A mí me funcionó, así que lo mismo a tí también. El motivo de este “parón” parece ser algo relacionado con la tecnología AJAX.

El mensaje de error relativo a tmp

Esto puede ocurrir porque drupal 7 necesita no sólo acceso total a las carpetas sites/default/files y sites/default/files/tmp, sino que el propietario y el grupo de las mismas sean los “del dueño del sitio y su grupo”, o como un ejemplo vale más que mil palabras, el mismo usuario y grupo que tenga el archivo sites/default/default.settings.php. Como yo tengo acceso root al servidor, pues cambio lo que me da la gana como quiero sin problemas, pero una posible solución para quienes no son tan pringados afortunados puede ser la que sugiero a continuación. De todas formas, ten presente que el objetivo es conseguir que sites/default/files y sites/default/files/tmp tengan permisos 777 (totales) y pertenezcan al usuario y al grupo que dijimos.

La solución  sugerida es entrar por ftp a nuestro sitio y crear estas carpetas antes de que las cree el propio Drupal (es decir, antes de ir a nuestra url para empezar la instalación), con lo que ya pertenecerán directamente al usuario y grupo adecuados. No nos olvidemos de darles los permisos.

Luego copiamos el archivo sites/default/default.settings.php con el nombre sites/default/settings.php y le damos permisos 666 para la instalación (más tarde habrá que reponer los permisos de ese archivo a 644, cosa de la que nos avisará el propio drupal).

Resumen de comandos a utilizar una vez que hemos subido todos los archivos de Drupal 7  y antes de ir a nuestra url (suponemos que ya estamos dentro de la carpeta raíz de nuestra instalación):

cd sites/default
cp default.settings.php settings.php
chmod 666 settings.php
mkdir -p files/tmp
chmod 777 files
chmod 777 files/tmp

Ahora entramos a nuestra url, realizamos la instalación y, cuando haya terminado:

chmod 644 settings.php

Y esto es todo, rapidito y práctico, para no entretener demasiado al personal.

Publicado en GNU/Linux | 1 comentario

Mi proyecto

Mi proyecto de software consiste en una aplicación de gestión para empresas. Si servirá sólamente para las pymes o también para alguna algo mayor ya se verá en su día, espero.

Hace mucho tiempo que lo empecé, pero como la programación no es la actividad con la que me gano la vida, sino una afición que me ha ido enganchando a fuerza de tratar con ordenadores desde que tenían monitores de fósforo verde y 64 ks (sí, kilobytes) de RAM, pues no he podido dedicarle todo el tiempo que me hubiese gustado. Cuando todavía la universidad de mi pueblo no tenía aula de informática, yo ya estaba programando en COBOL otro programa de gestión y peleándome con una cosa llamada “GWbasic” para conseguir algún rendimiento extra en mis tareas diarias de manejar cuentas y más cuentas, entre albaranes, resúmenes de albaranes y facturas.

Lo que me gustaría conseguir con Gesfaconta es plasmar mi experiencia laboral de muchos años como algo que ahora se llama Administrativo-Contable. Pero como no me va la vida en ello, me lo tomo con tranquilidad porque a mis años el estrés no es muy recomendable. Ahora parece que vislumbro en lontananza una posiblidad de darle un empujoncillo durante este año de 2011. Ojalá pudiera, y que ustedes lo vean.

Se llama Gesfaconta (gestión, facturación y contabilidad) y está alojado en Sourceforge. Si tienes curiosidad por ver qué hace (que de momento es muy poco) puedes descargarlo, pero necesitas tener instalado Subversion en tu sistema, ya sea como herramienta gráfica o directamente en modo texto, que es como la uso yo en mi Debian Testing de toda la vida.

Para descargar los fuentes sólo hay que hacer, en modo texto:

svn co https://gesfaconta.svn.sourceforge.net/svnroot/gesfaconta/trunk gesfaconta 

Luego hay que entrar a la nueva carpeta llamada “gesfaconta” que se habrá creado, y ejecutar los siguientes comandos:

~$ ./autogen.sh
~$ ./configure
~$ make

A continuación nos podemos conectar como root para instalar o utilizar sudo, según la configuración de cada distro:

~# make install (o ~$ sudo make install)

y luego hay que leerse atentamente el archivo README, donde se explica con detalle qué hay que hacer para echarlo a andar.

También tiene un manual pdf en construcción (como todo el proyecto) que se cargará pulsando la tecla F1 nada más abrirse la primera ventana, la de login, ya que ni siquiera hace falta conectarse a la base de datos para poder verlo.

Publicado en Gesfaconta | Deja un comentario