2011-11-04 12 views
7

La maggior parte dei campi in un file di controllo dpkg (Debian) è semplice. Il difficile è determinare l'elenco delle dipendenze (dipende da :). Speravo che dpkg-gencontrol potesse farlo per me osservando l'output ldd per gli eseguibili nella directory del pacchetto. Forse può, ma non riesco a farlo funzionare.C'è un modo per determinare automaticamente le dipendenze quando si imposta un file di controllo dpkg?

Se questo è ciò che è per dpkg-gencontrol, l'errore che sto ottenendo è:

dpkg-gencontrol: error: syntax error in control_template at line 7: first block lacks a source field. 

Per riferimento, il comando è dpkg-gencontrol -v1.1 -ccontrol_template -lchangelog -Pdebian. Il file contiene control_template questo:

Package: my-package 
Maintainer: Joe Coder <[email protected]> 
Description: The my-package system 
A longer description that runs to the end of one line and then 
extends to another line. 
Priority: optional 

Se questo non è ciò che è per dpkg-gencontrol, qualcuno ha qualche suggerimento su cosa posso fare, o consigli su come impostare l'elenco delle dipendenze, idealmente automaticamente?

Certamente, dedurre le dipendenze in modo generale è probabilmente un problema molto difficile, specialmente se si estende la ricerca a script e altri programmi. Spero che esistano alcuni strumenti che funzionano la maggior parte del tempo.

Si noti che questo è solo per la distribuzione interna. Non sto costruendo un pacchetto per andare in una distribuzione Linux o anche per essere scaricato dal pubblico in generale, quindi sono felice di piegare/infrangere le regole standard se necessario.

risposta

10

Dopo alcuni scavi ispirati alla risposta di Thiton e a un sacco di tentativi ed errori, ho finalmente trovato una soluzione al mio problema. Risulta che dpkg-gencontrol non è lo strumento per dedurre le dipendenze dei pacchetti dagli eseguibili, dpkg-shlibdeps lo è. Tuttavia, le cose devono essere impostate attentamente per i due programmi per aiutare a generare un pacchetto. Continua a leggere ....

L'esecuzione di dpkg-shlibdeps -O <executable> genera un elenco dei pacchetti e delle versioni che devono essere installati affinché l'eseguibile possa essere eseguito. Perfezionare. Quasi. Idealmente, dpkg-gencontrol potrebbe usare questo nella sua elaborazione, che afferma di essere in grado di fare attraverso la sua funzione di sostituzione variabile.

Per rendere tutto ciò agevole, ho dovuto creare una struttura di directory che corrisponda alle aspettative degli strumenti di pacchettizzazione Debian. Sembra sostanzialmente in questo modo:

my_project_directory/ 
    main.c (or other source code, etc.) 
    debian/ 
    changelog (created by hand; see below) 
    control  (this is basically a template, created by hand; see below) 
    files  (created by dpkg-gencontrol) 
    substvars (created by dpkg-shlibdeps and used by dpkg-gencontrol) 
    tmp/   (tmp is the root of the target system's filesystem) 
     path/ 
     to/ 
      my/ 
      project/ 
       executable_1 (this will be installed at /path/to/my/project) 
       executable_2 (this, too) 
     var/ 
     www/ 
      index.php (this will be installed at /var/www on target systems) 
     DEBIAN/  (create this by hand) 
     control  (created by dpkg-gencontrol and used in the final package) 

Si noti che gli strumenti di packaging Debian conservano il proprietario e il gruppo di tutti i file sotto debian/tmp /. Pertanto, se si desidera che i file di proprietà di root o di altri utenti siano installati, le cose si complicano. Un'opzione consiste nel preparare l'albero della directory debian come root e impostare i proprietari come preferisci. Se preferisci non essere eseguito come root o non ti è permesso, c'è un altro modo.

Creare uno script che chiami chown, ecc. Per regolare le proprietà come più ti piace, con l'ultima riga da dpkg-deb -b debian/tmp . (che crea il pacchetto .deb, vedi sotto per un esempio). Eseguilo tramite fakeroot, un altro strumento Debian, come questo: fakeroot ./fix_ownerships_and_build.sh. Fakeroot consente ai programmi di comportarsi come se fossero root, senza in realtà modificare le cose come farebbe root. È stato creato proprio per questo scenario.

Ho esaminato il motivo per cui dpkg-gencontrol stava generando l'errore "Primo blocco priva di un campo sorgente", arrivando persino a leggere la sua sorgente Perl. Come spesso accade, il codice di errore è preciso senza fornire un contesto sufficiente per sapere cosa fare: il file di controllo ha davvero bisogno di un campo chiamato "source", nei suoi primi (di due) blocchi.

Esistono due tipi di pacchetti Debian, sorgente e binario. Pensavo di aver bisogno di uno binario poiché volevo semplicemente inserire degli eseguibili compilati, ma non riuscivo a farlo funzionare. Ho provato un pacchetto sorgente e ho aggiunto un campo sorgente al mio file di controllo. Questo ha eliminato l'errore "primo blocco manca un campo sorgente", ma ha portato a un altro. Leggendo la documentazione più da vicino, ho capito che i pacchetti sorgente need two "paragraphs" nei loro file di controllo. Una volta ho cambiato il mio file di controllo a guardare come questo, ha cominciato a lavorare (quasi):

Source: my-package 
Maintainer: Joe Coder <[email protected]> 

Package: my-package 
Priority: optional 
Architecture: amd64 
Depends: ${shlibs:Depends}, apache2, php5 
Description: The My-Package System 
A longer description that runs to the end of one line and then 
extends to another line. 

Quello che ancora mancava era un file changelog. Questo è un file per conservare una cronologia delle versioni di un pacchetto, con modifiche significative, numeri di versione, date e persone responsabili. Normalmente mantengo una cosa del genere nel mio formato, che ho accuratamente convertito nel formato esatto di changelog di Debian. Per qualche ragione, il changelog è stato omesso dal pacchetto finale, così ho lasciato il mio file di storia da solo e ha utilizzato un segnaposto invece, che assomiglia a questo:

my-package (1.0) unstable; urgency=low 
    * placeholder changelog to satisfy dpkg-gencontrol 
-- Joe Coder <[email protected]> Thu, 3 Nov 2011 16:49:00 -0700 

I due spazi iniziali sulla linea con la * sono essenziali , come lo spazio principale sulla linea con il -, come lo sono i due spazi tra l'indirizzo email e la data. E sì, la data deve essere quella precisa, il fuso orario e tutto, anche se non ha bisogno di essere accurato.

Mettendo tutto insieme, con un albero di directory debian impostato come descritto sopra, la sequenza di comandi necessari per creare un pacchetto sono i seguenti:

dpkg-shlibdeps debian/tmp/path/to/my/project/executable_1 \ 
       debian/tmp/path/to/my/project/executable_2 
dpkg-gencontrol -v1.1 (or whatever version you are building) 
fakeroot ./fix_ownerships_and_build.sh 

dove fix_ownerships_and_build.sh assomiglia a questo:

chown -R root:root debian/tmp/path (or whatever user is appropriate) 
chown -R www-data:www-data debian/tmp/var/www/* (same goes here) 
dpkg-deb -b debian/tmp . (this leads to a nice my-package_1.1_amd64.deb file) 

Quindi è tutto. Speriamo che questa risposta aiuti gli altri a fare progressi più velocemente di me.

+0

Bel lavoro, ma hai riprogrammato buona parte di dpkg-buildpackage. Sei consapevole di quello strumento, vero? – thiton

+0

Un po '. Ci sono dozzine di strumenti relativi a dpkg e io ero interessato a mantenere le cose semplici. Anche gli strumenti Debian sembravano così concentrati sulla creazione di pacchetti da fonti upstream per la distribuzione con Debian stesso, il che non è esattamente quello che stavo cercando di fare. Avevo iniziato con la creazione di un semplice albero di directory, un file di controllo minimo e una singola chiamata a 'dpkg-deb -b'. Stavo cercando di trovare le aggiunte minime a quella base per ottenere ciò che volevo. È cresciuto. :) Vedrò dpkg-buildpackage. La reinvenzione delle ruote è spesso una grande parte dell'apprendimento. –

1

In realtà, l'elenco delle librerie incluse è piuttosto comune per i programmi C e solo per il lavoro dell'helper shlibs (dpkg-shlibdeps). Guarda la sua pagina di manuale per aiuto, ma in pratica si riduce a usare ${shlibs:Depends} nella tua linea dipende.

+0

Questo era l'indizio che mi ha fatto iniziare verso una soluzione. Grazie, Thilton. E per riferimento, non è stato dh_shlibdeps che ha aiutato, ma dpkg-shlibdeps. –

+0

@randallecook: Grazie per il suggerimento, modificato di conseguenza. – thiton