Filtro Automático de Ofertas y Demandas
Resumen
El sistema automático que requiere y proporciona contenido en RPM es bastante útil; sin embargo, a veces detecta capacidades de paquetes "privados" que no deberían publicitarse como globales, cosas que “son simplemente incorrectas” o cosas prohibidas por la política (por ejemplo, dependencias desde dentro de %{_docdir}
).
Por ejemplo:
-
Varios paquetes de "complementos" (por ejemplo, Pidgin, Perl, Apache, KDE) están marcados como "proveedores" de bibliotecas compartidas privadas fuera de la ruta del sistema.
-
Los archivos en
%{_docdir}
se analizan de forma rutinaria y pueden activar prov/req cuando esto está explícitamente prohibido por la política.
Esta guía describe cómo filtrar ofertas y requisitos en Fedora.
-
OBLIGATORIO: Los paquetes no deben proporcionar información de dependencias RPM cuando dicha información no sea de naturaleza global, o se gestione de otra manera (por ejemplo, mediante un sistema de proveedores virtuales). Por ejemplo, un paquete de complemento que contenga una biblioteca binaria compartida no debe proporcionar dicha biblioteca a menos que sea accesible a través de las rutas de bibliotecas del sistema.
-
OBLIGATORIO: Al filtrar la información de dependencias de RPM generada automáticamente, se debe utilizar el sistema de filtrado implementado por Fedora, excepto cuando exista una razón convincente para desviarse de él.
Utilización
Lugar de invocación de macro
Se recomienda encarecidamente que estas macros de filtrado se invoquen antes de %description
, pero después de cualquier otra definición. Esto las mantendrá en un lugar consistente en todos los paquetes y evitará que se mezclen con otras secciones.
Variante de Expresión Regular
Estos filtros utilizan expresiones regulares. La variante de expresión regular utilizada para estos filtros sigue el estándar de expresiones regulares POSIX.2
(consulte la página de manual +regex(7)
). En esta variante, los caracteres literales ^.[$()|*+?{
deben escaparse con una barra invertida. Dado que rpm interpreta las barras invertidas como parte del análisis de los archivos de especificaciones, deberá usar una doble barra invertida para cualquier escape. Una barra invertida literal (“\”) se representa con cuatro barras invertidas.
El motor de expresiones regulares solo recibe la cadena final, después de la expansión de la macro RPM. Por lo tanto, no se pueden usar datos sin escape mediante macros RPM. Por ejemplo, si se genera una lista de archivos para una macro y dicha lista contiene libfoo.so
, se deberá usar libfoo\\.so
para escapar el (“.”). Ejemplo:
%global to_exclude libfoo\\.so
%global __requires_exclude_from ^%{_datadir}/%{to_exclude}$
Cómo evitar que se escaneen archivos o directorios en busca de dependencias (filtrado previo al escaneo)
Las macros %__requires_exclude_from
y %__provides_exclude_from
se pueden definir en un archivo de especificaciones para evitar que el generador de dependencias escanee archivos o directorios específicos en busca de dependencias. Estas macros deben definirse con una expresión regular que coincida con todos los directorios o archivos. Por ejemplo:
# No verifique ningún archivo en docdir para ver si hay requisitos
%global __requires_exclude_from ^%{_docdir}/.*$
# No revise los archivos .so en un directorio de biblioteca específico de la aplicación
# ni ningún archivo en el directorio de datos de la aplicación para providencias
%global __provides_exclude_from ^(%{_libdir}/%{name}/.*\\.so.*|%{_datadir}/myapp/.*)$
Note que esta macro remplaza la macro %filter_provides_in
desde el filtro anterior de la líneas de guía pero no es la misma cosa. En particular:
-
La macro anterior podía invocarse varias veces. Esta solo usará la última expresión regular definida.
-
La macro anterior desaconsejaba anclar el inicio de la expresión regular (usando
^
). Esta macro recomienda anclar, ya que no presenta los problemas de compatibilidad de la anterior. -
Con la macro anterior, era común especificar un nombre de directorio para buscar todo en él recursivamente. Con la nueva macro, es posible que deba especificar
.*
para anclar sus expresiones regulares.
El filtrado proporciona y requiere después del análisis
Además de evitar que RPM analice archivos y directorios para la generación automática de dependencias, también puede indicarle que descarte una dependencia descubierta antes de registrarla en los metadatos de RPM. Para ello, utilice __requires_exclude
y __provides_exclude
. Estas macros deben definirse como expresiones regulares. Si una entrada creada por el generador automático de dependencias de RPM coincide con la expresión regular, se filtrará de los requisitos o las provisiones. Por ejemplo:
# Esto podría ser útil si el generador de dependencias detecta los complementos
%global __provides_exclude ^libfoo-plugin\\.so.*$
# Algo como esto podría usarse para evitar dependencias excesivas de
# un ejemplo de script de Python en %doc
%global __requires_exclude ^/usr/bin/python$
Estas macros tienen una función similar a la antigua macro %filter_from_provides
, pero su implementación es diferente. En particular, esta macro aceptaba expresiones sed, mientras que esta requiere una expresión regular.
Macros simplificadas para casos comunes
En algunos casos, el filtrado de Provides:
superfluos es bastante común en todos los paquetes que ofrecen funciones similares. Existen macros simples que configuran los filtros correctamente para estos casos, lo que permite realizar el filtrado con una sola línea. Si necesita filtrar más de lo que proporciona la macro simple, aún puede usar las macros mencionadas anteriormente.
Perl
Los módulos de extensión de Perl se pueden filtrar utilizando esta macro:
%{?perl_default_filter}
Básicamente, esto filtra las dependencias que surgen de archivos %doc
, de módulos no relacionados con Linux y de errores en el generador automático de dependencias.
Si desea usar filtros personalizados y %perl_default_filter
, defina primero sus filtros y luego llame a %perl_default_filter
. La macro de filtro predeterminado conservará los filtros definidos previamente. Por ejemplo:
# Filtrar todos los recursos proporcionados de un directorio
%global __provides_exclude_from %{_libexecdir}/autoinst
# Filtrar algunos requisitos específicos por nombre
%global __requires_exclude ^perl\\((autotest|basetest)
# Todos los filtros predeterminados
%{?perl_default_filter}
Ejemplos
Paquete complemental Pidgin
En una máquina x86_64, pidgin-libnotify proporciona pidgin-libnotify.so()(64bit)
, lo cual no debería ocurrir, ya que esta biblioteca no se encuentra en las rutas de búsqueda del sistema. Es una biblioteca privada, no global, y, por lo tanto, RPM no debe exponerla globalmente.
Para filtrar esto, podríamos usar:
%global __provides_exclude_from ^%{_libdir}/purple-2/.*\\.so$
Bibliotecas Privadas
Actualmente, el filtrado de bibliotecas privadas no es trivial. Esto se debe a que los símbolos que se desean filtrar de las bibliotecas privadas suelen ser requeridos por las aplicaciones públicas que incluye el paquete. Para ello, es necesario averiguar qué símbolos extrae RPM para la biblioteca privada y luego eliminarlos en ambas %__provides_exclude
y %__requires_exclude
..
Por ejemplo, imagine que está empaquetando una aplicación foo que crea %{_libdir}/foo/libprivate.so
que desea filtrar y %{_bindir}/foobar
que requiere esa biblioteca privada. Podría:
-
Primero construya el RPM:
$ rpmbuild -ba foo.spec
-
Luego determine qué proporciona el rpm decidido para la biblioteca privada:
$ rpm -qp foo-1.0-1.x86_64.rpm
:
libprivate.so()(64bit) foo = 1.0-1.fc19 foo(x86-64) = 1.0-1.fc19
-
Observe que
libprivate.so()(64-bit)
parece ser el único símbolo que RPM extrajo para este paquete. Tenga en cuenta que, en 32-bit, el símbolo proporcionado serálibprivate.so
, por lo que su expresión regular debe capturar ambos. -
Agregue las exclusiones al archivo de especificaciones tanto para los requisitos como para los suministros:
[...]
%global _privatelibs libprivate[.]so.*
%global __provides_exclude ^(%{_privatelibs})$
%global __requires_exclude ^(%{_privatelibs})$
[...]
Puedes consultar un ejemplo más complejo en la lista de correo: https://lists.fedoraproject.org/pipermail/devel/2012-June/169190.html. Puede ser un problema de mantenimiento si el desarrollador original cambia los nombres de sus bibliotecas privadas, pero es la única solución por ahora. Quizás exista una solución mejor en https://lists.osuosl.org/pipermail/rpm-maint/2013-January/003349.html, pero aún no hay planes concretos sobre cuándo se codificarán.
Extensiones específicas de la arquitectura para lenguajes de scripting
por ejemplo, para garantizar que un paquete perl-*
específico de la arquitectura no proporcione ni requiera cosas que no debería, podríamos usar una invocación como esta:
# No queremos proporcionar bibliotecas de extensión privadas de Perl
%{?perl_default_filter}
%{_docdir}
filtrando
Por política, ningún elemento bajo %{_docdir}
no está permitido "proporcionar" ni "requerir" nada. Podemos evitar esto impidiendo que se analice cualquier elemento bajo %{_docdir}
:
# no queremos proporcionar ni requerir nada de _docdir, según la política
%global __provides_exclude_from ^%{_docdir}/.*$
%global __requires_exclude_from ^%{_docdir}/.*$
Información Adicional
Puede encontrar información adicional sobre el generador de dependencias de RPM aquí: https://rpm-software-management.github.io/rpm/manual/dependency_generators.html
Want to help? Learn how to contribute to Fedora Docs ›