Los paquetes que contienen librerías que se comparten deben ser construídos con algo de cuidado, para asegurarse que las librerías compartidas estén ahí siempre disponibles. Esto es especialmente importante para aquellos paquetes los cuales el compartir librerías es de vital importancia, como en el caso de la C library" actualmente "libc6".

Los paquetes que les implique librerías compartidas deberían ser separados en varios paquetes binarios. La mayoría de esta sección abarca como son las reglas para la realización de estas separaciones; las reglas para sus archivos los cuales estén en los paquetes que compartan librerías están en "Libraries, Section 10.2 instead".

8.1 Librerías Run-time Compartidas

Las librerías run-time compartidas necesitan ser puestas en un paquete en el cual su nombre cambie cuando la versión del objeto compartido cambie. El más común de los mecanismos es el de ponerlo dentro de un paquete que se llame librarynamesoversion, en donde someversion es el número de versión en el nombre de la librería que se comparten. Alternativamente, si fuera confuso el poner someversion para el libraryname (Porque el mismo libraryname termina en un número), tu podrías usar el libraryname-someversion y el libraryname-someversion-dev en su lugar.

Si tu paquete tiene soporte run-time de programas que no necesitan ser involucrados manualmente por usuarios, pero sin embargo, requerido por el paquete para su funcionalidad, entonces es recomendado que esos programas sean puestos (si son binarios) en un subdirectorio de el /usr/lib, se prefiere que estén bajo /usr/lib/package-name. Si la arquitectura de el programa es independiente, la recomendación es que él sea puesto en un subdirectorio de /usr/share en su lugar, preferidamente bajo /usr/share/nombre-del-paquete.

Si tienes varias librerías compartidas construídas con el mismo código, tu puedes ponerlos a todos ellos juntos dentro de un único paquete de librerías compartidas, provisto para que cambie todos sus nombres de una vez (para que tu no tengas problemas con los nombres de archivo si tu intentas instalar una versión diferente de el paquete que combina librerías compartidas).

El paquete debería instalar las librerías compartidas bajo sus nombres normales. En ejemplo, el paquete libgdbm3 debería instalar libgdbm.so.3.0.0 como /usr/lib/libgdbm.so.3.0.0. Los ficheros no deberían ser renombrados o "re-linkied" por algún prerm o postrm scripts; dpkg se va hacer cargo de el renombramiento seguro sin afectar los programas que se estén corriendo, meterse a intervenir con esto es más o menos como lidear con algunos problemas.

Librerías compartidas no deberían instalar ejecutables, ya que el enlazador dinámico no requiere esto e intentar ejecutar una librería compartida usualmente resulta en un core dump.

El paquete run-time de librerías compartidas debería incluir el enlace simbólico que ldconfig pudiera crear para las librerías compartidas. Por ejemplo, el paquete libgdbm3 debería incluir un enlace simbólico desde /usr/lib/libgdbm.so.3 hasta libgdbm.so.3.0.0. Esto es necesario para que el linker dinámico (ld.so ó ld-linux.so.*) pueda encontrar la librería entre el tiempo que dpkg lo instala y el tiempo que ldconfig corre el postinst script.

8.1.1 ldconfig

Algún paquete que esté instalando librerías compartidas en algunos de los directorios por defecto de el linker dinámico (los cuales están actualmente en /usr/lib y en /lib) o en un directorio que es listado en /etc/ld.so.conf debe usar el ldconfig para actualizar el sistema de librerías compartidas.

El paquete debe de llamar al ldconfig en el postinst script si el primer argumento es configure; el postinst script puede opcionalmente invocar el ldconfig en otros tiempos. El paquete debería llamar el ldconfig bajo alguna circunstancia otro que el de aquello descrito en este párrafo. http://www.debian.org/doc/debian-policy/footnotes.html#f45

8.2 Soporte de programas Run-time Si tu paquete tiene algún programa de el tipo run-time el cual use la librería compartida tu no deberías de poner esos programas en el paquete de librerías compartidas. Si tu haces eso, entonces tu no podrás instalar varias versiones de las librerías compartidas sin obtener problemas de filename.

En lugar, crear otro paquete también para los binarios de los runtime (este paquete pudiera ser llamado típicamente libraryname-runtime; mira la ausencia de la versión en el nombre del paquete), o si el paquete de desarrollo es pequeño, lo incluyes a ellos ahí. 8.3 Librerías estáticas La librería estática (libraryname.a) es provista usualmente en adición para la versión compartida. Si ella es puesta dentro el paquete dev (mira más adelante).

En algunos casos, es aceptable para una librería estar disponible en forma estática sólamente; esos casos incluyen:

8.4 Archivos para Desarrolar Los archivos de desarrolladores que estén asociados a una librería compartida necesitan ser puestos en un paquete que se llame librarynamesoversion-dev, o si tu prefieres sólamente soportar una versión de desarrollo al mismo tiempo, libraryname-dev.

En muchos casos de versiones de desarrollo de una librería existente, tu puedes necesitar usar el mecanismo conflictivo de dpkg`s (Mira Conflicting binary packages - Conflicts, Section 7.3) para asegurarte que el usuario final instala una versión de desarrollo al mismo tiempo (como diferentes versiones de desarrollo tienden a tener los mismos archivos header en ellos, los cuales podrían causar unos problemas en los nombres de archivos si ambos estuvieran instalados).

El paquete de desarrollo debería contener a simlink para la asociada librería sin un número de versión. Por ejemplo, el paquete libgdbm-dev debería incluir un symlink /usr/lib/libgdbm.so para libgdbm.so.3.0.0. Este symlink es necesitado por el linker (ld) cuando se compilen paquetes, puede buscar por libgdbm.so cuando se compila dinámicamente.

8.5 Dependencias entre paquetes de la misma librería Típicamente la versión de desarrollo debería tener una exacta versión dependiente en la librería del runtime, para estar seguro que la compilación y el linking ocurren correctamente. La variable ${Source-Version} sustituta pueda ser muy útil para este propósito.

8.6 Dependencias entre la librería y otros paquetes -shlibs system- Si un paquete contiene un binario o librería los cuales se enlazan a una librería compartida, nosotros debemos asegurarnos que cuando el paquete es instalado en el sistema, todo de las librerías necesitadas son también instaladas. Este requerimiento nos lleva para la creación de las shlibs sistema, el cual es muy simple en su diseño algún paquete el cual provea una librería compartida también provee información en las dependecias requeridas del paquete requeridas para asegurarse la presencia de esta librería, y algún paquete el cual usa una librería compartida use esta información para determinar las dependecias que el requiere. Los archivos que contienen el mapping de las librerías compartidas para la dependiente información necesaria son llamadas shlibs files.

Así, cuando un paquete es emsamblado y contenga alguna librería compartida, debe proveer un archivo shlibs para otro paquete usar, y cuando un paquete es armado y que contenga alguna librería compartida o binarios, ese debe correr el dpkg-shlibdeps en aquellos para determinar las librerías usadas y por eso las dependencias necesitadas por este paquete.

En la siguiente sección primero a describir donde los varios archivos shlibs van a estar hallados, después el cómo usar dpkg-shlibdeps, y finalmente el formato de el archivo shlibs y cómo crearlos si tu paquete contiene una librería compartida.

8.6.1 Los archivos shlibs presentes en el sistema Hay varios sitios donde los archivos shlibs son encontrados. La siguiente lista te muestra en orden aquellos en donde son leídos por dpkg-shlibdeps.(El primero el cual da la requerida información es usada.)

debian/shlibs.local

Esta lista sobreescrita para este paquete. Su uso es descrito a continuación(mira Writing the debian/shlibs.local file, Section 8.6.5).

/etc/dpkg/shlibs.override

Esta lista global se elimina. Esta es normalmente vacía. Es mantenida por el administrador local.

DEBIAN/shlibs files in the "build directory"

Cuando los paquetes empiezan a hacer construidos, algunos archivos debian/shlibs son copiados dentro del área de control del archivo del temporal directorio de construcción y se le da el nombre de shlibs. Esos archivos dan detalles de alguna librería compartida incluída en el paquete.

/var/lib/dpkg/info/*.shlibs

Esos son los archivos shlibs correspondientes para todos los paquetes instalados en el sistema,y son mantenidos por el propio encargado del paquete.

/etc/dpkg/shlibs.defaultEste archivo lista alguna librería compartida el cual su paquete ha fallado al proveer los correctos archivos shlibs. Eso se usó cuando el shlibs setup fué primero introducido, pero ese es ahora normalmente vacío. Eso es mantenido por el dpkg maintainer.

8.6.2 Cómo usar el dpkg-shildeps y los archivos shlibs Pon una llamada para dpkg-shlibdeps dentro de tu archivo debian/rules. Si tu paquete contiene solamente binarios y librerías (pero ningún script), tu puedes usar un comando como el parecido:

dpkg-shlibdeps debian/tmp/usr/bin/* debian/tmp/usr/sbin/* \ debian/tmp/usr/lib/*.

De otra forma, tu podrías necesitar listar los binarios y librerías.

Este comando pone la información dependente dentro de debian/substvars, el cual es usado entonces por dpkg-gencontrol. Tu podrías necesitar poner una variable ${shlib:Depends} en la parte Depends dentro de el archivo de control para que esto funcionara.

Si dpkg-shlibdep no se queja, tu estás listo. Si se queja tu pudieras necesitar crear tu propio debian/shlibs. Archivo local, como es explicado aquí en ( Writing the debian/shlibs.local file, Section 8.6.5).

Si tu tienes paquetes múltiples binarios, tu podrías necesitar llamar el dpkg-shlibdeps en cada uno que contuviera compilados librerías o binarios. En tal caso, tu puedes necesitar usar la -T option para las utilidades dpkg para especificar un diferente archivo substvars.

Para más detalles para dpkg-shlibdeps, por favor dale un vistazo a http://www.debian.org/doc/debian-policy/ap-pkg-sourcepkg.html#s-pkg-dpkg-shlibdeps y a dpkg-shlibdeps(1). 8.6.3 El formato del archivo shlibs Cada archivo shlibs tiene el mismo formato. Líneas que empiezan con un # son consideradas a ser comentarios y son ignoradas. Cada línea es de la forma:

library-name soname-version-number dependencies ...

Explicaremos esto por referencia a el ejemplo de el paquete zlib1g, el cuál(en este tiempo de escritura) instala la librería compartida /usr/lib/libz.so.1.1.3

library-name es el nombre de la librería compartida, en este caso libz.(esto debería acertar la parte de nombre,mira más adelante.)

soname-version-number es la parte de versión de el nombre de la librería. El nombre es la cosa que debe exactamente concordar para que la librería sea reconocida por el linker dinámico, y es usualmente de la forma name.so.major-version,en nuestro ejemplo libz.so.1. La parte de versión es la parte la cual viene después .so., entonces en nuestro caso es 1.

Las dependencias tienen la misma sintax que un campo de dependencia en un archivo de control de un paquete binario. Debería dar detalles de cual paquetes son requeridos para satisfacer un binario construido en contra de la versión de la librería contenida en el paquete. Mira http://www.debian.org/doc/debian-policy/ch-relationships.html#s-depsyntax. Para detalles.

En nuestro ejemplo, si la primera versión de el paquete zlib1g el cual es contiene un menor número de al menos 1.3 fue 1:1.1.3-1, entonces la entrada de librería shlibs podría ser:

libz 1 zlib1g (>= 1:1.1.3)

La dependencia versión-específica es para evitar alertas de el linker dinámico acerca de estar usando librerías mas viejas compartidas con los más nuevos binarios.

8.6.4 Proveer el archivo shlibs Si tu paquete proporciona una librería compartida, tu deberías crear un archivo shlibs siguiendo el formato descrito a continuación. Es usual llamar este archivo debian/shlibs(pero si tu tienes paquetes binarios múltiples, tu podrías querer llamarlo debian/shlibs.package en su lugar). Entonces deja el debian/rules instalarse en la parte de control:

install -m644 debian/shlibs debian/tmp/DEBIAN

ó, en el caso de un paquete binario-múltiple:

install -m644 debian/shlibs.package debian/package/DEBIAN/shlibs

Una forma de hacer esto alternativamente es el de crear el archivo shlibs en el área de control directamente desde debian/rules sin usar un debian/shlibs del todo, el archivo mismo debian/shlibs es ignorado por dpkg-shlibdeps. debian/shlibs

Como dpkg-shlibdeps lee el archivo DEBIAN/shlibs en todos paquetes binarios siendo construídos desde el paquete de código fuente, todo de el archivo DEBIAN/shlibs debería ser instalado antes de que dpkg-shlibdeps sea llamado en algunos de los paquetes binarios.

8.6.5 Escribiendo el archivo debian/shlibs.local Este archivo es previsto solamente como un temporal si tu binario o librerías dependen en una librería la cual su paquete no aún provee un correcto archivo shlibs.

Asumiremos que tu estás intentando empacar un binario foo. Cuando tu intentes correr dpkg-shlibdeps tu obtendrás el siguiente mensaje de error (-0 muestra la información dependende en stdout en lugar de escribirlo en debian/substvars, y las líneas han sido envueltas para una fácil lectura):

$ dpkg-shlibdeps -O debian/tmp/usr/bin/foo dpkg-shlibdeps: warning: unable to find dependency information for shared library libbar (soname 1, path /usr/lib/libbar.so.1, dependency field Depends) shlibs:Depends=libc6 (>= 2.2.2-2)

Puedes correr el ldd en el binario para encontrar la locación completa de la librería en cuestión:

$ ldd foo libbar.so.1 => /usr/lib/libbar.so.1 (0x4001e000) libc.so.6 => /lib/libc.so.6 (0x40032000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Entonces el binario foo depende en el libbar librería compartida, pero no hay paquete que parezca proveer un archivo con *.shlibs teniendo una libbar.so.1 en /var/lib/dpkg/info/. Vamos a determinar el paquete responsable:

$ dpkg -S /usr/lib/libbar.so.1 bar1: /usr/lib/libbar.so.1 $ dpkg -s bar1 | grep Version Version: 1.0-1

Esto nos dice que el paquete barl versión 1.10-1, es el que estamos usando. Ahora nosotros podemos archivar un bug en contra de el paquete barl y crear nuestro propio debian/shlibs.local para localmente arreglar el problema. Incluyendo la siguiente línea en tu archivo debian/shlibs.local:

ibbar 1 bar1 (>= 1.0-1)

Debería dejar al paquete construirse.

Tan pronto el mantenedor de barl nos provea un correcto archivo shligs, tu deberías remover esta línea de tu debian/shlibs.local. (Tu problablemente deberías también tener una versión Build-Depends en barl para ayudar asegurarte que otros no tengan el mismo problema construyendo tus paquetes.)