[OpenBSD]

Cómo manejar las bibliotecas compartidas en el árbol de portes

Qué son las reglas numéricas de las bibliotecas compartidas

Las bibliotecas compartidas son algo complicadas por varias razones. Para su manejo es necesario entender antes el esquema de nombres de las bibliotecas: libfoo.so.major.minor.

Cuando se enlaza un programa, el enlazador ld embebe esa información en el binario que se genera. Esto se puede ver con ldd. Más tarde, cuando se ejecuta este programa, el enlazador dinámico ld.so utiliza esa información para encontrar la biblioteca dinámica pertinente: Esto quiere decir que todas las bibliotecas con el mismo número superior y con un número inferior igual o mayor al requerido, deben satisfacer el API binario que el programa espera encontrar. Si no fuera así, entonces el porte sería erróneo; en concreto, el porte no funcionaría cuando los usuarios intentaran actualizar sus sistemas.

Las reglas para las bibliotecas compartidas son bastante simples.

Algunas veces sucede que una biblioteca está escrita en varios ficheros, y las funciones internas son visibles para permitir la comunicación entre esos ficheros. Esos nombre de funciones suelen empezar con un guión bajo, y no son parte del API.

Nótese que el esquema de nombres de las bibliotecas es ubicuo en las plataformas de OpenBSD, tanto si el formato es ELF como a.out.

Cambios en los portes para obtener nombre correctos

Un buen número de portes necesitan cambios para poder ser compilados con bibliotecas compartidas. Recuerde que la compilación de las bibliotecas compartidas se debe hacer mediante gcc -shared -fpic|-fPIC -o libfoo.so.4.5 obj1 obj2

Si intenta cambiar el nombre de la biblioteca más tarde para ajustar el número de versión, no funcionará: las bibliotecas ELF usan magia adicional para el nombre interno de la biblioteca, por lo que debe enlazar desde la primera vez con la versión correcta.

Por otra parte, recuerde que puede anular y cambiar variables de Makefile desde la línea de órdenes, usando MAKE_FLAGS en el fichero Makefile del porte. Esto le será de gran utilidad en algunos portes, como por ejemplo los basados en libtool, ya que proveen de una de estas variables de versión por cada biblioteca que crean.

Intente poner todas las bibliotecas visibles en /usr/local/lib

Exigir que el usuario añada directorios a su camino a ldconfig es, como regla general, una mala idea: todas las bibliotecas compartidas que se encuentran directamente enlazadas a programas deberían aparecer en /usr/local/lib. Sin embargo, es posible usar un enlace simbólico a una determinada biblioteca. Es necesario que se comprendan las reglas de búsqueda de las bibliotecas: Asumamos que tenemos dos portes que provean dos versiones principales de una cierta biblioteca, pongamos como ejemplo qt.1.45 y qt.2.31. Como los dos portes no se pueden instalar de forma simultánea, para asegurarnos de que un programa cualquiera enlace con qt.1, esa biblioteca se proveerá como /usr/local/lib/qt/libqt.so.1.45, y los programas se enlazarán usando ld -o program program.o -L/usr/local/lib/qt -lqt. De igual modo, un programa que enlace con qt.2 usará el fichero /usr/local/lib/qt2/libqt.so.2.31 con ld -o program program.o -L/usr/local/lib/qt2 -lqt.

Para resolver esas bibliotecas en el momento de la ejecución, se proveerá un enlace llamado /usr/local/lib/libqt.so.1.45 y otro llamado /usr/local/lib/libqt.so.2.31. Esto será suficiente para satisfacer a ld.so.

Enlazar un programa usando qt1 con ld -o program program.o -L/usr/local/lib -lqt es un error. Este código asume que qt.2.31 no ha sido instalado, lo que es una presunción errónea.

Estos trucos sólo son necesarios en casos especiales en los que se den bibliotecas para las que se necesite proveer de un periodo de transición entre versiones. Por lo general, bastará con asegurarse de que la biblioteca aparezca en /usr/local/lib.

Cómo escribir correctamente las dependencias de las bibliotecas

El nuevo código de dependencia necesita dependencias de bibliotecas completas. Debe usar make lib-depends-check para verificar que un porte mencione todas las bibliotecas que requiere. Separe las especificaciones de bibliotecas con comas: LIB_DEPENDS=gtk.1.2,gdk.1.2::x11/gtk+.

Además, especificar las bibliotecas estáticas en una línea de LIB_DEPENDS no es un error. LIB_DEPENDS es evaluado por completo en el momento de la compilación de un paquete: el paquete resultante tendrá la información sobre dependencias de bibliotecas embebido, en forma de líneas para ld.so, que contienen el número superior.inferior que fue usado para su compilación, y nada para las bibliotecas compartidas.

También debe proveer de RUN_DEPENDS si un porte requiere algo más que compilar enlazando a una biblioteca. Esto permitirá al porte compilar correctamente en arquitecturas que no tengan soporte para bibliotecas compartidas.

De hecho, proveer líneas LIB_DEPENDS para bibliotecas estáticas es una buena idea: esto simplificará la acutalización del porte si una cierta dependencia pasa de biblioteca estática a biblioteca compartida.

La líneas LIB_DEPENDS deben especificar los mismos caminos que se utilizan para ld. Por ejemplo, el fragmento de dependencia típico de qt2 dice: LIB_DEPENDS+=lib/qt2/qt.2::x11/qt2, para que las líneas de dependencias de la biblioteca se resuelvan correctamente. Esto permite a la dependencia comprobar el código para poder hacer lo correcto si se encuentra con varias versiones de la misma biblioteca.

Cómo actualizar los portes correctamente

Cuando se actualice o añada un porte en el que haya por medio bibliotecas compartidas, hay que tener en cuenta unos cuantos detalles.
OpenBSD www@openbsd.org
Originally [OpenBSD: libraries.html,v 1.4 ]
$Translation: libraries.html,v 1.3 2004/08/29 16:14:27 santana Exp $
$OpenBSD: libraries.html,v 1.3 2004/08/29 16:55:04 jufi Exp $