Charlas informales de GNOME Chile: automake/autoconf

Relator: Germán Poo Caamaño (invierno)
Contraparte: Juan Carlos Inostroza (jci)
Domingo 15 de diciembre de 2002, 02:06 horas CLST
irc.gnome.cl #gnome

invierno
jci: me perdi con tu sugerencia
que paso?
jci
naa
que al libro de gnome le falta algo asi como 
un uso rapido de autoconf y demases para programacion en gnome
invierno
alguien tiene que hacerlo
:-)
jci
halley dijo usar anjuta o glade, pero la idea es no depender de eso
:-)
en too caso, si supiera, me mando un capitulo jejejejej
invierno
http://www.gtk.org/faq/#AEN424

jci
grax
invierno
de todas formas, le falta un poco, pero esta bien
mira el configure.in de un proyecto chico
jci
jejeje
en eso estoy
invierno
veamos si sale algo interesante
a saber
en desarrollo normalmente se utiliza un script llamado autogen.sh
que se encarga de ejecutar aclocal, autoheader, autoconf y automake
jci
yeps, si asi lo he visto cuando trabajo con anjuta
invierno
ademas de eso, cuando se genera el script configure, lo ejecuta
ese script, autogen.sh puede ser cualquiera
jci
yeps
cuando bajo algunas cuestiones del cvs viene ese juguete :-)
invierno
para gnome2 existe uno que normalmente se copia de proyecto en proyecto

pero cada uno lo modifica a su antojo
cuando bajas un tar.gz el autogen.sh no viene
sino que el configure viene listo
anatomia de una fuente.tar.gz:
esta compuesto por el script configure
y un conjunto de archivo terminados en .in
Makefile.in principalmente
jci
yeps
invierno
a partir del cual se generaran los correspondientes Makefiles
jci
eso lo vi en el linux programming unleashed
invierno
eso scripts nunca los toca el desarrollador
y se generan despues de ejecutar "make distcheck"
antatomia de un fuente de CVS:
el fuerte se compone por los archivos:
autogen.sh, configure.in y Makefile.am
los 2 primeros existen en el raiz del proyecto
halley
que es un overlap
invierno
Makefile.am existe uno en cada directorio
que se utiliza en el proyecto
el Makefile.am es bien pequeño, a partir del cual se genera el Makefile.in
 y posteriormente el Makefile
ese proceso se hace con automake (de ahi la extension .am)
que mas podria decir?
analicemos el configure de un proyecto
quiero decir, el configure.in
jci
hmmm
algunas de las macros las entiendo
solo que no me he puesto a cachurear las macros que son exclusivas de gnome

--> Dr_Neo (~Power_of_@irc.cl-339408.terra.cl) ha ingresado en #gnome
<-- Dr_Neo (~Power_of_@irc.cl-339408.terra.cl) ha salido de #gnome
invierno
son muy pocas las que corresponden a GNOME
por ejemplo:
estoy viendo el de gturing
y tambien el de gnome-network
AC_PREREQ(2.52)
eso indica, que se necesita la version 2.52 o superior de autoconf
esto es, puedes tener distintas versiones de autoconf instaladas
pero en tu proyecto podrias utilizar macros mas avanzadas (o reparadas)

y asi, autoconf sabra cual llamar
AC_INIT([gturing],[0.1.1],[gpoo@ubiobio.cl])
eso indica el nombre del paquete, la version y, opcionalmente, el autor

a partir de esto se pueden añadir una serie de #define
jci
jejeej
invierno
por ejemplo, esa linea quedara asi en el config.h
#define PACKAGE "gturing"
#define VERSION "0.1.1"
entonces, en tu programa fuente
colocas:
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
y ya tienes esos #define del configure.in
halley
una ves vi un configure que decia cheking for a free radiation enviroment.....ok

invierno
esas dos tipicamente se usan para registrar el nombre del programa
por ejemplo, en el programa principal:
jci
:-)
* invierno cerrando las ventanas, que entran los zancudos
<-- jrami ha salido (Quit: [BX] Gary Coleman uses BitchX. Whatchoo talkin bout foo?)
invierno
 program =
     gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE,
    argc, argv, GNOME_PARAM_POPT_TABLE,
    gturing_options, 
    GNOME_PARAM_APP_DATADIR, DATADIR,
    GNOME_PARAM_NONE);
si te das cuenta, los 2 primeros parametros son PACKAGE y VERSION
halley: se pueden añadir todos los chequeos que quieras :-)
halley
onda cheking for a  free kde enviroment
invierno
halley: si
bueno
luego tenemos:
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME,[0.1.1])
similar al AC_INIT
notar las 2 primeras letras de las macros
AC_ ==> autoconf y AM_ ==> automake
es decir, esta inicializa automake
AC_PACKAGE_NAME es una variable, que en este definimos en AC_INIT
el primer parametro
se supone que el segundo pudo ser AC_VERSION
pero autoconf y automake no estan libres de errores
y es un detalle menor
AM_CONFIG_HEADER(config.h)
es el archivo de configuracion
donde quedan los define
eso mas o menos es estándar
jci
jejeje
invierno
lo que hay que tener en claro, es entre versión y versión
las macros cambian
jci
pero una consulta german
invierno
por ejemplo, aceptan mas o menos parámetros
jci: dime
jci
la idea es que las macros de autoconf para gnome esten documentadas...como
 las de autoconf
ah retiro la pregunta entonces :-(
eso mismo que dijiste
que entre version y version he visto que algunas macros no eran las mismas

invierno
no es que no sean las mismas
jci
o sea, son las mismas, solo que cambian la cantidad de parametros y esas
 cosas
invierno
por ejemplo, AC_DEFINE_UNQUOTED ahora pide mas argumentos
pero sigue haciendo lo mismo
cuando se ejecuta, envia un warning
y te dice como solucionarlo
jci
no sep, quizas es carril, pero he visto que muchas de las macros de autoconf
 puras son exactamente las mismas para versiones antiguas
invierno
jci: depende
jci
ah
:-)
invierno
como te digo, las macros de GNOME son pocas
de hecho, hasta ahora no he mencionado ninguna macro de GNOME
jci
solamente de AC
pingu
OT a cuanto esta el euro con relacion al dolar ?
invierno
y AM
1 a 1
luego tenemos:
AM_MAINTAINER_MODE
modo mantención
alguna vez lo leí
jci
pingu: creo que 3 euros es un dolar
invierno
básicamente añade flags -Werror cuando se hace make distcheck
jci
creo :\
tella.cl
:-)
(ballo sin agua)
invierno
jci: te cambio unos dolares por euros
la relación es 1 a 1
pingu
okis
jci
:-)
no cacho a cuanto estaba el cambio, toy intoxicated with caffeine
:-)
invierno
un detalle, antes de continuar
como son macros M4 hay que ser muy cuidadoso con los espacios y tabuladores

estos ultimos hay que evitarlos
asi:
AC_PROG_INTLTOOL$
es distinto a
jci
los tabuladores o los espacios?
invierno
AC_PROG_INTLTOOL $
el $ es el fin de línea
que obviamente no va
pero ese espacio es interpretado y fallara
en el segundo caso
los tabuladores hay que evitar
bueno, esa macro indica que queremos usar intltool
intltool es la que permite trabajar con internacionalizacion
jci
ajap
invierno
intltool son un conjunto de scripts en Perl que facilitan la vida
se usa en conjunto con:
AM_GLIB_GNU_GETTEXT
es decir, trabajermos con gettext
gettext tiene una macro reducida llama _()
si alguna vez la han visto
_("My string")
jci
yeps, la explicaste en la charla de curico
invierno
gettext permite extraer esos textos y dejarlos en un archivo aparte
jci
pero no recuerdo que funcion era la que no funciono
<-- wes ha salido (Quit: [BX] With a BitchX here and a BitchX there, here a BitchX there a BitchX everywhere a BitchX)
invierno
para que puedan ser traducidos posteriormente
GETTEXT_PACKAGE=gturing-2.0
eso, es simplemente una definicion de una variable
como es una definicion nuestra
necesitamos decirle que la haga visible:
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[The gettext package])

--> Dr_Neo (~Power_of_@irc.cl-339408.terra.cl) ha ingresado en #gnome
jci
okas
ahhh
invierno
AC_DEFINE_UNQUOTED pondra caracteres de escape cuando reemplace el texto

en el fondo dice:
GETTEXT_PACKAGE definalo con el contenido de "$GETTEXT_PACKAGE"
que lo indicamos mas arriba
y el mensaje por pantalla será:
jci
ahhh
<-- Dr_Neo (~Power_of_@irc.cl-339408.terra.cl) ha salido de #gnome
invierno
The gettext package
jci
ahhhh
:-)
invierno
en el config.h quedará así:
#define ENABLE_NLS 1
#define HAVE_GETTEXT 1
#define GETTEXT_PACKAGE "gturing-2.0"
jci
aaahhhh
una consulta german
invierno
y en nuestro programa principal:
#ifdef ENABLE_NLS
bindtextdomain (GETTEXT_PACKAGE, GTURING_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 textdomain (GETTEXT_PACKAGE);
#endif
jci
ah 
invierno
el GETTEXT_PACKAGE ya sabemos de donde sale
jci
justamente era esa mi pregunta :-)
invierno
del config.h que se genero a partir del configure.in
el GTURING_LOCALDIR no es mágico
jci
y la plantilla del config.h supngo que sale del config.h.in o no? :-)
invierno
por ahí dice:
-DGTURING_LOCALEDIR=\""$(datadir)/locale"\" 
que quiere decir, el directorio donde deberá buscar las cadenas de textos

típicamente las traducciones
de acuerdo a la variable LANG, LC_ALL, etc.
jci: si
pero el config.in no pertenece al proyecto
tambien se genera en forma automatica
jci
ah
invierno
configure.in -> config.h.in -> config.h
jci
ah okas
invierno
aunque configure.in es mucho mas que config.h.in
jci
yeps
el config.h.in es mas una plantilla
el configure.in es otra cosa distinta
invierno
si
jci
jejeje
:-)
invierno
con el configure.in + una plantilla estándar, se genera otra plantilla
 (config.h.in)
que es dependiente de las opciones que definiste en el configure.in
es decir, una plantilla personalizada
jci
de re pente me he pillado con algunos .in.in
invierno
jci: si, en el directorio po/
la otra variable que se usa en internacionalizacion es:
ALL_LINGUAS="ca cs da de es fr ga"
e indica que idomas se encuentran las traducciones
jci
ahhh
jejeje
invierno
es conveniente colocarlas en orden alfábetico
si quieres añadir un nuevo idioma, simplemente colocas el nombre de la
 traduccion
halley
http://www.linuxjournal.com/article.php?sid=6176

jci
es necesario que esten en orden alfabetico?
invierno
ojo, esto hará que el programa verifique que los archivos
halley
ese para las traducciones
--> JuanCri (Enasdo@irc.cl-427014.surnet.cl) ha ingresado en #gnome
<-- JuanCri ha salido (Client exited)
invierno
ca.po cs.po da.po etc
existan dentro del directorio po
hay que recordar
que aclocal y no solo define
sino que busca si los programas necesarios estan instalados
y donde estan instalados
asi por ejemplo
si colocamos AC_PROG_INTLTOOL
e intltool no está instalado, hasta allí no mas llega el script
el ./configure fallará
lo cual es la idea
indicar por qué ha fallado
que otras macros van casi siempre:
AM_PROG_LIBTOOL
si queremos verificar la existencia de libtool
jci
ahhh
invierno
       The  `libtool'  program provides a standard way to generate both
 static
       and shared libraries.  It hides the complexities  of  platform-specific

       library  generation  behind  an  interface  that is the same across
 all
       platforms supported by libtool.
jci
eso hace un chequeo solamente?
invierno
si, verifica que existan para que se use :-)
jci
ahhh
:-)
invierno
AC_ISC_POSIX
no me la se :-) pero tiene algo que ver con POSIX :-)
AC_PROG_CC
nuestro programa esta en C, asi que requerimos lo necesario para compilar
 en C
jci
ah okas
invierno
AC_STDC_HEADERS
verificamos los headers (include) estandares
jci
jejeje
invierno
GNOME_PLATFORM_GNOME_2(yes, force)
jci
la mayoria de las macros de AC vienen en el LPU
<-- wheezy ha salido (Quit: [BX] Size DOES matter)
invierno
esa es una macro de GNOME
ahora bien
puede ser que nuestro programa requiera de alguna biblioteca en particular

por ejemplo, que esten las definiciones de limits.h
entonces le pedimos que lo verifique:
AC_CHECK_HEADER(limits.h)
jci
pero eso solo chequea que este en <prefix>/include?
o en algun path especifico?
invierno
en las rutas estandares
/usr/include
jci
ah okas
invierno
AC_CHECK_HEADERS(db_185.h db.h)
que verificará?
jci
:-)
invierno
que existan los encabezados db_185.h y db.h
jci
jejeje
invierno
ahora bien
puede ser que los encabezados esos se encuentren en otro lugar
porque quizas se instalaron en un directorio del usuario que los compilo
 a mano, etc.
para eso se utiliza el parámetro --includedir=DIR       C header files
 [PREFIX/include]
en el configure
que viene de manera automatica
ojo, aclocal, automake, no verifican, solo añaden comandos
que permitiran que ./configure verifique
ese el que hace la pega
jci
aahhhh
eso eso eso 
es lo que no cachaba
invierno
el configure.in es para decirlo como tiene que hacer el script configure

AC_CHECK_TYPE(umode_t, mode_t)
jci
alguien me alego no recuerdo donde 
que el configure.in no era lenguaje de macros :-\
invierno
eso te permitirá saber si existen esos tipos
jci
ac_check_type chequea los tipos de datos que existan?
ah...okas
invierno
con es un lenguaje, está escrito con macros
jci
:-)
invierno
s/con/no/
jci
ah eso eso
invierno
tambien podemos definir algunas variables extras
por ejemplo, para utilizar en nuestros Makefiles
por ejemplo:
DISABLE_DEPRECATED_CFLAGS=" \
    -DG_DISABLE_DEPRECATED \
    -DGDK_DISABLE_DEPRECATED \
    -DGDK_PIXBUF_DISABLE_DEPRECATED \
    -DGTK_DISABLE_DEPRECATED \
    -DGNOME_DISABLE_DEPRECATED \
    -DBONOBO_DISABLE_DEPRECATED"
eso son espacios
y el \ es para indicar que continua en la linea siguiente
jci
yeps
invierno
esas son definiciones para asegurarse que el programa no existen funciones
 declaradas "deprecated"
es decir, que ya no se recomiendan
por ejemplo:
gtk_signal_connect y g_signal_connet
gtk_signal_connect y g_signal_connect
la primera se usaba en GTK+ 1.2, pero ahora es deprecated
jci
gtk_signal_connect esta deprecada para gtk2, cierto?
pfff
invierno
y se recomienda usar g_signal_connect
jci
proxima pregunta muero piola mejor
invierno
por el movimiento de objetos que hay entre una version y otra
si bien es cierto, gtk_signal_connect aun existe en gtk 2.0
no se recomienda
jci
pero recomiendan no usarla
oye german 
una consulta
salio hace poco el lanzamiento de gnome 2.1.3
invierno
entonces, si quieres asegurarte que tu programa está completamente portado
 a GNOME 2
le indicas las definiones anteriors
jci
ah
invierno
así cuando compiles tu programa 
y el compilador encuentre un gtk_signal_connect, reclamará que esa funcion
 no existe
jci
y me di cuenta que agregaron hartas cosas, pero le sacaron cuestiones a
 nautilus (por ejemplo)
invierno
estás atrasad jci, ya va en 2.1.4
jci
ah jejejeje
tonces lo dejo bajando mañana :-)
pero no sep...
invierno
hay muchas cosas que se dieron cuenta que estaban mal
jci
el 2.1.2 y 2.1.3 siempre vive cayendo el panel
si el unico que me ha andado bien es el 2.0.2
invierno
por ejemplo, el manejo de objetos es independiente de la interfaz grafica

jci
yeps, eso sip
invierno
entonces, si quieres construir tus programas para consola
y quietes objetos en C, antes tenias que enlazar contra gtk+
lo cual es una tonteria
entonces, se movio el sistema de objetos a glib
jci
ahhh
invierno
para facilitar la migracion
las funciones se declaran deprecated
jci
ahhh
weno, conclusion
gnome 2.1.3 no me gusto :-(
invierno
eso significa que para el siguiente gran release (2.2 por ejemplo) estaran
 obsoletas
jci
eso
invierno
es decir, ya no se encontraran
jci
cuando se supondria que saldria el proximo release de 2.2?
invierno
enero en el calendario
jci
por que el movimiento que estan haciendo es como radical
invierno
no
jci
en algunas cosas, como fue nautilus
lo dejaron pelaito pa 2.1.3 :-)
no tiene tantos chiches como antes
invierno
limpieza, pero sigamos con configure
jci
okas
dele no mas profe :-)
invierno
luego
existe pkg-config
jci
yeps
invierno
el que permite buscar las bibliotecas y cabaceras de los programas que
 queremos instalar
jci
que se supone reemplaza a todas las bestias de gnome1.x, cierto?
gnome-config, orbit-config y varios?
invierno
si
jci
ah
en realidad, es harto mas facil
invierno
en todo caso, cada programa sigue trayendo sus propios scripts de configuracion

pero si tienes pkg-config, mejor usas eso
para utilizar pkg-config
jci
cierto
invierno
simplemente usas la macro:
PKG_CHECK_MODULES(GTURING, libgnomeui-2.0)
que en este caso, verificará si libgnomeui-2.0 se encuentra entre los modulos
 de pkg-config
es el equivalente a:
jci
ah okas
invierno
pkg-config --cflags libgnomeui-2.0
pero solo como ejemplo, porque en estricto rigor:
se deben declarar:
AC_SUBST(GTURING_CFLAGS)
AC_SUBST(GTURING_LIBS)
si te das cuenta
GTURING_
el primero es el nombre de la variable de verificacion de PKG_CHECK_MODULES

y automaticamente define VARIABLE_CFLAGS y VARIABLE_LIBS
y asi, podemos definir otras:
PKG_CHECK_MODULES(GNETWORK, libgnomeui-2.0 libgnome-2.0 gtk+-2.0 glib-2.0
 libglade-2.0)
AC_SUBST(GNETWORK_CFLAGS)
AC_SUBST(GNETWORK_LIBS)
la idea es la misma
solo que ahora verifica por mas paquetes
jci
ahhh
esa las lei recien en gtktalog
invierno
innecesario a decir verdad, porque libgnomeui-2.0 incluye a las otras,
 con excepcion de libglade-2.0
jci
osea
invierno
hubiera bastado con:
jci
eso
:-)
invierno
PKG_CHECK_MODULES(GNETWORK, libgnomeui-2.0 libglade-2.0)
AC_SUBST(GNETWORK_LIBS)
AC_SUBST(GNETWORK_CFLAGS)
ojo, vayan recordando las variables que hemos guardado, porque luego las
 usaremos
si se dan cuenta
AC_CHECK_HEADER(limits.h)
verifica que exista 
pero en ocasiones podemos querer que compile igual el programa
pero con o sin alguna opcion especial
por ejemplo:
AM_CONDITIONAL(HAVE_LIBZVT, test "x$have_zvt" = "xyes")
si se encuentra LIBZVT entonces haga lo que tenga que hacer
sino, no importa, no se incluye ese modulo
se entiende?
jci
yeah
invierno
para explicar un poco mas
puedo tener un programa que tiene interfaz ncurses y gtk+
si no es encuentra instalado gtk+, entonces solo compilo la interfaz ncurses

si estan instalados los 2, entonces compilo los 2
aun así, en esa macro hay cosas medio nebulosas
voy a escribirlo completo:
PKG_CHECK_MODULES(ZVT, libzvt-2.0, have_zvt=yes, have_zvt=no)
AM_CONDITIONAL(HAVE_LIBZVT, test "x$have_zvt" = "xyes")
AC_SUBST(ZVT_CFLAGS)
AC_SUBST(ZVT_LIBS)
jci
hmmm
invierno
si se dan cuenta, estou empleando 4 parámetros en la macro PKG_CHECK_MODULES

los 2 ultimos son opcionales
<-- halley ha salido (Quit: ipv6.ubiobio.cl)
halley
shau monos
invierno
el tercer argumento es "realizar una acción en caso de ser afirmativo"

se encuentra libzvt-2.0 en este caso
y define la variable have_zvt=yes
de la misma forma que se hace en el shell
jci
con un case supongo
invierno
no
simplemente la asigna
jci
ah okas
--> Muad-Dib (eric@irc.cl-316518.terra.cl) ha ingresado en #gnome
--- vmlinuz fija modos [#gnome +o Muad-Dib]
invierno
comprueba, si se encuentra ==> have_zvt=yes, sino have_zvt=no
pero eso no es suficiente
en alguna parte de nuestro programa queremos algo coo
 if HAVE_VFSMODULE
 if HAVE_HAVE_LIBZVT
eso era, error en el copy/paste
pero para poder hacer eso, tenemos que tener definido  HAVE_LIBZVT
con un valor de verdad
eso se declara con:
AM_CONDITIONAL(HAVE_LIBZVT, test "x$have_zvt" = "xyes")
jci
jjeje
invierno
eso es un vulgar "test" que existe en el shell
jci
ah
invierno
aqui hay un truco
la comparacion debiera ser:
test "$have_zvt" = "yes"
eso devuelve un valor de verdad
pero:
si por A, B o C motivo, $have_zvt no estuviera definido
habrá un error
porque no es posible comparar:
jci
ahhhh
invierno
"" con "yes"
jci
:-)
invierno
entonces se le añade algo comun en ambos lados
 test "x$have_zvt" = "xyes"
es decir, se asegura en al menos habrá una letra en cada lado
jci
aahhh
por eso el x
invierno
donde el lado peligroso es donde está la variable
jci
que pille hoy
Muad-Dib
holñas
invierno
claro que pensandolo bien
en este caso pareciera medio rebuscado
ya que PKG_CHECK_MODULES lo define en ambos caso (si y no)
jci
...
invierno
pero pongamos un ejemplo mas entretenido
queremos verificar si el programa ping se encuentra instalado y en donde

y nos interesa tener guardado el lugar donde se encuentra
así, en nuestro programa podremos llamarlo así:
gchar *cmd = PING_PROGRAM;
puede ser que ping, se encuentre instalado cualquier parte
y tal vez no este en la ruta definida en el ambiente del usuario que lo
 compila
entonces, queremos darle la opcion al usuario para que pueda ingresarlo

tipicamente con --with-ping=/opt/bin/ping
jci
...
invierno
o algo asi
se entiende lo que queremos hacer?
jci
yeps
invierno
entonces manos a la obra:
jci
en caso que el configure no lo pille automaticamente
invierno
claro
AC_ARG_WITH(ping, [  --with-ping=PATH  Where ping is.])
eso creara la opcion en el configure
jci
yeps
invierno
si se ejecuta ./configure --help aparecerá
en alguna parte:
  --with-ping=PATH  Where ping is.
jci
--with-ping algo
ah jejejeje
y una consulta
invierno
es decir, el usuario podrá llamarlo como:
jci
como el configure --help aparece tabulado
invierno
./configure --with-ping=/home/usuario/bin/ping
jci
o es automagico el tabulado?
invierno
jci: el primer parámetro si
jci
ah okas
invierno
el contenido no, en mi caso
Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)

  --with-gnu-ld           assume the C compiler uses GNU ld default=no

  --with-pic              try to use only PIC/non-PIC objects default=use
 both
  --with-ping=PATH  Where ping is.
es algo que debo analizar, pero no me quita el sueño
<-- Muad-Dib ha salido (Quit: Client Exiting)
jci
jejeejej
okas
no prob
con tal que se vea :-)
invierno
AC_ARG_WITH(ping, [  --with-ping=PATH  Where ping is.])
alli estabamos
jci
yeps
invierno
tenemos 2 argumentos
el segundo es el comando
que aparecera en la ayuda
quise decir:
el segundo es la ayuda del comando que aparecerá
jci
okas
invierno
el primero es el nombre de la variable
pero no es cualquier nombre, es del tipo
with_ping
jci
okas
invierno
así, si hubieramos colocado:
AC_ARG_WITH(chanchito, [  --with-ping=PATH  Where ping is.])
para saber su valor, debieramos preguntar por with_chanchito
pero como es una variable, como $with_chanchito
que es lo que haremos ahora:
jci
ah okas
invierno
determinar si el usuario agregó algo:
he aquí el truco nuevamente:
if test "x$with_ping" = "x" ; then
esto es shell
y lo que preguntamos: "el usuario *NO* ingresó nada"
para que sea verdad, $with_ping debe ser vació
vacío
sólo en ese caso "x$with_ping" será igual a "x"
jci
ahh
verdad
invierno
ahora se nota la utilidad del truco
jci
por que es medio complejo comparar valores vacios
de ahi el uso de la x
invierno
entonces
si el usuario no ingreso eso, trataremos de buscarlo
 AC_PATH_PROG(PING_PROGRAM, 
  ping,,
  $PATH:/usr/etc:/usr/sbin)
jci
ahhh
invierno
lo que hace, es buscar un programa en la ruta
jci
pero esa var $PATH
es la variable de ambiente PATH?
invierno
para ello utilizará PING_PROGRAM para dejar el valor
si, es del ambiente
ping es el programa a buscar
jci
ah...
invierno
el tercer argumento está vació, y es por si queremos dejar algo allí en
 caso que sea falsa la búsqueda
y el último parámetro es la ruta donde buscar
jci
ah okas
invierno
podría estar vacía también, y en ese caso solo buscará en el PATH
jci
ahhh
invierno
pero aquí añadí otros 2 directorios
algunos Unix tiene algunos de estos ejecutables bajo /usr/etc
jci
ah okas
invierno
o bien /usr/sbin, que normalmente no se encuentra en la ruta de todos los
 usuarios
luego,
debemos verificar que PING_PROGRAM tiene algun valor
es decir, saber como le fue en la busqueda a AC_PATH_PROG
y que hacemos?
if test "x$PING_PROGRAM" != "x" ; then
jci
aahhhhhh
invierno
PING_PROGRAM puede tener cualquier cosa
jci
poblamos la variable
invierno
no sabemos como
jci
ping_program
o no?
:-\
invierno
si, tenemos que poblarla
o mas bien, declarar el #define correspondiente en config.h
jci
aahhh
eso, eso
invierno
es decir
if test "x$PING_PROGRAM" != "x" ; then
verifica si PING_PROGRAM tiene algun valor
porque se pide que sea != "x"
jci
yeps
--> denys (denys@irc.cl-362436.terra.cl) ha ingresado en #gnome
invierno
    AC_DEFINE_UNQUOTED(PING_PROGRAM, "$PING_PROGRAM", [The ping program])


y en nuestro config.h aparecerá:
#define PING_PROGRAM "/bin/ping"
jci
#define PING_....
eso, eso
:-=
:-)
invierno
no está completo:
jci
una consulta
invierno
 /* The ping program */
#define PING_PROGRAM "/bin/ping"
jci
antes de seguir
invierno
es que xchat interpretó el /
jci
si la macro es UNQUOTED
por que aparece con comillas en el define? :-)
invierno
quiere decir lo siguiente:
que pasa si la valor de la variable es:
/bin/"ping?
quedaría mal el define
#define PING_PROGRAM "/bin/"ping"
jci
aaahhh
okas
invierno
lo cual es un error de sintaxis
jci
o sea
invierno
eso el unquoted es para que se preocupe de eso
jci
el resultado de ac_define_unquoted es sacar las comillas del resultado

:-)
invierno
finalmente quedará así:
AC_ARG_WITH(ping, [  --with-ping=PATH  Where ping is.])
if test "x$with_ping" = "x" ; then
       AC_PATH_PROG(PING_PROGRAM,
       ping,,
       $PATH:/usr/etc:/usr/sbin)
       if test "x$PING_PROGRAM" != "x" ; then
            AC_DEFINE_UNQUOTED(PING_PROGRAM, "$PING_PROGRAM", [The ping
 program])
       fi
jci
jejeje
<-- pingu ha salido (Ping timeout: 180 seconds)
* ReX is back (gone 02:39:18)
invierno
else
       AC_DEFINE_UNQUOTED(PING_PROGRAM, "$with_ping", [The ping program])



fi
AM_CONDITIONAL(HAVE_PING, test "x$PING_PROGRAM" != "x")
ojo:
en el else va:
       AC_DEFINE_UNQUOTED(PING_PROGRAM, "$with_ping", [The ping program])


eso es
jci
eso
ya como que entiendo el autoconf
invierno
en el caso que el usuario *SI* haya colocado --with-ping=/blah/bhal/ping

jci
grax german :-)
invierno
dejame terminar
que estoy inspirado
jci
okas, okas
ReX
hi
jci
hiz
invierno
te imaginaras para que es el:
AM_CONDITIONAL(HAVE_PING, test "x$PING_PROGRAM" != "x")
define HAVE_PING para poder preguntar posteriormente
si hay ping, se compila el modulo que analiza el ping
jci
yeps
ReX
uff, mis vecinos tienen una fiesta, y tienen sus cumbias a toda raja hahah

invierno
de lo contrario, construye el resto
ReX
me voy a acostar en otra pieza toi cachando
invierno
falta lo importante:
AC_CONFIG_FILES([
Makefile
po/Makefile.in
src/Makefile
pixmaps/Makefile
tapes/Makefile
help/Makefile
help/C/Makefile
])
eso es lo que finalmente construye
jci
ah okas
invierno
construye el Makefile en el directorio rail del proyecto
los los Makefiles de los otros directorios
jci
yo cacho que de aqui cuando me desconecte, de cabeza a GNU Autoconf, Automake
 y Libtool
:-)
invierno
si te das cuenta, en po/ hay un Makefile.in
jci
yeps
invierno
es decir, lo crea a partir de Makefile.in.in
los otros los crea a partir de un Makefile.in y estos se crean a partir
 de un Makefile.am
jci
jeje
invierno
opcionalmente podemos terminar con la siguiente macro:
AC_OUTPUT
echo "
Configuration:
    Source code location:   ${srcdir}
    Compiler:       ${CC} 
 Flags: ${CFLAGS}
"
jci
ah
invierno
que nos permite imprimir por pantalla cualquier cosa
jci
para mostrar las opciones 
o cualquier otro cachibache
invierno
en este caso para decirle al usuario que opciones finalmente se usaran

pero perfectamente podria ser:
echo "
jci
que no muchos configure muestran :-)
invierno
Esta es una version de desarrollo, no la use sino sabe lo que hace
"
no es obligacion hacerlo
jci
ah okas
invierno
ya vimos el configure.in
queda la anatomia de Makefile.am
que es mas pequeño
por ejemplo:
SUBDIRS = pixmaps tapes po src help
eso indica que tiene que hacer Make
make
en esos subdirectorios
tipicamente aparece:
"Entering to ..."
y luego....
"Leaving ..."
cuando uno ejecuta make
eso de saber a donde entrar, lo saca de ahí
un error que uno comete siempre cuando parte es
jci
ah...
invierno
pensar que con colocarlo en AC_CONFIG_FILES es suficiente
y no es así
lo unico que hace esa macro, es que configure creará los Makefiles correspondientes

en eso directorios
pero el Makefile.am principal no sabe a donde tiene que meterse, no lo
 hará
si al final, quien hace el trabajo es "make"
jci
jejej
invierno
si estamos en un directorio, como src, donde no hay subdirectorios
entonces se define vacío
SUBDIRS =
otras variables en el Makefile.am:
bin_PROGRAMS = gturing
eso es, como se llamará el ejecutable
jci
ah okas
invierno
es decir, cuando compile todo, el gcc dirá:
gcc -o gturing ....
jci
ah jejeje
invierno
la variable *TIENE* que llamarse bin_PROGRAMS
son estandares
jci
ah okas
invierno
otras cosas a definir:
INCLUDES = \
 -DGTURING_LOCALEDIR=\""$(datadir)/locale"\"  \
 @GTURING_CFLAGS@
jci
ah las arrobas
eso
invierno
oh! que encontramos acá
jci
jejeej
invierno
primero: -DGTURING_LOCALEDIR=\""$(datadir)/locale"\"
el que usamos magicamente al principio
cuando veiamos GETTEXT
jci
pa que voy a preguntar si ya viene la respuesta 
:-)
invierno
aqui está el define
y el @GTURING_CFLAGS@ de adonde salió?
PKG_CHECK_MODULES(GTURING, libgnomeui-2.0)
jci
jejejee
invierno
AC_SUBST(GTURING_CFLAGS)
jci
del configure :-)
invierno
de allí salió
cuando definimos esas variables
entonces, de lo que resulte de ejecutar:
pkg-config --cflags libgnomeui-2.0
tambien podriamos poner:
INCLUDES =    \
 -I$(includedir)  \
 -DGPING_LOCALEDIR=\""$(datadir)/locale"\" \
 -DDATADIR=\""$(dialogdir)/"\" \
 @GNETWORK_CFLAGS@
si se dan cuenta, son varios -D
que son equivalentes a #define en un programa
pero, que $(includedir) u $(datadir)?
jci
ah
invierno
no me lo van a creer
cuando ejecutan ./configure --help
jci
del configure?
invierno
por allí dice:
jci
--with-includes-dir?
invierno
  --datadir=DIR          read-only architecture-independent data [PREFIX/share]

  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]

  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
  --libdir=DIR           object code libraries [EPREFIX/lib]
  --includedir=DIR       C header files [PREFIX/include]
jci
eso
:-)
invierno
alli estan
jci
aaaahhhhhh
invierno
y tiene valores predeterminados
si no le colocan nada, probablemente será /usr/local/share (datadir)
jci
yeps
invierno
y /usr/local/include /(includedir)
jci
por que asume el prefix como /usr/local o no¿?
invierno
se puede cambiar en el configure
jci
yeps
invierno
cuando le das --prefix=
jci
--prefix 
:-)
invierno
pero se entiende que las compilaciones no van en /bin
jci
yeps
invierno
si lo vas a empaquetar si, pero sino, no son parte de la distro
jci
ah claro
invierno
y entramos a un plano mas filosófico del asunto
volvamos
jci
se supone que hay que construir un arbol falso cierto?
para lo que es empaquetamiento
invierno
cuando estas programando si
jci
okas
invierno
ahhh... si
jci
por que he visto en algunos rpms
invierno
con fakeroot se puede hacer en debian
jci
por ejemplo, que asume un RPM_ROOT 
ah 
invierno
si
jci
para eso era fakeroot!!!
no cachaba :-)
invierno
hay que tener algunos cuidados;
INCLUDES =    \
 -I$(includedir)  \
 -DGPING_LOCALEDIR=\""$(datadir)/locale"\" \
 -DDATADIR=\""$(dialogdir)/"\" \
 @GNETWORK_CFLAGS@
el @GNETWORK_CFLAGS@
debe ir al final
eventualmente podría ser *vacío*
y si está antes, podría dar un error en el Makefile
y el usuario estaría confundido, y no queremos eso
jci
ah okas
invierno
que mas tenemos:
gturing_LDADD = @GTURING_LIBS@
lo mismo
tambien pudo ser escrito como:
LDADD = $(GTURING_LIBS)
pero es mejor el primero
es mas propio del programa
un cuidado muy especial:
por qué se llama "gturing_LDADD" y no se llama "pepito_LDADD"?
porque en el configure.in pusimos:
AC_INIT([gturing],[0.1.1],[gpoo@ubiobio.cl])
jci
aaaaahhhhh
invierno
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME,[0.1.1])
entonces, le estamos diciendo que todo comenzará con
gturing_
nos damos cuenta que todo tiene relación
jci
aaahhh
:-)
invierno
y bien, nos falta lo mas importante
que queremos compilar?
gturing_SOURCES = \
 gturing.c \
 gturing.h \
 turing.h  \
 turing.c  \
 graph_editor.c \
 graph_editor.h \
 turing_table_editor.c \
 turing_table_editor.h
jci
ah
invierno
nuevamente gturing_
jci
los archivos de guentes
fuentes
invierno
exacto
jci
aahhh
invierno
y solito se encarga del resto
de alli toma los fuentes
jci
si quiero agregar un archivo mas, lo agrego ahi :-)
invierno
y finalmente lo transforma en gturing, de acuerdo a bin_PROGRAMS
jci
ah okas
invierno
jci, exacto
es mas
jci
ahhh
invierno
está hecho de tal forma, que si lo agregas al Makefile.am
y ya tiene el Makefile hecho,
al ejecutar 
$ make
automaticamente ejecutara automake
jci
jejejjee
o sea
invierno
volvera a construir el Makefile
jci
tiene su ciencia!
invierno
y luego compilarña
* jci mesmerized :-)
jci
ohhh
:-)
invierno
y no tienes para que ejecutar nuevamente ./autogen.sh ni ./configure nuevamente

jci
ah okas
invierno
lo hace por ti
cuando está bien hecho, eso si
jci
ah okas
invierno
tambien se pueden definir cosas extras
por ejemplo, es logico que el binario se instale
asi que bin_PROGRAMS es candidato a instalarse cuando se ejecute
make install
pero que sucede con las interfaces en glade?
son necesarias
igual que las imagenes o cualquier otra cosa que queramos que se instale

jci
okas
invierno
en gnome-netinfo defini lo siquiente:
dialogdir = $(datadir)/$(PACKAGE)/dialogs
dialog_DATA = gnome-netinfo.glade
ojo:
el "dialog" al principio es arbitrario
pudo ser:
pepitodir = ...
jci
ah 
okas
--> jrami (~jaime@eledificio.cl) ha ingresado en #gnome
invierno
pepito_DATA = ...
lo que buscara es a lo que esta antes de "dir" le buscara su pareja en
 "_DATA"
en este caso:
dialogdir = $(datadir)/$(PACKAGE)/dialogs
jci
ajap
invierno
si el prefix es /opt
se instalara en /opt/share/gnome-network/dialogs
jci
okas
invierno
por /opt/share es $(datadir)
gnome-netork es $(PACKAGE)
y dialogs, porque lo coloque en bruto allí
jci
jejeje
ReX
invierno: cual es la pagina con las listas de la ubb?
invierno
ReX: http://www.ubiobio.cl/mailman/listinfo

luego tenía:
dialog_DATA = gnome-netinfo.glade
alli puedo colocar mas archivos
jci
okas
aahhhh
:-)
invierno
que estarán relacionados a dialogdir
jci
los archivos donde sacar las interfaces ... 
:-)
invierno
si
por eso en:
INCLUDES =    \
 -I$(includedir)  \
 -DGPING_LOCALEDIR=\""$(datadir)/locale"\" \
 -DDATADIR=\""$(dialogdir)/"\" \
 @GNETWORK_CFLAGS@
hay un define que dice:
jci
eso es lo que siempre me complica...colocar los archivos
invierno
-DDATADIR=\""$(dialogdir)/"\" \
jci
ahh 
invierno
por que defino eso?
jci
pasando una variable para decir de donde sacar los archivos
:-)
invierno
en alguna parte del programa tengo:
const gchar *dialog = DATADIR "gnome-netinfo.glade";
es decir, *dialog apunta a "/opt/share/gnome-network/dialogs/gnome-netinfo.glade"

jci
jejejee
:-)
simple y clean
invierno
y siempre buscará en el lugar correcto de la instalación
eso tiene un contra, eso sí
si modifico la interfaz,
tengo que instalarla en ese directorio
de lo contrario el programa encontrará la antigua, se entiende?
jci
yeps
:-)
en realidad, eso era lo que me complicaba
invierno
que pasa si queremos monos?
pixmapdir    = $(datadir)/pixmaps
pixmap_DATA =
en este caso, no tengo imagenes
pero podria tenerlas y alli las colocare
jci
okas
invierno
y se instalaran en /opt/share/pixmaps
siempre que el prefix sea /opt como lo indique como ejemplo más arriba

pero, donde está la magia?
como en esto no hay magia, hay que definirlo:
jci
hmmm
invierno
EXTRA_DIST  = $(pixmap_DATA) gnome-netinfo.desktop \
     $(dialog_DATA)
EXTRA_DIST es para indicarle los archivos que son extras a los ejecutables

jci
ah okas
pero que son de la distribucion del paquete, cierto?
invierno
en este caso, toma los archivos en $(pixmap_DATA), $(dialog_DATA), etc.

si, son de la distribucion del paquete
es decir, nos interesa que se instalen
jci
ah okas
invierno
finalmente podemos colocar:
(repito, al final)
install-data-local:
 @$(NORMAL_INSTALL)
que es una regla que indica como instalar los datos
aqui podemos colocar algun "pseudo script" que funcione en make
jci
okas
invierno
en este caso, no es necesario
jci
en que caso seria tener un pseudo script?
invierno
que quieras ejecutar alguna cosa como cambio de permisos
jci
ah okas
<-- sourcer ha salido (Quit: BitchX: for distribution only with a new PC)
invierno
o algun detalle particular
antes que se me olvide
eso es todo lo de Makefile.am
lo de internacionalizacion tampoco es magico
jci
jejejeej
invierno
como sabe intltool de donde sacar las cadenas a traducir?
hasta el momento hemos dicho que queremos usarlos
jci
de los POTFILES?
invierno
exacto
jci
jejeje!
:-)
invierno
pero del POTFILES.in
si queremos añadir un nuevo archivo, lo indicamos alli
si borramos alguno, es conveniente que tambien lo saquemos de alli
bueno
jci
okas
invierno
ahora estamos en condiciones 
de ejecutar
make
make install
jci
jejeje
invierno
pero
como sacamos un tar.gz?
jci
ahora la consulta del millon!!!
--> sourcer (~sourcer@irc.cl-363090.terra.cl) ha ingresado en #gnome
--- vmlinuz fija modos [#gnome +o sourcer]
invierno
podriamos hacerlo a lo bruto
vmlinuz
[sourcer] My name is Dump, Core Dump
jci
antes del tar.gz
una consultilla german
invierno
pero la forma elegante de hacerlo, y la que se recomienda es:
make distcheck
jci
donde saca la lista de permisos (0644, etc)
invierno
¿?
jci
al hacer make install o depende solamente del tipo de archivo?
es que al hacer make install
invierno
depende del tipo de archivo
jci
algunas veces he visto 
invierno
lo que es _DATA es 0644
jci
install blabla <permisos> directorio
ah vale
tambien herencia del .am
:-)
invierno
es que se usa el script install
jci
okas
invierno
por ejemplo, un Makefile generado tendrá los siguiente:
INSTALL = /home/gpoo/bin/install -c
INSTALL_PROGRAM = ${INSTALL} $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL}
si te das cuenta:
INSTALL_DATA = ${INSTALL} -m 644
jci
aahhhh
invierno
alli se indican permisos
jci
:-)
invierno
para la parte _DATA
jci
ah okas
ya...okas
invierno
el make distcheck 
jci
:-)
invierno
es un poco mas desgraciado
muchas cosas funciona con make y make install
sourcer
uta que agarraste papa con autoconf/automake invierno 
invierno
pero fallan con make distcheck
make distcheck verifica que todo este correcto
y con AM_MAINTAINER_MODE añade -Werror
jci
aaahhh
invierno
es decir, si tu programa arroja algun warning, lo toma como error
y detiene el proceso hasta que saques ese warning
jci
aahhh
invierno
nada de entregar cosas medias cuchufletas
jci
jejeje
invierno
sourcer: aprovechando la inspiracion
y bueno, si tienen consultas...
jci
jejejee
yo quede liz taylor
:-)
invierno
esta es la explicacion que siempre quiso el juanjo
espero no haberlos aburrido
jci
jejeje
too lo contrario
:-)
grax german, nuevamente