![]() |
|
Requisiti: build-essential, automake, gnupg, lintian, fakeroot e pbuilder. |
In questo esempio useremo il programma GNU hello come esempio. Puoi scaricare l'archivio dei sorgenti da ftp.gnu.org. Per questo esempio, useremo la directory ~/hello/
.
mkdir ~/hello cd ~/hello wget http://ftp.gnu.org/gnu/hello/hello-2.1.1.tar.gz
We will also compare our package to one that is already
packaged in the Ubuntu repository. For now, we will place
it in the ubuntu
directory so we can look at
it later. To get the source
package, make sure you have a "deb-src" line in your
/etc/apt/sources.list
file for the Main
repository. Then, simply execute:
mkdir ubuntu cd ubuntu apt-get source hello cd ..
![]() |
|
A differenza di molti comandi di apt-get, non hai bisogno dei permessi di root per scaricare il pacchetto sorgente perchè è scaricato nella directory corrente. Infatti è consigliabile usare apt-get source solo come utente normale, in modo da poter modificare i filie nel pacchetto sorgente senza aver bisogno dei privilegi di root. |
Questo è quanto compie il comando apt-get source:
Scarica il pacchetto sorgente. Un pacchetto sorgente di solito contiene un file .dsc che descrive il pacchetto e fornisce gli hash MD5 del pacchetto sorgente, un file .orig.tar.gz che contiene il codice sorgente degli autori originali e un file .diff.gz che contiene le modifiche applicate al codice sorgente comprensive delle informazioni di pacchettizzazione.
Scompatta il file .orig.tar.gz nella directory corrente.
Applica il file .diff.gz decompresso nella directory dei sorgenti.
Se hai scaricato manualmente il pacchetto sorgente (i file .dsc, .orig.tar.gz e .diff.gz), puoi scompattarli nello stesso modo di apt-get source usando dpkg-source in questo modo:
dpkg-source -x *.dsc
La prima cosa che dovrai fare è fare una copia dell'archivio originale (a volte chiamato "upstream") nel seguente formato: <nomepacchetto>_<versione>.orig.tar.gz
. Questo passaggio fa due cose. In primo luogo, crea due copie del codice sorgente. Se per sbaglio modifichi o cancelli la copia su cui stai lavorando puoi usare quella che hai scaricato. In secondo luogo è considerata non una buona tecnica di pacchettizzazione modificare l'archivio dei sorgenti originale se non strettamente necessario. Si veda la sezione chiamata “Errori comuni” per i motivi.
cp hello-2.1.1.tar.gz hello_2.1.1.orig.tar.gz tar -xzvf hello_2.1.1.orig.tar.gz
![]() |
|
L'underscore, "_", tra il nome del pacchetto (hello) e la versione (2.1.1), in contrapposizione al trattino, "-", è molto importante. Il tuo pacchetto sorgente non sarà compilato come un pacchetto nativo di Debian. |
Ora abbiamo una directory hello-2.1.1
contenente i file sorgente. Ora dobbiamo creare la solita directory debian dove sono contenute tutte le informazioni di pacchettizzazione, consentendoci di separare i file di pacchettizzazione da quelli dell'applicazione.
mkdir hello-2.1.1/debian cd hello-2.1.1/debian/
We now need to create the essential files for any Ubuntu
source package: changelog
,
control
, copyright
, and
rules
. These are the files needed to create
the binary packages (.deb files) from the original (upstream)
source code. Let us look at each one in turn.
Il file changelog
, come suggerisce il suo nome, è un elenco dei cambiamenti effettuati in ogni versione. Ha un formato predefinito che fornisce il nome del pacchetto, la versione, la distribuzione, le modifiche e chi e quando ha fatto le modifiche. Se hai una chiave GPG, assicurati di usare lo stesso nome e indirizzo di posta elettronica nel changelog
di quello riportato nella tua chiave. Il seguente è un modello di changelog
:
package (version) distribution; urgency=urgency * change details more change details * even more change details -- maintainer name <email address>[two spaces] date
Il formato (in particolar modo dedlla data) è importante. La data dovrebbe essere in formato RFC822, la quale può essere ottenuta dal programma 822-date.
Ecco un esempio del file changelog
per hello:
hello (2.1.1-1) edgy; urgency=low * New upstream release with lots of bug fixes. -- Captain Packager <packager@coolness.com> Wed, 5 Apr 2006 22:38:49 -0700
Osserva che la versione contiene un -1 in coda ad essa e si definisce revisione di Debian, la quale è usata in modo tale che i pacchetti possano essere aggiornati (per correggere bug per esempio) con nuovi caricamenti all'interno del medesima versione del file sorgente.
![]() |
|
Ubuntu and Debian have slightly different package versioning
schemes to avoid conflicting packages with the same
source version. If a Debian package has been changed in Ubuntu,
it has ubuntuX (where
X is the Ubuntu revision number)
appended to the end of the Debian version. So if the
Debian hello package was
changed by Ubuntu, the version string would be
|
Now look at the changelog
for the
Ubuntu source package that we downloaded earlier:
less ../../ubuntu/hello-2.1.1/debian/changelog
Notice that in this case the distribution is unstable (a Debian branch), because the Debian package has not been changed by Ubuntu. Remember to set the distribution to your target distribution release.
A questo punto crea un file changelog
nella directory debian
, dove dovresti già essere.
Il file control contiene le informazioni che il gestore di pacchetti (come apt-get, synaptic e aptitude) usa, le dipendenze di compilazioni, le informazioni del manutentore, e molto altro.
For the Ubuntu hello package, the control file looks something like:
Source: hello Section: devel Priority: optional Maintainer: Captain Packager <packager@coolness.com> Standards-Version: 3.6.1 Package: hello Architecture: any Depends: ${shlibs:Depends} Description: The classic greeting, and a good example The GNU hello program produces a familiar, friendly greeting. It allows non-programmers to use a classic computer science tool which would otherwise be unavailable to them. . Seriously, though: this is an example of how to do a Debian package. It is the Debian version of the GNU Project's `hello world' program (which is itself an example for the GNU Project).
Crea il control
usando le informazioni elencate (accertandoti di fornire i tuoi dati per il campo Maintainer).
Il primo paragrafo fornisce informazioni sul pacchetto sorgente. Analizziamo ogni riga:
Source: Questo è il nome del pacchetto sorgente, hello, in questo caso.
Section: I repository di apt sono suddivisi in sezioni per facilitare la consultazione e la catalogazione del software. In questo caso, hello appartiene alla sezione devel.
Priority: Questo campo assegna l'importanza del pacchetto per gli utenti. Dovrebbe essere una delle seguenti:
Required - pacchetti essenziali per il funzionamento del sistema. Se vengono rimossi, è altamente probabile che il tuo sistema verrà danneggiato in maniera irreparabile.
Important - un insieme minimale di pacchetti per avere un sistema utilizzabile. Rimuovendo questi pacchetti non causerà un malfunzionamento irreparabile del sistema, ma di solito sono considerati strumenti importanti senza i quali qualsiasi distribuzione GNU/Linux sarebbe incompleta. Nota bene: questa categoria on include pacchetti come Emacs o persino il sistema X Window.
Standard - Autoesplicativo.
Optional - questa categoria è dedicata in pratica per i pacchetti non richiesti, o per la maggior parte di essi. Comunque, questi pacchetti non devono essere in conflitto tra loro.
Extra - pacchetti che possono essere in conflitto con i pacchetti di una delle altre categorie. Viene inoltre usata per pacchetti specifici che potrebbero essere utili a persono che già conoscono l'utilità del pacchetto.
Maintainer: Il manutentore del pacchetto e l'indirizzo di posta elettronica.
Standards-Version: La versione della Policy di Debian alla quale il pacchetto è assoggettato (in questo caso, la versione 3.6.1). Un modo rapido per visualizzare la versione corrente è apt-cache show debian-policy | grep Version.
Build-Depends: Uno dei campi più importanti e spesso causa di bug, questa riga elenca i pacchetti binari (con versione, se necessario) che devono essere installati per creare il pacchetto binario a partire da quello sorgente. I pacchetti essenziali sono richiesti da build-essential e non devono essere inclusi nella riga Build-Depends. Nel caso di hello, tutti i pacchetti che servono fanno parte di build-essential, così la riga Build-Depends non è necessaria. L'elenco dei pacchetti di build-essentiaò può essere reperita in /usr/share/doc/build-essential/list
.
Il secondo paragrafo è relativo ai pacchetti binari che saranno creati a partire dai sorgenti. Se più pacchetti binari saranno creati dal pacchetto sorgente, dovrebbe esserci una sezione per emphasis>ognuno
Package: Il nome del pacchetto binario. Il più delle volte per programmi semplici (come hello), il nome dei pacchetti binario e sorgente sono identici.
Architecture: L'architettura per la quale saranno costruiti i pacchetti binari. Esempi possono essere:
all - I sorgenti non dipendono da una specifica architettura. I programmi che usano Python o altri linguaggi interpretati lo usano. Il pachetto binario risultante dovrebbe terminare in _all.deb
.
any - I sorgenti sono dipendono da una specifica architettura e dovrebbero compilarsi su tutte le architetture supportate. Ci sarà un pacchetto .deb per ciascuna architettura ( _i386.deb
per esempio)
A subset of architectures (i386, amd64, ppc, etc.) can be listed to indicate that the source is architecture-dependent and does not work for all architectures supported by Ubuntu.
Depends: L'elenco dei pacchetti che il pacchetto binario dipende per poter funzionare. Per hello, notiamo ${shlibs:Depends}
, una variabile che sostituisce le necessarie librerie condivise. Si veda la pagina di manuale di dpkg-source
per maggiori informazioni.
Recommends: Usato per pacchetti che sono caldamente raccomandati e solitamente sono installati con il pacchetto. Alcuni gestori di pacchetti, più precisamente aptitude, installano automaticamente i pacchetti raccomandati.
Suggests: Usato per pacchetti simili o utili al pacchetto che deve essere installato.
Conflicts: Usato per pacchetti che vanno in conflitto con questo pacchetto. Entrambi non possono essere installati contemporaneamente. Se uno di essi sta per essere installato, l'altro verrà rimosso.
Description: Sia la descrizione breve, sia quella lunga sono usate dai gestori di pacchetti. Il formato è:
Description: <singola riga> <descrizione estesa su più righe>
Osserva che c'è uno spazio all'inizio di ogni riga della descrizione lunga. Maggiori informazioni su come realizzare una buona descrizione possono essere trovate su http://people.debian.org/~walters/descriptions.html.
Questo file elenca le informazioni sul copyright. Di solito, le informazioni sul copyright sono riportate nel file COPYING
nella directory dei sorgenti del programma. Questo file dovrebbe includere informazioni quali il nome dell'autore e del creatore del pacchetto, l'URL dal quale provengono i sorgenti, una riga Copyright con l'anno e il detentore dei diritti d'autore e il testo del copyright stesso. Un modello d'esempio è simile a:
This package was debianized by {Il tuo nome} <la tua email> {Data} It was downloaded from: {URL o pagina Web} Upstream Author(s): {Nomi e indirizzi email degli autori} Copyright: Copyright (C) {Anno/i} by {Autore} {Indirizzo email} License:
As one can imagine, hello is
released under the GPL license. In this case it is easiest to
just copy the copyright
file from the
Ubuntu package:
cp ../../ubuntu/hello-2.1.1/debian/copyright .
Devi inserire il copyright completo a meno che non sia GPL, LGPL, BSD o Licenza Artistica, nel qual caso puoi fare riferimento al file corrispondente nella directory /usr/share/common-licenses/
.
Notice that the Ubuntu package's
copyright
includes a license statement for
the manual. It is important that all the
files in the source be covered by a license statement.
The rules
file is an executable
Makefile that has rules for building the binary package from
the source packages. For hello, it
will be easier to use the rules
from the Ubuntu package:
#!/usr/bin/make -f # Semplice file debian/rules - for GNU Hello. # Copyright 1994,1995 by Ian Jackson. # Ti concedo il permesso perpetuo e illimitato di copiare, # modificare e modificare la licenza di questo programma, # a patto che non rimuova il mio nome dal file medesimo. # (Asserisco i miei diritti morali di paternità sotto il decreto # Copyright, Designs and Patents Act del 1988.) # Questo file può essere modificato pesantemente package = hello docdir = debian/tmp/usr/share/doc/$(package) CC = gcc CFLAGS = -g -Wall INSTALL_PROGRAM = install ifeq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CFLAGS += -O2 endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) INSTALL_PROGRAM += -s endif build: $(checkdir) ./configure --prefix=/usr $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)" touch build clean: $(checkdir) rm -f build -$(MAKE) -i distclean rm -rf *~ debian/tmp debian/*~ debian/files* debian/substvars binary-indep: checkroot build $(checkdir) # Non ci sono file dipendenti da una specifica architettura da caricare # generati da questo pacchetto. Se ce ne fossero, sarebbero dovuti # essere fatti qui binary-arch: checkroot build $(checkdir) rm -rf debian/tmp install -d debian/tmp/DEBIAN $(docdir) install -m 755 debian/postinst debian/prerm debian/tmp/DEBIAN $(MAKE) INSTALL_PROGRAM="$(INSTALL_PROGRAM)" \ prefix=$$(pwd)/debian/tmp/usr install cd debian/tmp && mv usr/info usr/man usr/share cp -a NEWS debian/copyright $(docdir) cp -a debian/changelog $(docdir)/changelog.Debian cp -a ChangeLog $(docdir)/changelog cd $(docdir) && gzip -9 changelog changelog.Debian gzip -r9 debian/tmp/usr/share/man gzip -9 debian/tmp/usr/share/info/* dpkg-shlibdeps debian/tmp/usr/bin/hello dpkg-gencontrol -isp chown -R root:root debian/tmp chmod -R u+w,go=rX debian/tmp dpkg --build debian/tmp .. define checkdir test -f src/$(package).c -a -f debian/rules endef binary: binary-indep binary-arch checkroot: $(checkdir) test $$(id -u) = 0 .PHONY: binary binary-arch binary-indep clean checkroot
Procediamo su questo file in dettaglio. Una delle prime componenti che vedrai è la dichiarazione di alcune variabili:
package = hello docdir = debian/tmp/usr/share/doc/$(package) CC = gcc CFLAGS = -g -Wall INSTALL_PROGRAM = install ifeq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CFLAGS += -O2 endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) INSTALL_PROGRAM += -s endif
Questa sezione definisce i CFLAGS per il compilatore e gestisce anche le DEB_BUILD_OPTIONS noopt
e nostrip
per il debug.
Poi c'è la regola build
:
build: $(checkdir) ./configure --prefix=/usr $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)" touch build
Questa regola esegue ./configure con il prefix appropriato, esegue make e crea un file build
che indica il momento in cui è stato creato il pacchetto per prevenire compilazioni multiple errate.
La regola seguente è clean
, la quale esegue make -i distclean che rimuove i file creati durante il processo di creazione del pacchetto.
clean: $(checkdir) rm -f build -$(MAKE) -i distclean rm -rf *~ debian/tmp debian/*~ debian/files* debian/substvars
Poi c'è una regola binary-indep
vuota, dato che non sono stati creati file dipendenti da una specifica architettura in questo pacchetto.
Ci sono, però, diversi file dipendenti da una specifica architettura, quindi viene usata binary-arch
:
binary-arch: checkroot build $(checkdir) rm -rf debian/tmp install -d debian/tmp/DEBIAN $(docdir) install -m 755 debian/postinst debian/prerm debian/tmp/DEBIAN $(MAKE) INSTALL_PROGRAM="$(INSTALL_PROGRAM)" \ prefix=$$(pwd)/debian/tmp/usr install cd debian/tmp && mv usr/info usr/man usr/share cp -a NEWS debian/copyright $(docdir) cp -a debian/changelog $(docdir)/changelog.Debian cp -a ChangeLog $(docdir)/changelog cd $(docdir) && gzip -9 changelog changelog.Debian gzip -r9 debian/tmp/usr/share/man gzip -9 debian/tmp/usr/share/info/* dpkg-shlibdeps debian/tmp/usr/bin/hello dpkg-gencontrol -isp chown -R root:root debian/tmp chmod -R u+w,go=rX debian/tmp dpkg --build debian/tmp ..
Per prima cosa, questa regola richiama checkroot
per assicurarsi che il pacchetto venga costruito come root e richiama la regola build
per compilare i sorgenti. Quindi vengono creati i file debian/tmp/DEBIAN
e debian/tmp/usr/share/doc/hello
e gli script postinst
e prerm>
vengono installati in debian/tmp/DEBIAN
. Quindi viene eseguito make install con un prefix apposito che installa il pacchetto nella directory debian/tmp/usr
. In seguito i file della documentazione (NEWS, ChangeLog e il changelog di Debian) vengono compressi e installati. Viene invocato dpkg-shlibdeps per trovare le librerie condivise da cui dipende l'eseguibile hello, e ne registra l'elenco nel file debian/substvars
per la variabile ${shlibs:Depends} in control
. Quindi viene eseguito dpkg-gencontrol per creare un file di controllo per il pacchetto binario, applicando le modifiche create da dpkg-shlibdeps. Infine, dopo che i permessi di debian/tmp
sono stati assegnati, viene eseguito dpkg --build per costruire il pacchetto binario .deb che verrà collocato nella directory superiore.
The postinst
and
prerm
files are examples of maintainer
scripts. They are shell scripts that are executed after
installation and before removal, respectively, of the package. In the case of
the Ubuntu hello package, they
are used to install (and remove) the info file. Go ahead and
copy them into the current debian
directory.
cp ../../ubuntu/hello-2.1.1/debian/postinst . cp ../../ubuntu/hello-2.1.1/debian/prerm .
Ora che abbiamo analizzato in dettaglio i file nella directory debian
per hello, possiamo costruire il pacchetto sorgente (e binario). Per prima cosa entriamo nella directory principale dei sorgenti estratti:
cd ..
Ora costruiamo il pacchetto sorgente usando dpkg-buildpackage:
dpkg-buildpackage -S -rfakeroot
Il flag -S flag indica a dpkg-buildpackage di creare un pacchetto sorgente, mentre il flag -r flag gli indica di usare fakeroot per permettergli di avere privilegi di root apparenti durante la creazione del pacchetto. dpkg-buildpackage prenderà il file .orig.tar.gz
e produrrà un .diff.gz
(le differenze tra l'archivio originale dell'autore e la directory che abbiamo creato, debian/
and its contents) e un file .dsc
che contiene la descrizione e gli hash MD5 del pacchetto sorgente. I file .dsc
e *_source.changes
(utilizzato per caricare i pacchetti sorgente) sono firmati usando la tua chiave GPG.
![]() |
|
Se non hai una chiave gpg disponibile, otterrai un errore da debuild. Puoi creare sia una chiave gpg. o usare le chiavi -us -uc di debuild per disabilitare la firma. Però non sarai in grado di caricare i tuoi pacchetti in Ubuntu senza firmarli. |
![]() |
|
Per assicurarti che debuild la chiave gpg corretta, dovresti impostare le veriabili d'ambiente DEBFULLNAME e DEBEMAIL (nel tuo Alcune persone hanno riportato che non sono state in grado di far trovare a debuild la loro chiave gpg, anche dopo aver configurato le variabili d'ambiente citate. Per risolvere il problema, puoi indicare a debuild il flag -k<keyid> dove <keyid> è l'ID della tua chiave gpg. |
In aggiunta al pacchetto sorgente, possiamo costruire il pacchetto binario con pbuilder:
sudo pbuilder build ../*.dsc
E' molto importante usare pbuilder per costruire il pacchetto binario. Si assicura che le dipendenze di compilazione siano corrette, dato che pbuilder: prevede solo un ambiente minimale, così tutte le dipendeze di compilazione vengono determinate dal file control
.
Possiamo controllare il pacchetto sorgente per errori comuni usando lintian:
cd .. lintian -i *.dsc