Mandrake Linux 8.2: Manual de Referencia | ||
---|---|---|
Anterior | Capítulo 13. Compilando e instalando software libre | Siguiente |
Ahora que el software está configurado correctamente, sólo falta compilarlo. Generalmente esta parte es fácil, y no presenta problemas serios.
make es la herramienta favorita de la comunidad de software libre para compilar los fuentes. Tiene dos cosas interesantes:
le permite ganar tiempo al desarrollador, porque le permite administrar la compilación de su proyecto de manera eficiente,
permite que el usuario final compile e instale el software en pocas líneas de comando, incluso si él no tiene conocimientos preliminares de desarrollo.
Las acciones a ejecutar para obtener una versión compilada de los fuentes generalmente se almacenan en un archivo denominado Makefile o GNUMakefile. De hecho, cuando se invoca a make, este lee dicho archivo, si existe, en el directorio corriente. Si no es así, se puede especificar el archivo usando la opción -f con make.
make funciona de acuerdo a un sistema de dependencias, razón por la cual la compilación de un archivo binario ("objetivo") necesita pasar por varias etapas ("dependencias"). Por ejemplo, para crear el archivo binario (imaginario) glloq, se deben compilar y luego vincular los archivos objeto main.o e init.o (archivos intermedios de la compilación). Estos archivos objeto también son objetivos, cuyas dependencias son los archivos fuente.
Este texto sólo es una introducción mínima para sobrevivir en el mundo sin piedad de make. Si Usted quiere aprender más, le aconsejamos dirigirse al sitio web de APRIL, donde puede encontrar documentación más detallada sobre make. Para una documentación exhaustiva, debe referirse a Managing Projects with Make (Administración de proyectos con Make), segunda edición, de O'Reilly, por AndrewOram y Steve Talbott.
Por lo general, el uso de make obedece a muchas convenciones. Por ejemplo:
make sin argumentos simplemente ejecuta la compilación del programa, sin instalarlo.
make install compila el programa (aunque no siempre), y asegura la instalación de los archivos necesarios en el lugar adecuado del sistema de archivos. Algunos archivos no siempre se instalan correctamente (man, info), ellos deben ser copiados por el usuario. Algunas veces, make install tiene que volver a ser ejecutado en los subdirectorios. Por lo general, esto pasa con los módulos desarrollados por terceros.
make clean borra todos los archivos temporales creados por la compilación, y, en la mayoría de los casos, el archivo ejecutable.
La primera etapa para compilar un programa es ingresar (ejemplo imaginario):
$ make gcc -c glloq.c -o glloq.o gcc -c init.c -o init.o gcc -c main.c -o main.o gcc -lgtk -lgdk -lglib -lXext -lX11 -lm glloq.o init.o main.o -o glloq |
Excelente, el archivo binario está compilado correctamente. Ahora estamos preparados para la etapa siguiente, que es la instalación de los archivos de la distribución (archivos binarios, archivos de datos, etc...). Ver la sección Instalación).
Si Usted es lo suficientemente curioso para mirar el archivo Makefile , encontrará comandos conocidos (rm, mv, cp, ...), aunque también encontrará algunas cadenas extrañas, de la forma $(CFLAGS).
Estas son variables, es decir las cadenas que generalmente se fijan al comienzo del archivo Makefile, y luego se reemplazan por el valor con el cual están asociadas. Estas son muy útiles cuando quiere usar las mismas opciones de compilación varias veces.
Por ejemplo, puede mostrar la cadena "pepe" en la pantalla usando make all:
TEST = pepe all: echo $(TEST) |
La mayor parte del tiempo, se definen las variables siguientes:
CC: este es el compilador que va a utilizar. Generalmente es cc1, que en la mayoría de los sistemas libres, es sinónimo de gcc. Cuando tenga dudas, ponga aquí gcc.
LD: este es el programa usado para asegurar la fase de la compilación final (ver la sección Las cuatro fases de la compilación). El valor predeterminado es ld.
CFLAGS: estos son los argumentos adicionales que se pasarán al compilador durante las primeras etapas de la compilación. Entre ellos:
-I<ruta>: le especifica al compilador donde buscar algunos archivos de encabezado adicionales (por ejemplo:-I /usr/X11R6/include permite incluir los archivos de encabezado que están en el directorio /usr/X11R6/include)
-D<símbolo>: define un símbolo adicional, útil para los programas cuya compilación depende de los símbolos definidos (ej: utilizar el archivo string.h si está definida HAVE_STRING_H).
Generalmente hay líneas de compilación de la forma:
$(CC) $(CFLAGS) -c pepe.c -o pepe.o |
LDFLAGS (o LFLAGS): estos son los argumentos que se usan durante la última etapa de compilación. Entre ellos:
-L<ruta>: especifica una ruta adicional donde buscar bibliotecas (por ejemplo: -L/usr/X11R6/lib).
-l<biblioteca>: especifica una biblioteca adicional para usar durante la última etapa de compilación.
No tenga pánico, le puede pasar a cualquiera. Entre las causas más comunes:
glloq.c:16: decl.h: No such file or directory(glloq.c :16: decl.h: no hay archivo o directorio con ese nombre)
El compilador no pudo encontrar el archivo de encabezado correspondiente. Por lo tanto, la etapa de configuración del software debería haber anticipado este error. Como resolver este problema:
verifique que verdaderamente exista el archivo de encabezado en uno de los directorios siguientes: /usr/include, /usr/local/include, /usr/X11R6/include o en alguno de sus subdirectorios. De no ser así, búsquelo por todo el disco (con find o locate), y, si todavía no lo encuentra, verifique que ha instalado la biblioteca de desarrollo correspondiente a este archivo de encabezado. Puede encontrar ejemplos de los comandos find y locate en las respectivas páginas Man.
Verifique que el archivo de encabezado se pueda leer (para verificarlo, puede ingresar less <ruta>/<archivo>.h).
Si es un directorio como /usr/local/include o como /usr/X11R6/include, Usted tiene que agregar, a veces, un argumento nuevo al compilador. Abra el archivo Makefile correspondiente (tenga cuidado de abrir el archivo correcto, los que se encuentran en el directorio donde falla la compilación[1]) con su editor de texto favorito (Emacs, Vi, etc). Busque la línea errónea, y agregue la cadena -I<ruta>, donde <ruta> es la ruta donde se puede encontrar el archivo de encabezado en cuestión, justo después de la llamada del compilador (gcc, o, a veces, $(CC)). Si no sabe donde agregar esta opción, agréguela al comienzo del archivo, después de CFLAGS=<algo> o después de CC=<algo>.
ejecute make de nuevo, y si todavía sigue sin funcionar, verifique que esta opción (ver el punto anterior) se agrega durante la compilación en la línea errónea.
si todavía sigue sin funcionar, pida ayuda al autor del software, a su gurú local, o a la comunidad de software libre para resolver su problema (ver la sección Soporte técnico).
glloq.c:28: `struct pepe' undeclared (first use this function)
(glloq.c:28: "struct pepe" no está declarada (esta es la primera utilización en esta función))
Las estructuras son tipos de datos especiales, que usan todos los programas. El sistema define un montón de ellas en los archivos de encabezados. Eso significa que es muy probable que el problema sea la falta o el mal uso de un archivo de encabezado. El procedimiento correcto para resolver el problema es:
intente verificar si la estructura en cuestión es una estructura definida por el programa o por el sistema. Una solución es usar el comando grep para ver si la estructura está definida en alguno de los archivos de encabezado.
Por ejemplo, cuando Usted está en la raíz de la distribución:
$ find . -name '*.h'| xargs grep 'struct pepe' | less |
Es posible que aparezcan muchas líneas en la pantalla (por ejemplo, cada vez que se define una función que use esta estructura). Elija, si existe, la línea donde se define la estructura mirando el archivo de encabezado obtenido por la utilización del comando grep.
La definición de una estructura es:
struct pepe { <contenido de la estructura pepe> }; |
Verifique si ella corresponde a lo que Usted tiene. De ser así, eso significa que no se incluye el encabezado en el archivo .c erróneo. Hay dos soluciones:
agregar la línea #include "<nombre_de_archivo>.h" al comienzo del archivo .c erróneo.
o copiar y pegar la definición de la estructura al comienzo del archivo .c (esto no es de lo mejor, pero al menos por lo general, funciona).
si este no es el caso, haga lo mismo con los archivos de encabezado del sistema (que, generalmente, se encuentran en los directorios siguientes: /usr/include, /usr/X11R6/include y /usr/local/include). Pero en este caso, use la línea #include <<nombre_de_archivo>.h>.
si todavía no existe esta estructura, intente encontrar en que biblioteca (es decir, conjunto de funciones agrupadas en un solo paquete) debería estar definida (ver en el archivo INSTALL o README cuales son las bibliotecas que usa este programa y las versiones necesarias). Si la versión que necesita el programa no está instalada en el sistema, Usted deberá actualizar esta biblioteca. Cabe destacar que debe tener sumo cuidado al manipular los archivos de encabezado del sistema, ya que estos son comunes a muchos programas.
si todavía sigue sin funcionar, verifique que el programa funciona adecuadamente sobre su arquitectura (algunos programas todavía no han sido portados a todos los sistemas UNIX. Verifique también que ha configurado el programa correctamente (por ejemplo, cuando ejecutó configure) para su arquitectura.
parse error (error de análisis sintáctico)
Este es un problema que es relativamente complicado de resolver, porque generalmente es un error que aparece en cierta línea, pero después que el compilador lo encontró. A veces, es simplemente un tipo de datos que no está definido. Si Usted encuentra un mensaje de error del tipo:
main.c:1: parse error before `glloq_t main.c:1: warning: data definition has no type or storage class |
entonces el problema es que el tipo glloq_t no está definido. La solución al problema es más o menos la misma que en el problema anterior.
![]() | puede haber un error del tipo parse error en las bibliotecas curses antiguas si la memoria no nos falla. |
no space left on device (no queda espacio en el dispositivo)
El problema es simple de resolver: no hay espacio suficiente en el disco para generar un archivo binario a partir del archivo fuente. La solución consiste en liberar espacio en la partición que contiene el directorio de instalación (borrar archivos innecesarios, archivos temporales, desinstalar programas que no use). Si descomprimió en /tmp, mejor hágalo en /usr/local/src que evita la saturación innecesaria de la partición tmp. Es más, verifique si hay archivos core> en su disco. De ser así, elimínelos o haga que el usuario al cual pertenezcan los elimine. En fin, trate de liberar espacio en disco.
/usr/bin/ld: cannot open -lglloq: No such file or directory (/usr/bin/ld: no puedo abrir -lglloq: no hay archivo o directorio alguno con ese nombre)
Esto significa claramente que el programa ld (usado por gcc durante la última etapa de la compilación) no puede encontrar una biblioteca. Para incluir una biblioteca, ld busca un archivo cuyo nombre está en los argumentos del tipo -l<biblioteca>. Este archivo es lib<biblioteca.so>. Si ld no puede encontrarlo, produce un mensaje de error. Para resolver el problema, siga los pasos que se indican a continuación:
verifique que el archivo existe en el disco rígido usando el comando locate. Por lo general, las bibliotecas gráficas se encuentran en /usr/X11R6/lib. Por ejemplo:
$ locate libglloq |
Si la búsqueda no tiene resultado, Usted puede buscar con el comando find (ej: find /usr -name libglloq.so*). Si Usted no puede encontrar la biblioteca, entonces tendrá que instalarla.
una vez que está localizada la biblioteca, verifique que ld puede accederla: el archivo /etc/ld.so.conf especifica donde encontrar estas bibliotecas. Agregue el directorio en cuestión al final del mismo y ejecute ldconfig. También puede agregar este directorio a la variable de entorno LD_LIBRARY_PATH. Por ejemplo, si el directorio a agregar es /usr/X11R6/lib, ingrese:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/X11R6/lib |
(si su shell es bash).
si todavía no funciona, verifique que el formato de la biblioteca en cuestión es un archivo ejecutable (o ELF) (con el comando file). Si esta es un vínculo simbólico, verifique que el vínculo es correcto y no apunta a un archivo inexistente (por ejemplo, con nm <lib>). Los permisos pueden ser erróneos (por ejemplo, Usted usa una cuenta que no es root y la biblioteca está protegida contra lectura).
glloq.c(.text+0x34): undefined reference to `glloq_init' (glloq.c(.text+0x34): referencia indefinida al símbolo `glloq_init')
Esto significa que no se resolvió un símbolo durante la última etapa de la compilación. Por lo general, este es un problema de biblioteca. Puede haber varias causas:
la primera cosa a hacer es saber si se supone que el símbolo esté presente en una biblioteca. Por ejemplo, si es un símbolo que comienza por gtk, pertenece a la biblioteca gtk. Si el nombre de la biblioteca es difícil de identificar (como por ejemplo, zorglub_gloubiboulga), se pueden listar los símbolos de una biblioteca con el comando nm. Por ejemplo,
$ nm libglloq.so 0000000000109df0 d glloq_message_func 000000000010a984 b glloq_msg 0000000000008a58 t glloq_nearest_pow 0000000000109dd8 d glloq_free_list 0000000000109cf8 d glloq_mem_chunk |
Agregar la opción -o a nm permite mostrar el nombre de la biblioteca en cada línea, lo cual facilita la búsqueda. Imaginemos que buscamos el símbolo bulgroz_max, una solución cruda es realizar una búsqueda del tipo:
$ nm /usr/lib/lib*.so | grep bulgroz_max $ nm /usr/X11R6/lib/lib*.so | grep bulgroz_max $ nm /usr/local/lib/lib*.so | grep bulgroz_max /usr/local/lib/libfrobnicate.so:000000000004d848 T bulgroz_max |
¡Formidable! El símbolo bulgroz_max está definido en la biblioteca zorglub (la letra mayúscula T se encuentra delante de su nombre). Entonces, Usted sólo tiene que agregar la cadena -lzorglub en la línea de compilación editando el archivo Makefile: agréguela al final de la línea donde se define la variable LDFLAGS o LFGLAGS (o, en el peor de los casos, CC), o en la línea correspondiente a la creación del archivo binario final.
la compilación está hecha con una versión de la biblioteca que no es la que permite el software. Lea el archivo README o INSTALL de la distribución para saber que versión de la biblioteca debe usar.
no todos los archivos objeto de la distribución están vinculados correctamente. Falta, o no se menciona, el archivo donde está definida esta función. Ingrese nm -o *.o, para saber el nombre del archivo .o correspondiente y agréguelo en la línea de compilación si es que falta.
la función o variable en cuestión puede ser fantasiosa. Intente eliminarla: edite el archivo fuente en cuestión (el nombre del mismo se especifica al comienzo del mensaje de error). Esta es una solución desesperada cuya consecuencia ciertamente será un funcionamiento anárquico del software (error de segmentación en el arranque, etc.)
Segmentation fault (core dumped) (Error de segmentación (se produjo un archivo core))
A veces, el compilador se cuelga lamentablemente y produce este mensaje de error. No tengo consejo alguno, salvo pedirle que instale una versión más reciente de su compilador.
no queda espacio en /tmp
La compilación necesita espacio temporal durante las diferentes etapas; si no tiene espacio suficiente, falla. Por lo tanto, debe limpiar la partición, pero debe tener cuidado ya que algunos programas en curso de ejecución (servidor X, tuberías...) se pueden colgar si se borran algunos archivos. ¡Usted debe saber lo que está haciendo! Si tmp es parte de una partición que no la contiene solamente (por ejemplo, la raíz), busque y borre algunos archivos core eventuales.
make/configure en bucle infinito
Generalmente, esto es un problema de la hora en su sistema. En efecto, make necesita saber la fecha y la hora de la computadora y de los archivos que verifica. Este compara las fechas de los archivos y usa el resultado para saber si el objetivo es más reciente que la dependencia.
Algunos problemas en la fecha pueden inducir a make a reconstruirse a sí mismo indefinidamente (o a construir y reconstruir un sub-árbol en bucle). Si es así, el uso del comando touch (cuya consecuencia es poner en la hora corriente a los archivos pasados como argumento) resuelve el problema la mayoría de las veces.
Por ejemplo:
$ touch * |
O también, (más bruto, pero eficiente):
$ find . | xargs touch |
[1] | Usted debe analizar el mensaje de error que devuelve make. Normalmente, las últimas líneas deberían contener un directorio (un mensaje como make[1]: Leaving directory `/home/benj/Proyecto/pepe'). Elija aquel que tiene el número más grande. Para verificar que es el bueno, vaya al directorio y ejecute make de nuevo para obtener el mismo error. |