From Fedora Project Wiki

< How to create an RPM package

Revision as of 00:32, 29 September 2012 by Eduleo (talk | contribs) (→‎Subpaquetes: Corrección ortográfica)

Configure su cuenta en su sistema

Instalación de software necesario:

 # yum groupinstall "Development Tools" 
 # yum install rpmdevtools
 # yum install rpmlint
Important.png
Una sugerencia es utilizar un usuario aparte para crear paquetes RPM en su sistema , de esa forma, si algo va terriblemente mal, podrá simplemente tirar al cesto de la basura todo el entorno y volver a empezar sin presión de perder datos personales en su directorio /home.
 # useradd makerpm

Una vez ingresado al sistema con el usuario adecuado:

 # [makerpm@movix ~]$ rpmdev-setuptree

El programa "rpmdev-setuptree" creará el directorio "rpmbuild" en su directorio $HOME, En dicha estructura existen una serie de subdirectorios tales como SPECS y BUILD que usted utilizará para crear sus paquetes. El programa "rpmdev-setuptree" también crea el archivo "~/.rpmmacros" que provocará que rpm y rpmbuild lo utilicen cuando sea necesario.

Una vez que ha configurado su cuenta, normalmente no habrá necesidad de volver a ejecutar estos pasos nuevamente.

Fundamentos en la construcción de un RPM

Para crear un paquete RPM usted necesitará crear un archivo de texto ".spec" que suministre la información acerca del software que será empaquetado. Luego usted podrá ejecutar el comando "rpmbuild" sobre dicho archivo spec lo que provocará ejecutar una serie de pasos para producir sus paquetes.

Normalmente usted deberá colocar sus fuentes originales (prístinas), archivos tales como .tar.gz provistos por los desarrolladores originales, en "~/rpmbuild/SOURCES". Usted deberá colocar su archivo .spec en "~/rpmbuild/SPECS" y nombrarlo "NOMBRE.spec" donde NOMBRE es el nombre (base) del paquete. Para crear todos los paquetes, tanto binario como fuente, usted deberá cambiarse al directorio "~/rpmbuild/SPECS" y ejecutar:

rpmbuild -ba NOMBRE.spec

rpmbuild invocado de esta manera leerá el archivo .spec e intentará ejecutar las siguientes, en ese orden (los nombres que comienzan con % so macros predefinidos y que luego se comentarán, los directorios sobre los que se actúa son listados):

Etapa Lee Escribe Acción
%prep %_sourcedir %_builddir Se leen la fuentes y parche en el directorio fuente %_sourcedir (usualmente ~/rpmbuild/SOURCES). Se desempaca las fuentes al subdirectorio bajo el directorio de construcción %_builddir (usualmente ~/rpmbuild/BUILD/) y se aplican los parches.
%build %_builddir %_builddir Se compilan los fuentes localizados en el directorio de construcción %_builddir (usualmente ~/rpmbuild/BUILD/). Esto se hace comunmente implementando alguna variación de "./configure ; make".
%check %_builddir %_builddir Verifica que el software funciona correctamente. Esto es usualmente implementado ejecutando alguna variación de "make test". Muchos paquetes no implementan esta etapa.
%install %_builddir %_buildrootdir Se leen los archivos en el directorio de construcción %_builddir (usualmente ~/rpmbuild/BUILD/) y se escribe en el directorio raíz de construcción %_buildrootdir (usualmente ~/rpmbuild/BUILDROOT). Los archivos que son escritos son los que se suponen que sean instalados cuando el paquete binario sea instalado por el usuario final. Esté al tanto de la terminología algo extraña, el "directorio raíz de construcción" no es lo mismo que el "directorio de construcción". Esta etapa usualmente se implementa ejecutando "make install".
bin %_buildrootdir %_rpmdir Se leen los archivos bajo el directorio raíz de construcción %_buildrootdir (usualmente ~/rpmbuild/BUILDROOT/) para crear los paquetes binarios RPM en el directorio RPM %_rpmdir (usualmente ~/rpmbuild/RPMS/). Dentro del directorio RPM hay un directorio para cada arquitectura y un directorio "noarch" para los paquetes a los cuales no les aplica la arquitectura. Los archivos RPM son los paquetes para que los usuarios instalen.
src %_sourcedir %_srcrpmdir Esto crea un paquete fuente RPM (.src.rpm) dentro del directorio fuente RPM %_srcrpmdir (usualmente ~/rpmbuild/SRPMS). Estos archivos son necesarios para revisar y actualizar los paquetes.

Como puede notar, algunos directorios tienen propósitos específicos en rpmbuild. Estos son:

Nombre del macro Nombre Usualmente Propósito
%_specdir Directorio especificaciones ~/rpmbuild/SPECS Archivos de especificaciones RPM (.spec).
%_sourcedir Directorio fuente ~/rpmbuild/SOURCES Paquete fuente prístina (e.g., tarballs) y parches.
%_builddir Directorio de construcción ~/rpmbuild/BUILD Archivos fuente son desempacados y compilados en un subdirectorio bajo este directorio.
%_buildrootdir Directorio raíz de construcción ~/rpmbuild/BUILDROOT Los archivos son instalados bajo este directorio durante la etapa %install .
%_rpmdir Directorio binario RPM ~/rpmbuild/RPMS Los binarios RPM son creados y almacenados bajo este directorio.
%_srcrpmdir Directorio fuente RPM ~/rpmbuild/SRPMS Los fuente RPM son creados y almacenados bajo este directorio.

Si falla alguna etapa, deberá revisar la salida para ver por qué falló, y deberá cambiar el archivo .spec (u otra entrada) en la medida de lo necesario.

Preparándose a empaquetar un programa específico

Si hay necesidad de instalar paquetes especiales para construir o ejecutar su programa a empaquetar, instale dichos programas y anote dónde se encontraron (usted necesitará la información).

Para empaquetar un programa usted debe empaquetar los fuentes originales (pristine) junto a los parches y las instrucciones de construcción. En general no es aceptable comenzar con un código precompilado. Instale el archivo con la fuente original (usualmente un archivo tar.gz) en el directorio "~/rpmbuild/SOURCES" de la cuenta de usuario para construcción de rpms.

Lea el manual de instrucciones para instalación de su programa, usted deberá automatizar esas tareas por medio de la edición de un archivo ".spec" así que deberá entender qué es lo que se supone debe hacer antes. Es probable que sea mejor que intente un "dry run", realizando el procedimiento de instalación sin hacerlo con RPM (esto es especialmete cierto si usted no está familiarizado con RPM).

Intente reusar lo que pueda. Asegúrese que no está empacando algo que ya se encuentra empaquetado, usted puede encontrar la lista de paquetes en Fedora Package Collection en Fedora Package Database. Verifique también In Progress Review Requests (paquetes que actualmente están bajo revisión) y la lista Retired Packages. Garantizado ello, vea si alguien más ha comenzado a empaquetarlo para Fedora. Google por "PROGRAMNAME Fedora rpm" o similar, tal vez puede comenzar por dónde otra persona más quedó. Puede usar http://cvs.fedoraproject.org/viewcvs/rpms/ directamente para ver los archivos .spec (y parches) de cualquier paquete similar que ya se encuentre en Fedora. Usted puede descargar los fuentes RPMs utilzando un programa del paquete yum-utils:

   $  yumdownloader --source nombre-del-paquete

Alternativamente un fuente rpm (source rpm) puede ser descargado manualmente explorando algunos de los repositorio Fedora (ya sea via http o ftp). Seleccione releases/12/Everything/source/SRPMS (remplace "12" con la versión Fedora que desea) y descargue el fuente RPM de su elección (terminan en .src.rpm).

Una vez descargue el fuente RPM, ejecute el comando siguiente para instalar los fuentes a partir del src.rpm (como el usuario escogido, makerpm):

  $ rpm -ivh sourcepackage-name*.src.rpm

Este coloca el archivo .spec del paquete en el directorio ~/rpmbuild/SPECS y los otros fuentes y parches ~/rpmbuild/SOURCES).

También puede desempaquetar el .src.rpm en un directorio utilizando rpm2cpio:

  $ mkdir NOMBREDEPROGRAMA_src_rpm
  $ cd NOMBREDEPROGRAMA_src_rpm
  $ rpm2cpio ../NOMBREDEPROGRAMA-*.src.rpm | cpio -i

Algunas veces es más fácil comenzar con un paquete existente y luego limpiarlo y prepararlo para Fedora. RPM Find RPM puede ayudarle a encontrar rpms para sistemas diferentes a Fedora. Usted puede instalar fuentes RPMs de otros sistemas de la misma forma que para los de Fedora. Si eso falla, usted puede localizar archivos de paquetes fuentes (no los paquetes binarios .deb) en Ubuntu o Debian (los paquetes fuentes son tarbals estandar posiblemente con un subdirectorio "debian"/ asociado a los archivos de parches). Si "FreeBSD".http://www.freebsd.org/ports/installing.html lo tiene, usted podrí­a descargar de ftp://ftp.freebsd.org/pub/FreeBSD/ports/ports/ports.tar.gz y ver si la información de empaquetado existente le ayuda como punto de partida.

Sin embargo, a veces eso no ayuda en nada. Las diferentes distribuciones tienen diferentes reglas y lo que hacen en algunos casos puede ser inapropiado para Fedora.

Creando un archivo spec

Usted ahora necesita crear un archivo ".spec" en el directorio "~/rpmbuild/SPECS". Usted debería nombrarlo de acuerdo al nombre del programa, ej. "programa.spec", use el nombre de archivo o el nombre publicado por el autor del software. Creando un archivo spec en blanco¶

Cuando usted está creando un archivo spec por primera vez, puede crear su versión inicial utilizando emacs o vim, ellos crearán una plantilla para usted.

 $ cd ~/rpmbuild/SPECS
 $ vi program.spec

Abajo un ejemplo de como luce la plantilla creada:

Name:        
Version:    
Release:    1%{?dist}
Summary:    
Group:        
License:    
URL:        
Source0:    
BuildRoot:    %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires:    
Requires:    
%description
%prep
%setup -q
%build
%configure
make %{?_smp_mflags}
%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
%clean
rm -rf %{buildroot}
%files
%defattr(-,root,root,-)
%doc
%changelog

Usted puede tener $RPM_BUILD_ROOT en vez de %{buildroot}; sólo por consistencia.

Usted puede también usar el comando rpmdev-newspec para que le cree un nuevo archivo spec. rpmdev-newspec NOMBRE-DE-UN-NUEVO-PAQUETE le puede crear un archivo spec inicial para un nuevo paquete que se puede ajustar a varios tipos de paquetes. Este programa intentará adivinar qué tipo de plantilla basándose en el nombre del paquete, o usted puede especificarle una plantilla particular, vea las plantillas disponibles en /etc/rpmdevtools/spectemplate-*.spec . Vea rpmdev-newspec --help para más información. Por ejemplo, para crear un nuevo archivo spec para un módulo python:

cd ~/rpmbuild/SPECS
rpmdev-newspec python-antigravedad
vi python-antigravedad.spec

Un ejemplo: eject

Sigue un ejemplo simple, un paquete Fedora 9 para el programa "eject":

Summary: A program that ejects removable media using software control
Name: eject
Version: 2.1.5
Release: 11%{dist}
License: GPL
Group: System Environment/Base
Source: http://metalab.unc.edu/pub/Linux/utils/disk-management/%{name}-%{version}.tar.gz
Source1: eject.pam
Patch1: eject-2.1.1-verbose.patch
Patch2: eject-timeout.patch
Patch3: eject-2.1.5-opendevice.patch
Patch4: eject-2.1.5-spaces.patch
Patch5: eject-2.1.5-lock.patch
Patch6: eject-2.1.5-umount.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
URL: http://www.pobox.com/~tranter
ExcludeArch: s390 s390x
BuildRequires: gettext
BuildRequires: automake
BuildRequires: autoconf
BuildRequires: libtool
%description
The eject program allows the user to eject removable media (typically
CD-ROMs, floppy disks or Iomega Jaz or Zip disks) using software
control. Eject can also control some multi-disk CD changers and even
some devices' auto-eject features.
Install eject if you'd like to eject removable media using software
control.
%prep
%setup -q -n %{name}
%patch1 -p1 -b .versbose
%patch2 -p1 -b .timeout
%patch3 -p0 -b .opendevice
%patch4 -p0 -b .spaces
%patch5 -p0 -b .lock
%patch6 -p1 -b .umount
%build
%configure
make
%install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} install
# pam stuff
install -m 755 -d %{buildroot}/%{_sysconfdir}/pam.d
install -m 644 %{SOURCE1} %{buildroot}/%{_sysconfdir}/pam.d/%{name}
install -m 755 -d %{buildroot}/%{_sysconfdir}/security/console.apps/
echo "FALLBACK=true" > %{buildroot}/%{_sysconfdir}/security/console.apps/%{name}
install -m 755 -d %{buildroot}/%{_sbindir}
pushd %{buildroot}/%{_bindir}
mv eject ../sbin
ln -s consolehelper eject
popd
%find_lang %{name}
%clean
rm -rf %{buildroot}
%files -f %{name}.lang
%defattr(-,root,root)
%doc README TODO COPYING ChangeLog
%attr(644,root,root) %{_sysconfdir}/security/console.apps/*
%attr(644,root,root) %{_sysconfdir}/pam.d/*
%{_bindir}/*
%{_sbindir}/*
%{_mandir}/man1/*
%changelog
* Wed Apr 02 2008 Zdenek Prikryl <zprikryl at, redhat.com> 2.1.5-11
- Added check if device is hotpluggable
- Resolves #438610

Usted tambien puedes usar el "BuildRoot:" en vez de acceso desde la plantilla, aunque ambas son aceptables, la opción desde la plantilla es la preferida.

Explicando las partes de un archivo spec

El RPM Guide, section on creating RPMs, describe los detalles de cómo rellenar un archivo spec.

La serie developerWorks en "Packaging software with RPM" Part 1 , Part 2 , y Part 3 son también útiles.

Maximum RPM tiene la información más completa, pero no es reciente.

Usted deberá seguir los lineamientos Fedora, tales como los especificados en Package Naming Guidelines, Packaging Guidelines y Package review guidelines.

Usted puede insertar comentarios precediendo la línea con "#", pero no inserte macros-potencialmente-multilineas, palabras que comiencen con "%", en un comentario, los macros son expandidos primero. Si está comentando una línea, doble los simbolos de porcentaje ("%%"). Tampoco use comentarios inline ("#") en la misma línea justo después de un comando script.

Aquí se comentan los campos/areas principales que deberá rellenar:

  • Name: El nombre (base) del paquete. Debe estar conforme a las normas Package Naming Guidelines. En muchos casos, será todo en letras minúsculas. En cualquier lugar del archivo spec usted puede referirse al nombre utilizando el macro %{name} - de esa forma, si el nombre cambia, el nuevo nombre será utilizado por esas otras locaciones donde se utiliza. Este nombre debería coincidir con el nombre de archivo del archivo spec.
  • Version: El número de versión aguas arriba (upstream). Vea Packaging/Naming guidelines - package version para más información. Si la versión no es numérica (contiene marcas que no son números o dígitos), puede que necesite incluir caracteres no numéricos adicionales en el campo release. Si aguas arriba se usan fechas completas para distinguir las versiones, considere usar números de versión de la forma yy.mm[dd] (de tal que la liberación 2008-05-01 se convierte en 8.05). En cualquier lugar del archivo spec, refiérase a este valor como %{version}.
  • Release: El valor inicial de release debería normalmente ser "1%{?dist}". Entonces, incremente el número cada vez que libere un nuevo paquete para la misma versión de software. Si se está empaquetando y liberando una nueva versión del software, el número de versión debería ser cambiado para reflejar la nueva versión de software y el número de liberación (release) debería ser restablecido a 1. Vea Name Guidelines - package release para más información. Packaging/DistTag describe la marca "dist", la cual no es requerida pero puede ser útil. Use %{release} para reusar este valor.
  • Summary: Una breve, de una línea, descripción del paquete. Use Inglés Americano, y no termine con punto.
  • Group: Este debe ser un nombre de grupo existente, como "Applications/Engineering", ejecute "less /usr/share/doc/rpm-*/GROUPS" para ver la lista completa. Si usted crea un subpaquete, "...-doc" con documentation, use el grupo "Documentation".
  • License: La licencia, para software, debe ser una licencia de fuente abierta. Use las abreviaciones estandar, e.g., "GPLv2+". Intente ser específico, e.g., use "GPLv2+" (GPL version 2 or greater) en vez de solo "GPL" o "GPLv2" cuando esto sea cierto. Vea Licensing y lo lineamientos en Licensing Guidelines para más información. Usted puede listar múltiples licencias combinándolas con "and" y "or", e.g., "GPLv2 and BSD". Llame a esta marca "License", no use la marca antigua "Copyright".
  • URL: El URL para conseguir más información acerca del programa, e.g., el sitio web del proyecto. Nota: Este NO es de donde provino el código fuente original, vea "Source" (a continuación!).
  • Source0: El URL para conseguir el archivo comprimido que contiene los fuentes (originales) prístinas, como se ha liberado aguas arriba. "Fuente" es sinónimo de "Source0". Si usted define un URL completo (y debería), su nombre base será utilizado cuando se busque en el directorio SOURCES. Si posible, agregue %{name} y %{version}, así los cambios a cualquiera de ellas irá al lugar adecuado. Alerta: Source0: y URL: son diferentes , normalmente ambos son URLs, pero la entrada "URL:" apunta al sitio web del proyecto, mientras que "Source0:" apunta al archivo que contiene el código fuente (y es típicamente un archivo .tar.gz). Como está anotado en los lineamientos, "cuando descargue fuentes, parches, etc, considere usar un cliente que preserve las marcas de tiempo aguas arriba. Por ejemplo wget -N o curl -R. Para hacer el cambio algo global para wget, agregue lo siguiente a su ~/.wgetrc: timestamping = on, and for curl, agregue a su ~/.curlrc: -R." Si existe más de un fuente, nómbrelos como Source1, Source2, y así. Si está agregando nuevos archivos completos además de las fuentes prístinas, usted puede listar cada uno como fuentes también, pero lístelos después de las fuentes prístinas. Una copia de cada una de estas fuentes serán incluídas en cualquier paquete fuente que cree (a menos que específicamente le indique lo contrario). Vea "Packaging/SourceURL"https://fedoraproject.org/wiki/Packaging/SourceURL para más información de casos especiales (uso de control de revisión, cuando aguas arriba usa código prohibido, etc).
  • Patch0: El nombre del primer parche que aplicará al código fuente. Si necesita parchar los archivos después de descomprimir, usted debería editar los archivos, salvar sus diferencias como archivo "patch" en su directorio ~/rpmbuild/SOURCES. Los parches deberían hacer un único cambio lógico, así que muy probable que tenga múltiples archivos de parches (patch).
  • BuildRoot: Esto es dónde los archivos serán "instalados" durante el proceso "%install" (que ocurre después de proceso de compilación build). Normalmente usted debería dejar esta línea sin modificación, bajo la configuración Fedora usual, este será un macro que creará un directorio nuevo especial bajo /var/tmp. La próxima versión por salir de RPM ignorará este valor y en su lugar la raíz de construcción será "{_topdir}/BUILDROOT/".
  • BuildRequires: Una lista separada por comas de paquetes requeridos para construir (compilar) el programa. Estos no son determinados automáticamente, así que usted debe incluir todo lo necesario para construir el programa. Hay algunos pocos paquetes que son tan comunes en las compilaciones que usted no necesitará mencionarlos, tal como "gcc"; vea Packaging Guidelines para ver la lista completa de paquetes que puede omitir. También puede especificar versiones mínimas requeridas, si es necesario, asi: "ocaml >= 3.08". Usted puede tener más de una línea de BuildRequires (en cuyo caso son todas ellas requeridas para compilación). Si necesita el archivo /EGGS, puede obtener su paquete corriendo "rpm -qf /EGGS"; si EGGS es un programa, usted determina su paquete rápidamente ejecutando rpm -qf which EGGS". Intente especificar la menor cantidad posible de paquetes necesarios para construir apropiadamente el paquete ya que cada uno desacelerará el proceso una construcción basada en "mock" (e.g., intente usar sed en vez de perl si realmente no necesita las habilidades de perl). Tenga cuidado, algunas aplicaciones deshabilitan permanentemente funciones si su paquete no es detectado durante la compilación, en dichos casos puede que necesite incluir dichos paquetes adicionales.
  • Requires: Una lista de paquetes separados por coma que son requeridos cuando el programa es instalado. Note que la lista de paquetes para Requires (lo que es requerido cuando se instala/ejecuta) y BuildRequires (lo que se requiere para compilar el RPM binario) son independientes, un paquete puede estar presente en una lista pero no en la otra o pudiera estar en ambas listas. Las dependencias de los paquetes binarios son en muchos casos automáticamente detectadas por rpmbuild asi que es común el caso de que no se requiere especificar Requires para nada. Pero si desea resaltar algunos paquetes como requeridos, o requerir algún paquete que rpm no pueda detectar, entonces agréguelo aquí.
  • %description - Una descripción más larga del programa, multilínea. Use Inglés Americano. Todas las líneas deben ser de ochenta (80) caracteres o menos. Se asume que las líneas en blanco son párrafos separados. Algunos programas de instalación GUI reformatearán los párrafos, la líneas que comienzan con un espacios en blanco, tales como espacio o tabulador, serán tratados como texto preformateado y lo mostrarán tal cual es, normalmente con una fuente de ancho fijo (de acuerdo a RPM Guide).
  • %prep - Comandos guión para "preparar" el programa, esto es, descomprimirlo tal que esté listo para construcción (compilación). Típicamente es sólo "%setup -q" o alguna variación, una variación común es "%setup -q -n NAME" si el archivo fuente desempaca en NAME. Vea la sección "%prep" abajo para más detalles.
  • %build - Comandos guión para "construir" el programa, esto es, compilarlo y alistarlo para instalación. El programa debería venir con instrucciones de cómo hacerlo. Vea la sección "%build" abajo para más detalles.
  • %check - Comandos guión para auto-probar el programa. Estos se ejecutan justo después de %build y antes de %install, así que debería colocarlo si usted tienen dicha sección. A menudo simplemente contiene "make test" o "make check". Esto es aparte de %build asi que las personas pueden saltarse la auto-prueba si lo desean. Esto no tampoco está documentando en muchas partes.
  • %install - Comando guión para "instalar" el programa. Los comandos deben copiar los archivos desde el "directorio de construcción" %{_builddir} (que estaría debajo de ~/rpmbuild/BUILD) en el directorio raíz de construcción, %{buildroot} (que normalmente estaría bajo /var/tmp). Vea la sección "%install" abajo para más detalles.
  • %clean - instrucciones para limpiar la raíz de construcción. Típicamente: rm -rf %{buildroot}
  • %files - la lista de archivos que serán instalados. Vea la sección "%files" para más detalles.
  • %changelog - Cambios en el paquete. Use el formato que se especifica abajo.
  • ExcludeArch: Si el paquete no compila exitosamente, construye o funciona en una o más arquitecturas dadas, entonces dichas arquitecturas deberían ser listadas en el spec con la marca ExcludeArch.
  • Usted puede agregar secciones de tal forma que su código será ejecutado cuando los paquetes sean instalados o removidos en el sistema real (en oposición a sólo ejecutar el guión %install, que sólo seudoinstala a la raíz de construcción). Estos se denominan "scriptlets", y son usualmente utilizados para actualizar el sistema en ejecución con la información contenida en el paquete. Vea la sección "Scriptlets" para más detalles.

No use las marcas "Packager" o "Vendor". No use la marca "Copyright" - use en su sustitución "License".

No cree un paquete "relocalizable" - ellos no agregan valor en Fedora aún y complican las cosas.

RPM soporta subpaquetes, esto es, un único archivo spec puede generar varios paquetes binarios. Por ejemplo, si la documentación es muy larga, usted puede generar un subpaquete aparte "-doc". Vea más detalles abajo.

Sección %prep

La sección "%prep" describe cómo desempacar los paquetes comprimidos y asi poderlos luego, construir. Típicamente es un conjunto de comando "%setup" y/o %patch, que referencian Source0, Source1, etc.

Vea Maximum RPM section on %setup and %patch para más detalles.

Alerta: En los archivos spec, no use comentarios en-línea (un "#" en la misma línea después de un comando), y no coloque macros (palabras que comienzan con "%") en un comentario a menos que lo cite con "%" como "%%". Los macros pueden provocar fallos si se comentan porque ellos siempre son expandidos (incluso en líneas comentadas) y pueden expandir a múltiples líneas. Esto es cierto para %prep, %build, y subsiguientes.

La nueva serie RPM 4.4.2.x agregó dos nuevos macros, %{patches} y %{sources}, con los que puede hacer cosas como:

for p in %{patches}; do
...
done

Estos nuevos macros pueden ser muy poderosos si tiene una larga lista de parches o fuentes. Sin embargo, mantenga presente que usarlos hará su spec incompatible con el rpm utilizado en Fedora 9 y anteriores, RHEL, y muchas otras distribuciones basadas en RPM. Sección %prep: comando %setup El comando "%setup" desempaquete un paquete fuente y toma varias opciones (switches). Normalmente usted usará -q (quiet/silencioso) para evitar que los ajustes sean visibles a cada cambio de archivo que se desempaqueta. Abajo le mostramos otras opciones diferentes aparte de -q:

  • -n nombre: Si el nombre del rpm es algo diferente a lo que la Fuente desempaca, use esta opción para establecer el nombre a donde desempaquetar. E.G., si el tarball desempaca en el directorio MINOMBRE, use %setup -q -n MINOMBRE.
  • -c nombre: Si el tarball no desempaca en un único directorio, esto crea un directorio nombre y luego desempaca en él. Es útil si usted tiene uno de esos molestos tarballs que no tienen un único directorio embutido en ellos.

Estas son más opciones %spec si está desempaquetando múltiples archivos, que es primordialmente útil si está creando subpaquetes (vea más abajo). Las más importantes son:

  • -a número Sólo desempaqueta la directiva fuente de número dado, tal como –a 0 para source0:, después de cambiarse al directorio.
  • -b número Sólo desempaqueta la directiva fuente de número dado, tal como –b 0 para source0:, antes de cambiarse al directorio.
  • -D No eliminar el directorio antes de desempaquetar.
  • -T Deshabilita el desempaquetado automático de archivos.

Sección %prep: comandos %patch

El comando "%patch0" aplica el parche 0 (similar para 1, 2, etc.). La opción "-pNUMERO" aplica, simplemente pasa el argumento a patch. Los nombres de los archivos parche usualmente lucen como "telnet-0.17-env.patch",esto es, -{version}-propósito_del_parche.patch , algunas personas omiten - %{version}. Los archivos parche son típicamente el resultado de un comando "diff -u", si usted hace eso desde el subdirectorio de ~/rpmbuild/BUILD, usted no tiene que especificar -p level después. Usted puede usar todas las formas normales de crear achivos parche. Si usted está creando un archivo parche para un archivo único NOMBREDEARCHIVO, una forma común de hacerlo es copiar a NOMBREDEARCHIVO.orig, modificarlo, y luego guardar el resultado como "diff -u NOMBREDEARCHIVO.orig NOMBREDEARCHIVO":

cp X/Y.Z X/Y.Z.orig
vim X/Y.Z
diff -u X/Y.Z.orig X/Y.Z > ~/rpmbuild/SOURCES/PKGNAME.REASON.patch

Si editará muchos archivos, un método fácil es copiar el subdirectorio completo bajo BUILD, y luego hacer diffs por subdirectorio, una vez que se encuentre en BUILD/loquesea, usted puede hacer:

cp -pr . ../NOMBREDEPAQUETE.orig
... muchas ediciones ...
diff -u ../NOMBREDEPAQUETE.orig . > ~/rpmbuild/SOURCES/NOMBREDEPK.RASON.patch   << ojo aqui, no entendí bien, ver el original si duda.

Si usted edita muchos archivos en un parche, también puede copiar los archivos originales utilizando una finalización consistente como ".orig" antes de editarlos. Luego, puede usar "gendiff" (en el paquete rpm) para crear un parche con las diferencias. Vea "man gendiff" para más información.

Intente asegurar que su parche el "contexto" hace coincidencia exacta. Por omisión, patch intentará aplicar los parches incluso cuando la coincidencia es imprecisa con valor "fuzz" de 2, pero "el nuevo RPM para Fedora 10!:http://lwn.net/Articles/289235/ cambiará el valor por omisión de fuzz a 0. Usted puede darle la vuelta agregando "%define _default_patch_fuzz 2", pero es mejor no tener el problema.

Usted debería enviar su parche hacia aguas arriba, y documentar en su archivo spec el email/bug de aguas arriba que lo incluye. Vea PatchUpstreamStatus .

Sección %prep : Archivos sin modificación

Algunas veces usted empaquetará un archivo simple que no requiere ser descomprimido, e.g., un "Source1:" que simplemente es un archivo PDF. Esto no aplica desde fuentes externas, e.g., tal vez usted ha creado unos archivos adicionales que no se encontraban en los fuentes originales de tal que el paquete instale limpiamente en Fedora. Usted puede "prep" esos archivos en el directorio de construcción haciendo lo siguiente (remplace "1" con el número adecuado):

 cp -p %SOURCE1 .

Sección %build

La sección "%build" es algunas veces complicada, aquí usted configura y compila/construye los archivos a ser instalados.

Muchos programas siguen la forma GNU configure (o alguna variación). Por omisión, instalarán con prefijo "/usr/local" (/usr/local/bin, /usr/local/lib, etc.), que es un valor por omisión razonable para archivos desempaquetados. Sin embargo, ya que usted está empaquetándolo, deseará cambiar el prefijo (prefix) a "/usr" ya que desde ahora este es un paquete mantenido por el sistema mismo. Si hay librerías, ellas deben ser instaladas en el directorio adecuado que es /usr/lib o /usr/lib64 dependiendo de la arquitectura (el valor actual está en %{_libdir}).

Ya que el sistema "configure" de GNU es tan común, rpm predefine un macro denominado "%configure", que invoca el GNU configure con las opciones adecuadas (e.g., cambia --prefix a /usr). Esto significa que alguna variación de esto usualmente funcionará como comando de construcción:

 %configure
 make %{?_smp_mflags}

Algunas veces usted querrá sobrescribr las variables de un archivo makefile, ello lo puede lograr fácilmente pasándolas como parámetros a make, así:

make %{?_smp_mflags} CFLAGS="%{optflags}" BINDIR=%{_bindir}

Si necesita hacerlo complicado con el configure-GNU generado, dele un vistazo a GNU autoconf, automake, and libtool . Una buena presentación al respecto al igual que de "make" es Open Source Development Tools: An Introduction to Make, Configure, Automake, Autoconf by Stefan Hundhammer .

Algunos programas usan Cmake. Vea algunas sugerencias en Empaquetando con cmake .

Si incluye algunas autopruebas (y ello es buena idea), colóquelas en una sección "%check" aparte inmediatamente después del área "%build", en vez de incluir dichas pruebas en %build. De esta forma será fácil para el sistema saltarse las pruebas innecesarias.

Sección %check

La sección"%check" hace pruebas, usualmente es "make test". Esto no está documentado en mucha otras fuentes de información RPM.

Sección %install

La sección "%install" es un conjunto de guiones (scripts) para "instalar" el programa. Los comandos en esta sección deberían copiar los archivos del directorio dentro del "directorio de construcción" %{_builddir} (normalmente ~/rpmbuild/BUILD/_algo_) hacia el directorio raíz de construcción, %{buildroot} (normalmente /var/tmp/_algo_ o ~/rpmbuild/BUILDROOT), creando los directorios dentro de %{buildroot} en la medida de lo necesario.

Cuidado: la terminología puede ser algo confusa en algunos casos:

  • El directorio de construcción (build directory), bajo el cual ocurren las compilaciones durante %build, y la raíz de construcción (build root), donde los archivos son copiados durant el el proceso %install, son diferentes. El objeto del proceso %install es copiar archivos, tales como los archivos bajo el directorio de construcción, al lugar correcto en la raíz de construcción. Tal vez "buildroot" debiése llamarse "installroot", pero es demasiado tarde ahora, la terminología está muy anidada.
  • El directorio de construcción es normalmente ~/rpmbuild/BUILD, mientras que la raíz de construcción, donde se instalan los archivos durante install, es normalmente ~/rpmbuild/BUILDROOT. La etapa %prep normalmente creará un subdirectorio bajo el directorio de construcción como parte de %setup y lo poblará con archivos, basándose en información fuente en %_sourcedir, que es típicamente en ~/rpmbuild/SOURCES. Durante %build, el directorio actual de hecho comenzará siendo %{buildsubdir}, ese nuevo subdirectorios creado bajo el directorio de construcción. Típicamente %{buildsubdir} es algo como ~/rpmbuild/BUILD/{name}-%{version}.
  • El guión "%install" no es utilizado cuando el paquete binario rpm es instalado por el usuario final. El término "%install" es confuso, de hecho el guión no debe instalar el programa en las ubicaciones REALES finales (e.g., en /usr/bin), sino bajo el buildroot %{buildroot}.

Normalmente el guión install primero borrará el directorio, luego hará alguna variación de "make install" (idealmente utilizando DESTDIR={buildroot}, si el programa lo soporta. Abajo un ejemplo de una sección %install:

%install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} INSTALL="install -p" CP="cp -p" install

Idealmente cada programa tendrá un comando "make install" que soporte la convención DESTDIR. Si el programa incluye un "make install" que soporte DESTDIR, cuando sea posible, úselo. La convención DESTDIR soporta redireccionar las instalaciones de archivos para descender de un director5io específico, que es exactamente lo que se desea durante %install.

Instalar un programa que no soporte DESTDIR puede ser mucho más difícil y ninguna otra opción mejor como el soporte nativo a DESTDIR. Considere estas alternativas:

  • Parchar el makefile de tal que sí soporte DESTDIR. Cree los directorios dentro de DESTDIR cuando sea necesario (siéntase libre de usar "mkdir -p", la opción "-p" es ahora estandar y ampliamente soportada). Asegúrese de enviar el parche aguas arriba.
  • Use "%makeinstall". Muchos documentos antiguos acerca de RPM sugieren usar "%makeinstall", que puede funcionar si "make install" no soporta DESTDIR. Sin embargo, así como se indica en los lineamientos Fedora, el macro makeinstall "NO debe ser usado cuando make install DESTDIR={buildroot} funcione. makeinstall es (meramente) una forma improvisada que puede funcionar con Makefiles que no hacen uso de la variable DESTDIR...". Desafortunadamente, esto a veces tiene fallas imprevistas, por lo que %makeinstall no deber ser usado si DESTDIR funciona. La razón está basada en el cómo funciona %makeinstall. El macro "%makeinstall" expande a algo como "make prefix={buildroot}%{_prefix} bindir=%{buildroot}%{_bindir} ... install". Muchos programas recompilarán silenciosamente o cambiarán partes del programa cuando valores como prefix cambian, resultando en una instalación incorrecta. Vea los lineamientos Fedora si desea urgar en los detalles de por qué este método puede fallar. Usted probablemente necesitará crear los directorios apropiados dentro de buildroot antes de llamar a %makeinstall (e.g., mkdir -p %{buildroot}{_bindir}/).
  • Considere usar el paquete auto-destdir. Esto requiere "BuildRequires: auto-destdir", y cambiar "make install" a "make-redir DESTDIR=%{buildroot} install". Esto sólo funciona bien si la instalación usa sólo ciertos comandos para instalar archivos, como cp e install, vea "man make-redir" para los detalles.
  • Haga la instalación "a mano", esto es, en vez de invocar un sistema de construcción, copie los archivos a las ubicaciones correctas. Básicamente esto sería una secuencia de creación de directorios que aún no existiesen y no fuesen creados por los "BuildRequires" de paquetes (típicamente usando install -d o mkdir -p), seguida del copiado de archivos del directorio actual (dentro del directorio de construcción) hacia el directorio raíz de construcción (tipicamente usando "cp -p" y/o "install -p"). Ejecutar "make -n install" puede hacer más fácil el determinar cuál es la secuencia que debiése seguirse. Asegúrese de crear los directorios dentro de %buildroot cuando sea necesario. Un problema serio con esta técnica es que es fácil fallar al instalar archivos nuevos o renombrados durante una actualización, asi que si hay una mejor técnica, úsela. Si usted hace una instalación "a mano", tenga especial cuidado con las actualizaciones. Por ejemplo:
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}%{_bindir}/
cp -p mycommand %{buildroot}%{_bindir}/

De acuerdo a los lineamientos, "cuando agregue comandos de copiado en el archivo spec, considere usar el comando que preserve las marcas de tiempo de los archivos, eg. cp -p o install -p". Si, el makefile le permite sobrescribir el comando install (típicamente llamado INSTALL), usted podría poner algo como INSTALL="install -p" CP="cp -p" como parámetros make, así:

make INSTALL="install -p" CP="cp -p" DESTDIR=%{buildroot} install

Sección %files

La sección %files identifica los archivos y directorios agregados por el paquete, y así entonces, cuáles archivos y directorios son propiedad del paquete. La propiedad es importante, cuando usted tipea "rpm -qif bla" usted podrá visualizar a quién pertenece bla .

Fundamentos %files

La sección %files normalmente comienza con una línea %defattr que define los permisos de los archivos por omisión. El formato de la línea es %defattr(<permisos de achivo>, <usuario>, <grupo>, <permisos de directorio>), esto significa que puede especificar los permisos que aplican a los archivos y directorios en la sección %files. El cuarto parámetro es a veces omitido. Usualmente se usa %defattr(-,root,root,-), donde "-" significa "use los permisos por omisión".

Esta línea es seguida por nombres o patrones de directorios o archivos que serán instalados y propiedad de este paquete. Usted debería usar macros para los nombres de directorio, e.g., use %{_bindir}/miarchivo en vez de /usr/bin/miarchivo, y %{_sbindir}/killaccount en vez de /usr/sbin/killaccount. Si un nombre o patrón comienza con"/" cuando se expande, entonces se presume que ha sido copiado en %{buildroot} seguido de dicho patrón, cuando se instale en sistema final, será copiado en ese nombre sin el prefijo buildroot. Si usted no precede con "/", entonces se presume estar en el directorio actual (e.g., dentro del directorio de construcción) - esto se usa para archivos de "documentación". Asi que si su paquete sólo instala /usr/bin/micomando, entonces su sección %files podría ser simplemente:

%files
%defattr(-,root,root,-)
%{_sbindir}/mycommand

Cualquier archivo o directorio identificado en la sección %files es propiedad del paquete que lo define. Usted debería asegurarse que declare la propiedad para cada nuevo archivo o directorio que el paquete cree. Puede utilizar wildcards (*) que abarquen a un grupo de archivos, esto hace que el paquete sea menos sensible a los cambios. Por ejemplo, usted puede declarar que todos los archivos que fuesen copiados en en %{buildroot}/usr/bin fuesen propiedad de este paquete declarando:

%{_bindir}/*

Note que "%{_bindir}/*" no reclama que este paquete es dueño del directorio /usr/bin - reclama que todos los archivos que fueron instalados dentro del build root 's /usr/bin son propiedad del paquete. Si usted lista un directorio in la sección files, entonces usted está reclamando que este paquete es dueño de ese directorio y todos sus archivos en él, recursivamente (todos hacia abajo ) si están presentes en la raíz de construcción. No liste los directorios "/usr/bin" o "{_bindir}" directamente en sus lista files porque ello reclamaría la propiedad de /usr/bin y todo dentro de él. El reclamar la propiedad de "{_bindir}/*" está bien, ya que sólo reclama la propiedad de los subdirectorio y archivos que usted coloque bajo /{_bindir}. Si crea un subdirectorio tal como /{name}, (/usr/share/NAME), usted debería incluir el directorio en la lista %files:

%{_datadir}/%{name}/

Usualmente es más fácil utilizar wildcards para los nombres de archivo, y también es mejor que copiar con cambios aguas arriba. La documentación antigua RPM típicamente muestra largos listados bajo %files con nombres individuales, tal como /usr/bin/programa1 seguido de /usr/bin/programa2. Debido a la forma como Fedora usar buildroots ahora, esto ya no es necesario.

Es un eror si ningún archivo hace coincidencia con el wildcard en la línea, así que sólo liste los directorios que de hecho importan. Tampoco puede identificar el mismo archivo o directorio más de una vez. Finalmente, es un error tener algo en el buildroot y no listado bajo %files, el punto de copiar algo en el buildrott es porque usted pretende tenerlo instalado en el sistema final. Si usted no pretende eso, remueva dichos archivos durante el proceso %install.

También es posible excluir archivos de la coincidencia anterior utilizando el glob %exclude. Esto puede ser útil para incluir "casi todo" los archivos que hacen coincidencia con glob diferente. Sin embargo, note que, como cualquier otro glob, incluso el glob %exclude fallará si no hace coincidencia con algo. Esto puede parecer contraintuitivo ya que el objetivo es esencialmente asegurarse de que cierto archivo NO esté ahí, así que esta regla es particularmente importante que la recuerde.

Prefjos %files

Usted puede necesitar agregar uno o más prefijos a la entrada %files (si es más de una, use espacio en blanco para separarlos).

Típicamente hay una entrada "%doc" con una lista de archivos de documentación que no fueron copiados en el buildroot, usualmente al menos hay un archivo README y un archivo LICENSE. Usted debe incluir un archivo para la licencia, si es que hay uno. Puede prefijar algunos de éstos con attr (mode, user, group) para definir los permisos del archivo, el usuario y el grupo. Usted no necesita reclamar la propiedad del directorio /usr/share/doc/{name}, ello es automático. Cualquier entrada %doc no debe afectar la aplicación en tiempo de ejecución (si está en %doc, el programa debe ejecutarse apropiadamente si no están presentes).

Si usted guarda archivos de configuración (bajo /etc - no los coloque bajo /usr), debería prefijarlos con %config(noreplace) a menos que esta versión de programa use un formato de configuración no compatible hacia atrás (en cuyo caso, prefíjelos con %config).

Prefijar las entradas %files con "%attr(mode, user, group)" le permite establecer los permisos para archivos particulares, e.g., "%attr(0644, root, root)". Un "-" significa "usa los valores por omisión".

Si un archivo está en un lenguaje natural particular, use %lang para anotarlo. E.G.:

%lang(de) %{_datadir}/locale/de/LC_MESSAGES/tcsh*

Algunas documentaciones dicen que %license y %readme son prefijos válidos, no lo son, en Fedora. Use en sustitución %doc.

%files y el Filesystem Hierarchy Standard (FHS)

Usted debería seguir el estandar Filesystem Hierarchy Standar, i.e., los ejecutable de aplicaciones ordinarias van en /usr/bin, los archivos de configuración global en /etc, las librerías ordinarias en /usr/lib, y así, con una excepción, los ejecutables que no deberían normalmente ser ejecutados por usuarios o administradores, deberían ir al subdirectorio /usr/libexec, usualmente usted se referirá al directorio necesario como "%{_libexecdir}/%{name}".

Usted no debería instalar archivos bajo /usr/local, allí es donde van los archivos no empaquetados. Típicamente existirá un atributo "prefijo" que le permitirá definir el prefijo para que sea "/usr" en vez de "/usr/local".

Desafortunadamente las rutinas "normales" de instalación de muchos programas no siguen el FHS. En particular muchos programas colocarán la librerías dependientes de la arquitectura bajo /usr/lib, en vez de bajo /usr/share como lo manda el FHS. El FHS /usr/lib section indica que /usr/lib para datos "dependientes" de la arquitecturar (e.g., archivos ELF como los archivos .so), mientras que /usr/share es para datos "independientes" de la arquitectura. De esa forma, los sistemas con diferentes CPUs pueden compartir /usr/share. Hay muchas excepciones a esta regla en Fedora (e.g., Python y Perl), pero Fedora aplica esta regla lo más estrictamente que otras distribuciones. Note, por ejemplo, que rpmlint se quejará si usted coloca cualquier otra cosa que archivos ELF en /usr/lib.

Ejemplo %files

Aqui sigue un ejemplo simple de una sección %files:

%files
%defattr(-,root,root,-)
%doc README LICENSE
%{_bindir}/*
%{_sbindir}/*
%{_datadir}/%{name}/

Scriptlets

Usted puede agregar secciones de tal que el código correrá cuando los paquetes sean instalados o removidos en el sistema real (en oposición a solo correr el guión %install, que sólo hace una pseudoinstalación en la raíz de construcción). Estos son denominados "scriptlets", y son usualmente utilizados para actualizar el sistema en ejecución con información existente en el paquete.

Los scriptlets en %pre y %post se ejecutan antes y después de la instalación (respectivamente). Los scriptlets %preun and %postun son ejecutado antes y después de que el paquete es desinstalado, respectivamente. Los scriptlets %pretrans y %posttrans son ejecutados al comienzo y al final de la transacción. Vea Packaging/ScriptletSnippets para más ejemplos y detalles. Por ejemplo, cada RPM binario que almacena librerías compartidas (no sólo symlinks) en cualquier de las rutas por omisión del enlazador dinámico, debe llamar a ldconfig en %post y %postun (post-install y post-uninstall). Si el paquete tiene múltiples subpaquetes con librerías, cada subpaquete debería también tener una sección %post/%postun que llame a /sbin/ldconfig. Por ejemplo:

%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig

Alerta: La opción "-p" especifica cual _command proccesor _ usar para los comandos en las siguientes líneas. Si no hay líneas siguientes, entonces si usa /sbin/ldconfig como el "command processor" es una mejora menor en eficiencia comparada con colocar "/sbin/ldconfig" en la siguiente línea y dejando al shell que lo invoque. Esto es así por que al usar la opción "-p" el shell no es invocado simplemente para invocar un único programa. Pero si tiene múltiples comando shell, no use "-p" o /sbin/ldconfig después! En sustitución, déjese en blanco, e incluya los comando shell justo abajo.

Si va a ejecutar programas en scriptlets, ellos deben estar instalados antes de que los ejecute. Usted debe usar variantes especiales de la marca "Requires:" de tal forma que el programa sea instalado antes de que se intente usar. Estas son las formas "Requires(CONTEXTO):", e.g., "Requires(post)".

La mayoría de los scriptlets (%pre, %post, %preun, y %postun) proveen un argumento que puede usar, accesible via $1, que es el número de paquetes de este nombre que será puesto en el sistema una vez que se complete la acción.

No compare y pregunte por la igualdad a 2, pruebe si es mayor o igual que 2 ya que los usuarios se las pueden arreglar para tener múltiples versiones del paquete instalados simultáneamente. Para %pretrans y %posttrans, $1 es siempre 0.

Por ejemplo, después de agregar un manual info al sistema, el archivo dir que indexa los manuales info debería ser actualizado. Básicamente, después que instale el manual info, necesita ejecutar el programa install-info. Eso está bien, excepto que install-info es parte del paquete info y no hay garantía de que info esté instalado a menos que lo requiramos. Igualmente, si "install-info" falla, no queremos fallar todo el procesamiento. Abajo mostramos una forma de hacerlo:

Requires(post): info
Requires(preun): info
...
%post
/sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || :
%preun
if [ $1 = 0 ] ; then
/sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
fi

Otro habilitado tipo scriptlet son los triggers. Usted puede definir triggers (disparadores) para cuando otros paquetes son instalados o desinstalados. Vea Maximum RPM para más información acerca de los triggers o disparadores.

Macros

Los archivos spec pueden contener referencias a macros (textos que comienzan con "%"), que son remplazados con otros valores. Usted puede seguir % con una palabra, e.g., "%name", pero al igual que las variables shell usted debe ponerle llaves {...} si le siguen letras o dígitos justo después, e.g., "%{name}". Como se menciona en Packaging Guidelines, hay dos estilos de referenciar algunos valores como rpm Build Root y las banderas de optimización:

  • "estilo macro": %{buildroot}, %{optflags}
  • "estilo variable": $RPM_BUILD_ROOT, $RPM_OPT_FLAGS

Escoja un estilo y úselo consistentemente cuando empaquete, este documento usa "estilo macro".

Abajo una lista de macros típicos:

Macro Expansión Típica
%{_bindir} /usr/bin
%{_builddir} ~/rpmbuild/BUILD (directorio de construcción, vea %buildsubdir)
%{buildroot} /var/tmp/... buildroot, donde los archivos se "instalan" durante %install
%{buildsubdir} /{name} donde se compilan los archivos durante %build. Es bajo %{_builddir}, puesto después de %setup.
%{_datadir} /usr/share
%{_defaultdocdir} /usr/share/doc
%{dist} Distribución+nombre corto de versión (e.g., ".fc9")
%{fedora} Número de liberación fedora (e.g., 9)
%{_includedir} /usr/include
%{_infodir} /usr/share/info
%{_initrddir} /etc/rc.d/init.d
%{_libdir} /usr/lib
%{_libexecdir} /usr/libexec
%{_localstatedir} /var
%{_mandir} /usr/share/man
%{name} Nombre de paquete, definido por marca Name:
%{_sbindir} /usr/sbin
%{_sharedstatedir} /usr/com
%{_sysconfdir} /etc
%{_sysconfdir} /etc
%{version} Versión de paquete, definido por marca Version:

Para más macros puede ver en /etc/rpm/* y los archivos "macros" bajo "/usr/lib/rpm/", especialmente /usr/lib/rpm/macros. También puede usar "rpm --showrc" para mostrar los valores que rpm utilizará para todas las opciones configuradas en los archivos rpmrc y archivos de configuración de macro.

Usted puede definir su propio conjunto de valores macro utilizando %define, asegúrese de definirlos antes de usarlos. Las definiciones de macro puede referenciar otros macros. Por ejemplo:

%define myvalue 50

Usted puede usar rpmbuild para descubrir el valor de algún macro utilizando la opción "-E" (--eval). Por ejemplo, para ver la expansión de %{_bindir} en myfile.spec, usted puede ejecutar:

rpmbuild -E '%{_bindir}' myfile.spec

Packaging/RPMMacros tiene más información acerca de los macros, al igual que RPM Guide chapter 9.

Otras marcas

Anotamos anteriormente las marcas "Requires" y "BuildRequires". Hay unas otras marcas más para controlar las dependencias: Provides, Obsoletes, Conflicts, y BuildConflicts.

  • "Provides:" le permite listar nombres de paquete virtual que este paquete provee. Algunas veces hay diferentes paquetes que pueden proveer la funcionalidad y usar paquetes (using packages) no importa cual. En ese caso (aclarar), cada uno de los paquetes que provee la funcionalidad deberían "proveer" un paquete virtual y entonces usando packages puede listar el nombre de paquete virtual bajo "Requires:". Por ejemplo, distintos paquetes puede proveer "latex", si usted depende del paquete virtual "tex(latex)", entonces los usuarios pueden escoger qué paquete obtener para obtener "latex" de él. Si usted provee paquetes virtuales, puede que tambien quiera usar sistema de alternativas, pero sea cuidadoso: los ajustes de las "alternativas" son a nivel del sistema, así que si múltiples usuarios en el mismo sistema quieren valores por omisión diferentes, no utilice este sistema. Usted puede encontrar lo que un paquete provee, tanto virtual como no-virtual, consultando "rpm -q --provides NOMBREDEPAQUETE". Algunos paquetes virtuales en Fedora son:
    • MTA : Nombre usado para Mail Transport Agents, tal como Postfix.
    • tex(latex) : Nombre usado para latex.
  • "Obsoletes:" le permite declarar que instalando este paquete debería (normalmente) provocar la remoción de los otros paquetes nombrados. Esto es útil cuando un nombre de paquete cambia, o cuando un paquete remplaza completamente a un paquete diferente.
  • "Conflicts:" le permite declarar cuáles paquetes no pueden ser instalados simultáneamente con este. Obviamente, intente evitar esto si puede, vea Packaging/Conflicts si cree que necesita usarlo.
  • "BuildConflicts:" le permite declarar qué paquetes no pueden ser instalados cuando se construye este paquete. Obviamente, intente evitar esto si puede.

Usted puede controlar qué arquitecturas un paquete construye (o no construye). Por ejemplo, si su paquete no puede compilar en ppc, usted puede hacer:

ExcludeArch: ppc

También existe la marca "ExclusiveArch". Las arquitecturas válidas que se pueden especificar en estas marcas están listadas en la sección Arquitecturas.

Subpaquetes

Un archivo spec puede definir más de un paquete binario, e.g., cliente y servidor, o paquetes runtime y developer. Si hay una gran cantidad de documentación, puede ser dividida en subpaquetes NOMBRE-doc. Usted siempre tendrá un archivo spec y un fuente RPM (SRPM), incluso si hay múltiples RPM binarios que ellos generan. Un archivo spec que produce múltiples paquetes binarios tiene aún así un único proceso de creación, así que existe secciones únicas %prep, %build, %check, e %install que crean todos los archivos para todos los paquetes.

En un archivo spec use la directiva %package para iniciar la definicón de un subpaquete:

%package sub_package_name

Por omisión, el nombre de subpaquete es PACKAGE_NAME, "-", SUBPACKAGE_NAME, usted puede utilizar "-n" para invalidar este comportamiento y construir un nuevo nombre:

%package -n new_sub_package_name

Después de la directiva %package, liste las marcas (tags) para el subpaquete. Debería incluirse como mínimo las marcas "Summary:" y "Group:" y las directivas "%description SUBPACKAGE_NAME" y "%files SUBPACKAGE_NAME". Cualquier cosa no especificada por el subpaquete será heredado de su padre.

Para las directivas, si usó "-n" con %package, usted lo necesitará nuevamente para estas directivas. Usted necesita especificar el nombre para las otras directivas, e.g., %pre y %post, si las usa en el subpaquete.

Vea la sección acerca de subpaquetes de RPM Guide para más información.

Condicionales

Usted puede insertar declaraciones condicionales. Es decir, usted puede probar si está creando un binario para una arquitectura dada con:

%ifarch ARCHITECTURE_NAME

the negated version with:

%ifnarch ARCHITECTURE_NAME

O la forma más general de condicional:

%if TRUE_OR_FALSE

Opcionalmente existe una sección "%else", todas las seccciones se cierran con "%endif".

Lineamientos específicos de aplicación

Existen muchos lineamientos específicos a las aplicacioens que pueden ayudarle (e.g., para lenguajes de programación específicos, aplicaciones, librerías, y sistemas de construcción). Muchos de ellos se listan como parte de Application Specific Guidelines of Packaging/Guidelines. Ejemplos de lineamientos específicos a la aplicación son aquellos para :

De fallar eso, otras formas de encontrar ayuda específica a la aplicación son:

Algunas otras pistas

Si desea ver muchos ejemplos de scriptlets, usted puede mostrar todos los scriptlets de los programas instalados utilizando:

rpm -qa --queryformat "

PACKAGE: %{name} " --scripts | less

La siguiente página tiene información acerca de los errores comunes que se cometen: [Packaging/FrequentlyMadeMistakes] .

No intente interactuar con el usuario, RPM está diseñado para soportar instalaciones en modo lote (batch). Si una aplicación necesita mostrar un EULA, eso sería parte de la ejecución inicial, no de la instalación.

Usted puede no querer iniciar ningún servicio, debido a que en una gran instalación eso puede frenar las cosas. Si instala un guión para init, considere usar chkconfig para arreglar que el servicio se arranque y detenga en el próximo reinicio del sistema. Antes de desinstalar usted debería normalmente intentar detener los servicios si están corriendo.

La desinstalación debería reversar la mayoría de los cambios hechos durante la instalación, pero no remueva ningún archivo creado por el usuario.

Normalmente, si existen binarios ejecutables, un paquete separado "debug" se crea con los simbolos, y los simbolos son removidos de los paquetes normales binarios. Si esto no debiese ocurrir, usted puede deshabilitar la creación del paquete y remoción con:

%define _enable_debug_package 0
%define debug_package %{nil}
%define __os_install_post /usr/lib/rpm/brp-compress %{nil}

Una forma de verificar la versión de Fedora en un archivo spec para construcción condicional es:

%if 0%{?fedora} <= <version>

El ? provoca que el macro evalúe a blanco si %fedora no está definido, y ello provoca que el resultado final sea "0", que es un número y en consecuencia aceptable, mientras que no interfiere con el resultado si de hecho hay un valor definido para %fedora.

Note que el truco anterior NO FUNCIONA en Koji "scratch" builds - %fedora es puesto durante la creación del fuente RPM. En consecuencia, este truco funciona en Koji ya que le sistema extrae las fuentes de los fuente RPM y reconstruye el fuente RPM con el valor apropiado de %fedora.

También existen algunas recomendaciones y trucos controversiales en [PackageMaintainers/Packaging_Tricks] .

Los programas GUI deben tener una entrada desktop (de tal forma que las personas puedan invocarla desde un menú gráfico). El desktop entry spec (para archivos .desktop) y icon theme spec definen cómo hacerlo (e.g., como usar /usr/share/icon). Algunos documentos antiguos acerca de RPM tienen la mayor cantidad de información, pero algunos de estos documentos antiguos hacen algunas afirmaciones que ya no son ciertas:

  • Los archivo rpm ya no son colocados en un directorio compartido /usr/src/redhat. Esta es una forma obsoleta de usar rpm y no es recomendada. Los sistemas modernos definen %{_topdir} en vez de ~/rpmbuild.
  • El proceso %install no instala archivos en su ubicación final. En cambio, "instala" los archivos en buildroot.
  • El comando "rpm" ya no crea paquetes (e.g., "rpm -ba" fue alguna vez legal). Use el programa aparte "rpmbuild" para dichos propósitos.

Prueba rápida con rpmplint

Antes de intentar contruir nada, usted puede intentar ejecutar rpmlint sobre su archivo spec:

rpmlint program.spec

Este programa atajará muchos errores de forma temprana. Si el error reportado no tiene sentido, ejecute nuevamente con la opción "-i" (esta opción ofrece mensajes de error más explicativos).

Generalmente, usted no debería tener errores de rpmlint, pero algunas veces rpmlint es excesivamente ruidoso. Los lineamientos de empaquetamiento Fedora explican cuáles mensajes ignorar, e.g., ignore los erro"no-packager-tag" y "no-signature".

Vale la pena revisar http://wiki.mandriva.com/es/Problemas_comunes_RpmLint para saber cómo ajustar el archivo spec en ciertas circunstancias.

Creando RPMs a partir del archivo spec

Una vez que ha creado su archivo spec, digamos "programa.spec", usted puede crear los RPM fuente y binario simplemente corriendo:

$ rpmbuild -ba program.spec

Esto intentará ejecutar las siguientes etapas:

  • 1. Etapa %prep (preparación), que descomprime e instala los fuentes y parches en %_builddir (subdirectorio en ~/rpmbuild/BUILD).
  • 2. Etapa %build, que construye (e.g., compila) los archivos a ser instalados en %_buildir. Usualmente esto es algún equivalente a "make".
  • 3. Etapa install, que copia los archivos del directorio de construcción %_buildir (que estarí­a bajo ~/rpmbuild/BUILD) en el directorio buildroot, %{buildroot}. El directorio buildroot es definido por un previo "BuildRoot:", si lo deja a su valor normal que comienza con %{_tmppath}/{name}..., entonces el buildroot sería dentro de /var/tmp.
  • 4. Crea los RPM fuente y binario (archivos .rpm y .src.rpm). Los archivos binario RPM son creados utilizando la información de la lista %files.

Tenga cuidado: el "directorio de construcción" (donde ocurre la compilación durante %build) y la "raíz de construcción" (donde serán instalados los archivos durante %install) son diferentes .

Cuando las cosas salen mal, usted puede hacer "cd" al directorio apropiado y mirar que quedó allí. Si desea evitar etapas tempranas, use la opción "--short-circuit", esto es útil si ya tiene una construcción exitosa y un error en la sección %install. Por ejemplo, para reiniciar la etapa %install (saltando las etapas previas), haga lo siguiente:

 $ rpmbuild -bi --short-circuit program.spec

Si tiene éxito, encontrará sus RPMs bianrios en el subdirectorio "~/rpmbuild/RPMS/", y los fuente RPMs en "~/rpmbuild/SRPMS".

Si sólo desea crear el fuente RPM (.src.rpm), haga lo siguiente estando en el directorio SPECS:

rpmbuild -bs program.spec

Esto creará el fuente RPM en ~/rpmbuild/SRPMS. Crear solamente el fuente rpm (.src.rpm) es relativamente rápido porque rpm simplemente necesita copiar el archivo .spec y los SOURCES asociados en el archvio .src.rpm. Crear el rpm binario toma mucho más tiempo porque requiere que se ejecuten los guiones %prep, %build e %install.

Probar los RPMs construídos

Si usted hace "cd" al directorio "~/rpmbuild/RPMS", y luego cd al subdirectorio de la arquitectura especí­fica, encontrará algunos rpms binarios. Usted puede rápidamente ver sus archivos y permisos utilizando rpmls (verifique que sea lo que usted espera):

$ rpmls *.rpm

Ejecute rpmlint sobre el RPM "binario" (rpmlint trabaja sobre archivos .spec, RPMs binarios y RPMs fuentes, encontrando diferentes cosas en cada uno):

$ rpmlint *.rpm

Si esto luce bien, puede intentar convertirse en root e instalarlos:

# rpm -ivp XYZ1.rpm XYZ2.rpm XYZ3.rpm ...

Luego puede probarlos. Si es una herramienta de lí­nea de comandos, puede invocarla sin necesidad de prefijar con /usr/bin? Si es una herramienta GUI, ¿se muestra en el menú? (si no, algo está mal con su entrada .desktop).

Luego puede desinstalarlos usando:

# rpm -e XYZ1 XYZ2 XYZ3

Si todo ello funciona, puede usar Mock para hacer prueba rigurosa de que usted tiene los requerimientos para construcción adecuados. Vea PackageMaintainers/MockTricks para más información acerca de cómo usar Mock, una vez que su cuenta sea miembro del grupo "mock", puede ejecutar comandos como el siguiente para realizar pruebas locales:

$ mock -r fedora-9-i386 rebuild path_to_source_RPM

Una vez que Mock funcione en su sistema, puede usar Koji (que usa Mock) para hacer compilaciones en diferentes sistemas, algunos de los cuales usted puede que no tenga. Unirse_Mantenedores_de_Paquetes y PackageMaintainers/UsingKoji tienen más información acerca de Koji.

Una vez configurado, usted puede probar su RPM fuente en variedad de plataformas ejecutando comandos como el siguiente:

$ koji build --scratch dist-f9 path_to_source_RPM

Uste puede sustituir dist-f9 por dist-f8, dist-f10, etc., para intentar construir para otras versiones. No use "dist-rawhide", ello no es realmente rawhide. Recuerde, los valores %fedora, %fc9, etc., no serán correctos para un "scratch build", así­ que no funcionarán si su archivo spec hace algo diferente basándose en esos valores.

Sus compilaciones koji sólo pueden depender de paquete de hecho están en el repositorio de la distribución OBJETIVO. En consecuencia, usted no puede usar koji para construir para distribuciones liberadas si su paquete depende de otros nuevos paquete que Bodhi no haya liberado aún. Usted "puede" usar koji para construir para rawhide (la próxima versión aún no liberada), incluso si depende de otros paquetes nuevos en la medida que los otros paquetes hayan sido construidos en la sección "devel" del CVS como se describe abajo.

Si necesita compilar versus un paquete que aún no está en una liberación estable, puede generar un ticket a rel-eng en: https://fedorahosted.org/rel-eng/newticket y solicitar que dicho paquete sea agregado como "buildroot override".

Herramientas útiles

El paquete "rpmdevtools" contiene una serie de herramientas útiles, "rpm -qil rpmdevtools" le mostrará qué es lo que instala. Una herramienta útil en particular es rpmdev-bumpspec que tiene la siguiente forma:

rpmdev-bumpspec --comment=COMMENT --userstring=NAME+EMAIL_STRING SPECFILES

rpmdev-bumpspec resaltará la marca release en los archivos specs y agrega un comentario al changelog con el formato correcto de fecha/hora y versión. COMMENT tí­picamente deberí­a comenzar con "- ".

De forma simular "yum-utils" posee una serie de herramientas especí­ficas a yum. "yumdownloader" es especialmente útil, usted puede descargar el RPM fuente de un paquete simplemente ejecutando "yumdownloader --source NOMBREDEPAQUETE. Luego puede entonces usar "rpm -U NOMBREPAQUETEFUENTE" para instalar los archivos fuentes. E.G., "yumdownloader --source glib; rpm -Uvh glib*.src.rpm".

Puede que le sea útil RUST (GPL). Es un herramienta GUI para creación RPM "drag&drop" y también es una herramienta para crear cajas de pruebas (sandoxing) que le permite ejecutar instalaciones de software dentro de un entorno chrooted y automáticamente generar RPMs para código fuente arbitrario, sin siquiera ver el archivo spec.

Si está creando archivos spec, puede ayudar el determinar %files. Note que, sin embargo, que ello no crea archivos spec, ni tampoco crea paquetes de calidad adecuada para los repositorios Fedora, es una herramienta principalmente para crear paquetes binarios RPM rápida y suciamente (Nota: ya no se encuentra más en "rusthq.com".)

Alien convierte entre formatos de paquetes. No producirá RPMs fuente limpios, pero convertir un paquete existente puede proveerle cierta información útil.

Lineamientos y reglas

Cuando usted cree sus paquetes, necesitará seguir las siguientes reglas y lineamientos:

   * Unirse Mantenedores de Paquetes - describe el proceso para convertirse en un mantenedor de paquetes Fedora.
   * Packaging Guidelines
   * Package Naming Guidelines
   * Dist Tag Guidelines
   * Package Review Guidelines

Existen muchos guí­as oficiales de lineamientos que le ayudarán con sus circunstancias especí­ficas (programas Java programs, programas OCaml, programas GNOME, etc.), el Packaging Guidelines incluye una referencia cruzada a dichas guí­as. También puede aprender a partir de las secciones SIGs y Package Maintainers. También puede ver la lista completa de páginas Wiki acerca de Empaquetamiento para ver si alguna aplica a su circunstancia.

En caso de que ello falle, puede encontrar recomendaciones útiles en los borradores no oficiales Packaging Drafts y Packaging Drafts To Do. Obviamente estos no son oficiales. Puede encontrar algunas ideas a partir de SuSE , Debian , pero recuerde las distribuciones difieren en sus reglas , así­ que no presuma que pueden ser utilizadas directamente.

Los archivos .spec que usted cree deben ser igualmente de código libre, como se nota en el CLA.

Mantenimiento de paquetes

Una vez que su paquete sea aceptado, usted, o sus comantenedores, deben mantenerlo. Vea el Package update HOWTO y el Package update guidelines para más información.

Si usted actualiza la versión en múltiples liberaciones de Fedora, hágalo "hacia atrás" en el tiempo, e.g., libere para Fedora N, luego, una vez aceptado, Fedora N-1 (el sistema presume que las versiones mas recientes de Fedora poseen la misma o más recientes versiones de programas).

Para más información

La página Package Maintainers enlaza a muchas otras páginas útiles y Updating Package HOWTO describe como actualizar un paquete existente que ya usted mantiene en Fedora.

Para más información, fuera de este sitio, y del Wiki de Fedora, vea:

  • How to build RPM packages on Fedora - vistazo breve
  • Packaging software with RPM (developerWorks) Part 1 , Part 2 y Part 3 .
  • Fedora Packager's Handbook
  • When Sally met Eddie - un cuento simple, pero poco detalle.
  • Maximum RPM Book - la información más completa, pero en algunos casos, antigua/obsoleta.
  • RPM Guide, sección creando RPMs - esto tiene mucha buena información y es ligeramente más actualizada, pero es un borrador.
  • Developer's guide, section on building RPMs .
  • Creating RPMS slides de Guru Labs.
  • The fight, my first attempt to make a readable rpm package building introduction .
  • RPM Tutorial .
  • RPM HOWTO: RPM at Idle by Donnie Barnes .
  • RPM HowTo por Dawson.
  • SuSE build tutorial - es acerca de SuSE, no Fedora. Cross-distribution package HOWTO tiene algunas pistas si está creando un RPM para varias distribuciones.
  • Mandriva Rpm HowTo (alt ) es un tutorial RPM, para Mandriva (Mandrake). Nota: En Fedora no se recomprime los tarballs originales, como Mandriva sugiere porque ello cambiarí­a sus hash criptográficos.
  • Creating Your Own Linux RPM's - The Initial Software Build es otra introducción breve, pero anota acerca de que el proceso de construir RPMs es mucho más simple que crear paquetes para Solaris, menos pasos, y tiene la habilidad de agregar toda la información del software en un único archivo haciendo el proceso algo más compacto y fácil de modificar o reproducir para el caso del sistema de empaquetamiento de software.
  • All you need to know about RPM - más acerca de instalación de paquetes que acerca de crear paquetes.
  • El Wiki de rpm.org Wiki tiene algunas informaciones útiles, tal como la lista de problemas RPM conocidos .

Nota: El sitio de rpm5.org tien algo de documentación pero no dependa de ella, ese es el sitio del "fork" de RPM mantenido por Jeff Johnson. El RPM utilizado por Fedora y Novell/SuSE, está basado en rpm.org rpm.org. lwn.net tiene un breve artí­culo al respecto.