Vai al contenuto

Esercitazione 3 - Confezionamento per la distribuzione

Finora abbiamo eseguito la nostra applicazione in "modalità sviluppatore". Questo ci consente di eseguire facilmente la nostra applicazione a livello locale, ma ciò che vogliamo veramente è poterla fornire ad altri.

Tuttavia, non vogliamo insegnare ai nostri utenti come installare Python, creare un ambiente virtuale, clonare un repository git ed eseguire Briefcase in modalità sviluppatore. Preferiamo dare loro un programma di installazione e far sì che l'applicazione funzioni e basta.

Briefcase può essere utilizzato per impacchettare l'applicazione per la distribuzione in questo modo.

Creare lo scaffold dell'applicazione

Poiché è la prima volta che impacchettiamo la nostra applicazione, dobbiamo creare alcuni file di configurazione e altre impalcature per supportare il processo di impacchettamento. Dalla cartella helloworld, eseguire:

(beeware-venv) $ briefcase create

[helloworld] Generazione del modello dell'applicazione...
Utilizzo del modello di applicazione: https://github.com/beeware/briefcase-macOS-app-template.git, ramo v0.3.18
...

[helloworld] Installazione del pacchetto di supporto...
...

[helloworld] Installazione del codice dell'applicazione...
Installazione di src/helloworld... completata

[helloworld] Installazione dei requisiti...
...

[helloworld] Installazione delle risorse dell'applicazione...
...

[helloworld] Rimozione dei contenuti non necessari dell'app...
Rimozione dei contenuti non necessari del bundle dell'app... completata

[helloworld] Creato build/helloworld/macos/app
(beeware-venv) $ briefcase create

[helloworld] Completamento della configurazione dell'applicazione...
Destinazione: ubuntu:jammy (base Debian del fornitore)
Determinazione della versione di glibc... fatto
Destinazione: glibc 2.35
Destinazione: Python 3.10

[helloworld] Generazione del modello dell'applicazione...
Utilizzo del modello di applicazione: https://github.com/beeware/briefcase-linux-AppImage-template.git, ramo v0.3.18
...

[helloworld] Installazione del pacchetto di supporto...
Nessun pacchetto di supporto richiesto.

[helloworld] Installazione del codice dell'applicazione...
Installazione di src/helloworld... fatto

[helloworld] Installazione dei requisiti...
...

[helloworld] Installazione delle risorse dell'applicazione...
...

[helloworld] Rimozione dei contenuti non necessari dell'app...
Rimozione dei contenuti non necessari del bundle dell'app... fatto

[helloworld] Creato build/helloworld/linux/ubuntu/jammy

Errori sulle versioni di Python

Se si riceve un errore del tipo:

La versione di Python utilizzata per eseguire Briefcase (3.12) non è la versione di sistema python3 (3.10).

È necessario ricreare l'ambiente virtuale utilizzando il sistema python3. L'uso del sistema Python è un requisito per il confezionamento dell'applicazione.

(beeware-venv) C:\...>briefcase create

[helloworld] Generazione del modello di applicazione...
Utilizzo del modello di applicazione: https://github.com/beeware/briefcase-windows-app-template.git, ramo v0.3.18
...

[helloworld] Installazione del pacchetto di supporto...
...

[helloworld] Installazione del codice dell'applicazione...
Installazione di src/helloworld... completata

[helloworld] Installazione dei requisiti...
...

[helloworld] Installazione delle risorse dell'applicazione...
...

[helloworld] Creato build\helloworld\windows\app

Probabilmente avete appena visto passare delle pagine di contenuto nel vostro terminale… cosa è successo? Briefcase ha fatto quanto segue:

  1. Ha generato un modello di applicazione. Per costruire un programma di installazione nativo sono necessari molti file e configurazioni, oltre al codice dell'applicazione vera e propria. Questa impalcatura aggiuntiva è quasi la stessa per ogni applicazione sulla stessa piattaforma, tranne che per il nome dell'applicazione vera e propria che si sta costruendo, quindi Briefcase fornisce un modello di applicazione per ogni piattaforma che supporta. Questo passo esegue il modello, sostituendo il nome dell'applicazione, l'ID del bundle e altre proprietà del file di configurazione, come richiesto per supportare la piattaforma su cui si sta costruendo. Se non si è soddisfatti del modello fornito da Briefcase, si può fornire il proprio. Tuttavia, probabilmente non si vuole fare questo finché non si ha un po' più di esperienza nell'uso del modello predefinito di Briefcase.

  2. Ha scaricato e installato un pacchetto di supporto. L'approccio alla pacchettizzazione adottato da Briefcase è meglio descritto come "la cosa più semplice che possa funzionare": fornisce un interprete Python completo e isolato come parte di ogni applicazione che costruisce (ad eccezione dei pacchetti del sistema nativo Linux). Questo è leggermente inefficiente dal punto di vista dello spazio: se avete 5 applicazioni pacchettizzate con Briefcase, avrete 5 copie dell'interprete Python. Tuttavia, questo approccio garantisce che ogni applicazione sia completamente indipendente, utilizzando una versione specifica di Python che è nota per funzionare con l'applicazione. Anche in questo caso, Briefcase fornisce un pacchetto di supporto predefinito per ogni piattaforma; se volete, potete fornire il vostro pacchetto di supporto e farlo includere nel processo di compilazione. Questo può essere utile se si hanno particolari opzioni nell'interprete Python che devono essere abilitate, oppure se si vogliono togliere dalla libreria standard i moduli che non servono in fase di esecuzione. Briefcase mantiene una cache locale dei pacchetti di supporto, per cui una volta scaricato uno specifico pacchetto di supporto, quella copia in cache sarà usata nelle build future. Come già detto, quando Briefcase confeziona un'applicazione come pacchetto di sistema nativo per Linux (il formato di pacchetto predefinito per Linux), un pacchetto di supporto non viene incluso nell'applicazione. Invece, l'applicazione utilizzerà il Python fornito dalla distribuzione di Linux a cui si rivolge.

  3. Si tratta di requisiti dell'applicazione installata. L'applicazione può specificare qualsiasi modulo di terze parti richiesto in fase di esecuzione. Questi saranno installati usando pip nel programma di installazione dell'applicazione.

  4. Ha installato il codice dell'applicazione. L'applicazione avrà il suo codice e le sue risorse (ad esempio, le immagini necessarie per l'esecuzione); questi file vengono copiati nel programma di installazione.

  5. Infine, aggiunge qualsiasi risorsa aggiuntiva necessaria al programma di installazione stesso. Questo include cose come le icone che devono essere allegate all'applicazione finale e le immagini della schermata iniziale.

Una volta completata l'operazione, se guardi nella directory build del progetto, dovresti ora vedere una directory corrispondente alla tua piattaforma (macOS, linux, o windows) che contiene file aggiuntivi. Si tratta della configurazione di pacchettizzazione specifica per la piattaforma della tua applicazione. Ad esempio, su macOS, la directory del tuo progetto ora includerà:

helloworld/
└── build/
    └── helloworld/
 └── macos/

Creazione dell'applicazione

È ora possibile compilare l'applicazione. Questo passaggio esegue la compilazione binaria necessaria affinché l'applicazione sia eseguibile sulla piattaforma di destinazione.

(beeware-venv) $ briefcase build

[helloworld] Firma ad hoc dell'app...
...
Firma di build/helloworld/macos/app/Hello World.app
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100,0% • 00:07

[helloworld] Compilazione completata build/helloworld/macos/app/Hello World.app

Su macOS, il comando build non ha bisogno di compilare nulla, ma deve firmare il contenuto del binario in modo che possa essere eseguito. Questa firma è una firma ad hoc: funzionerà solo sulla vostra macchina; se volete distribuire l'applicazione ad altri, dovrete fornire una firma completa.

(beeware-venv) $ briefcase build

[helloworld] Completamento della configurazione dell'applicazione...
Destinazione: ubuntu:jammy (base Debian del fornitore)
Determinazione della versione di glibc... fatto
Destinazione: glibc 2.35
Destinazione: Python 3.10

[helloworld] Compilazione dell'applicazione...
Compilazione del binario bootstrap...
make: Entrando nella directory '/home/brutus/beeware-tutorial/helloworld/build/linux/ubuntu/jammy/bootstrap'
...
make: Uscendo dalla directory '/home/brutus/beeware-tutorial/helloworld/build/linux/ubuntu/jammy/bootstrap'
Compilazione del binario bootstrap... fatto
Installazione della licenza... fatto
Installazione del changelog... fatto
Installazione della pagina man... fatto
Aggiornamento dei permessi dei file... fatto
Stripping del binario... fatto

[helloworld] Compilato build/helloworld/linux/ubuntu/jammy/helloworld-0.0.1/usr/bin/helloworld

Una volta completato questo passaggio, la cartella build conterrà una cartella helloworld-0.0.1 che contiene un mirror di un file system Linux /usr. Questo file system mirror conterrà una cartella bin con un binario di helloworld, oltre alle cartelle lib e share necessarie per supportare il binario.

(beeware-venv) C:\...>briefcase build
Impostazione dei dettagli dell'app stub... fatto

[helloworld] Creato build\helloworld\windows\app\src\Hello World.exe

Su Windows, il comando build non ha bisogno di compilare nulla, ma deve scrivere alcuni metadati in modo che l'applicazione conosca il suo nome, la sua versione e così via.

Attivazione dell'antivirus

Poiché questi metadati vengono scritti direttamente nel binario precompilato che viene lanciato dal modello durante il comando create, è possibile che il software antivirus in esecuzione sul computer impedisca la scrittura dei metadati. In questo caso, istruire l'antivirus per consentire l'esecuzione dello strumento (chiamato rcedit-x64.exe) e rieseguire il comando precedente.

Esecuzione dell'applicazione

Ora è possibile utilizzare Briefcase per eseguire l'applicazione:

(beeware-venv) $ briefcase run

[helloworld] Avvio dell'app...
===========================================================================
Configurazione di Python isolato...
Pre-inizializzazione del runtime Python...
PythonHome: /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib
PYTHONPATH:
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python311.zip
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib
- /Utenti/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib/lib-dynload
- /Utenti/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/app_packages
- /Utenti/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contenuti/Risorse/app
Configurazione di argc/argv...
Inizializzazione del runtime Python...
Installazione del gestore NSLog di Python...
Esecuzione del modulo dell'app: helloworld
---------------------------------------------------------------------------
(beeware-venv) $ briefcase run

[helloworld] Completamento della configurazione dell'applicazione...
Destinazione: ubuntu:jammy (base Debian del fornitore)
Determinazione della versione di glibc... fatto
Destinazione: glibc 2.35
Destinazione: Python 3.10

[helloworld] Avvio dell'applicazione...
===========================================================================
Percorso di installazione: /home/brutus/beeware-tutorial/helloworld/build/helloworld/linux/ubuntu/jammy/helloworld-0.0.1/usr
Pre-inizializzazione del runtime Python...
PYTHONPATH:
- /usr/lib/python3.10
- /usr/lib/python3.10/lib-dynload
- /home/brutus/beeware-tutorial/helloworld/build/helloworld/linux/ubuntu/jammy/helloworld-0.0.1/usr/lib/helloworld/app
- /home/brutus/beeware-tutorial/helloworld/build/helloworld/linux/ubuntu/jammy/helloworld-0.0.1/usr/lib/helloworld/app_packages
Configurazione di argc/argv...
Inizializzazione del runtime Python...
Esecuzione del modulo dell'app: helloworld
---------------------------------------------------------------------------
(beeware-venv) C:\...>briefcase run

[helloworld] Avvio dell'applicazione...

===========================================================================
Inizio del log: 2023-04-23 04:47:45Z
Preinizializzazione del runtime Python...
PythonHome: C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src
PYTHONPATH:
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src\python39.zip
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src\app_packages
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src\app
Configurazione di argc/argv...
Inizializzazione del runtime Python...
Esecuzione del modulo dell'app: helloworld
---------------------------------------------------------------------------

In questo modo si avvia l'esecuzione dell'applicazione nativa, utilizzando l'output del comando build.

È possibile notare alcune piccole differenze nell'aspetto dell'applicazione quando è in esecuzione. Ad esempio, le icone e il nome visualizzati dal sistema operativo potrebbero essere leggermente diversi da quelli visualizzati durante l'esecuzione in modalità sviluppatore. Ciò è dovuto anche al fatto che si sta utilizzando l'applicazione pacchettizzata e non solo il codice Python in esecuzione. Dal punto di vista del sistema operativo, ora si sta eseguendo "un'applicazione", non "un programma Python", e questo si riflette sull'aspetto dell'applicazione.

Prima di continuare, chiudere l'applicazione. Come per le precedenti esercitazioni, è possibile farlo premendo il pulsante di chiusura della finestra dell'applicazione, selezionando Quit/Exit dal menu dell'applicazione o digitando Ctrl+C nel terminale in cui è stato eseguito briefcase run.

Creazione del programma di installazione

È ora possibile pacchettizzare l'applicazione per la distribuzione, utilizzando il comando package. Il comando package esegue qualsiasi compilazione necessaria per convertire il progetto scaffolded in un prodotto finale distribuibile. A seconda della piattaforma, ciò può comportare la compilazione di un programma di installazione, l'esecuzione della firma del codice o altre operazioni preliminari alla distribuzione.

(beeware-venv) $ briefcase package --adhoc-sign

[helloworld] Firma dell'app...

*************************************************************************
** AVVISO: Firma con identità ad hoc **
*************************************************************************

 Questa app viene firmata con un'identità ad hoc. L'app risultante
    funzionerà su questo computer, ma non funzionerà su nessun altro
    computer.

 Per generare un'app che possa essere distribuita ad altri, è necessario
    ottenere un certificato di distribuzione dell'applicazione da Apple e
    selezionare l'identità dello sviluppatore associata a quel certificato
    quando si esegue 'briefcase package'.

*************************************************************************

Firma dell'app con identità ad hoc...
 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100,0% • 00:07

[helloworld] Creazione DMG...
Creazione di dist/Hello World-0.0.1.dmg

[helloworld] Pacchetto dist/Hello World-0.0.1.dmg

La cartella dist conterrà un file chiamato Hello World-0.0.1.dmg. Se individuate questo file nel Finder e fate doppio clic sulla sua icona, monterete il DMG, ottenendo una copia dell'applicazione Hello World e un collegamento alla cartella Applicazioni per facilitare l'installazione. Trascinate il file dell'app in Applicazioni e avrete installato la vostra applicazione. Inviate il file DMG a un amico, che dovrebbe essere in grado di fare lo stesso.

In questo esempio, abbiamo usato l'opzione --adhoc-sign, cioè stiamo firmando la nostra applicazione con credenziali ad hoc, credenziali temporanee che funzioneranno solo sul vostro computer. Abbiamo fatto questo per mantenere il tutorial semplice. L'impostazione delle identità di firma del codice è un po' complicata e sono richieste solo se si intende distribuire la propria applicazione ad altri. Se stessimo pubblicando un'applicazione reale da utilizzare, dovremmo specificare delle credenziali reali.

Quando si è pronti a pubblicare un'applicazione reale, consultare la guida Briefcase How-To su Impostazione di un'identità di firma del codice macOS

L'output del passaggio del pacchetto sarà leggermente diverso a seconda della vostra distribuzione Linux. Se si utilizza una distribuzione derivata da Debian, si vedrà:

(beeware-venv) $ briefcase package

[helloworld] Completamento della configurazione dell'applicazione...
Scelta della piattaforma: ubuntu:jammy (base Debian del fornitore)
Determinazione della versione di glibc... fatto
Scelta di glibc 2.35
Scelta di Python 3.10

[helloworld] Creazione del pacchetto .deb...
Scrittura del file di controllo del pacchetto Debian... fatto

dpkg-deb: creazione del pacchetto 'helloworld' in 'helloworld-0.0.1.deb'.
Creazione del pacchetto Debian... fatto

[helloworld] Pacchetto creato dist/helloworld_0.0.1-1~ubuntu-jammy_amd64.deb

La cartella dist conterrà il file .deb generato.

Se si utilizza una distribuzione basata su RHEL, si vedrà:

(beeware-venv) $ briefcase package

[helloworld] Completamento della configurazione dell'applicazione...
Destinazione fedora:40 (base fornitore rhel)
Determinazione versione glibc... fatto
Destinazione glibc 2.39
Destinazione Python3.12

[helloworld] Creazione pacchetto .rpm...
Generazione layout rpmbuild... fatto

Scrittura file spec RPM... fatto

Creazione archivio sorgente... fatto

Esecuzione di (%prep): /bin/sh -e /var/tmp/rpm-tmp.Kav9H7
+ umask 022
...
+ exit 0
Creazione del pacchetto RPM... fatto

[helloworld] Pacchetto creato: dist/helloworld-0.0.1-1.fc40.x86_64.rpm

La cartella dist conterrà il file .rpm generato.

Se si utilizza una distribuzione basata su Arch, si vedrà:

(beeware-venv) $ briefcase package

[helloworld] Finalizzazione della configurazione dell'applicazione...
Architettura di destinazione: 20240101 (architettura di base del fornitore)
Determinazione della versione di glibc... fatto
glibc 2.38
Destinazione Python 3.12

[helloworld] Creazione del pacchetto .pkg.tar.zst...
...
Creazione del pacchetto Arch... fatto

[helloworld] Pacchetto creato: dist/helloworld-0.0.1-1-x86_64.pkg.tar.zst

La cartella dist conterrà il file .pkg.tar.zst che è stato generato.

Altre distribuzioni Linux non sono attualmente supportate per il packaging.

Se volete creare un pacchetto per una distribuzione Linux diversa da quella che state usando, Briefcase può aiutarvi, ma dovrete installare Docker.

Gli installatori ufficiali di Docker Engine sono disponibili per diverse distribuzioni Unix. Seguite le istruzioni per la vostra piattaforma; tuttavia, assicuratevi di non installare Docker in modalità "rootless".

Una volta installato Docker, dovreste essere in grado di avviare un contenitore Linux, ad esempio:

$ docker run --rm -it ubuntu:22.04

mostrerà un prompt Unix (qualcosa come root@84444e31cff9:/#) all'interno di un contenitore Docker Ubuntu 22.04. Digitare Ctrl-D per uscire da Docker e tornare alla shell locale.

Una volta installato Docker, si può usare Briefcase per creare un pacchetto per qualsiasi distribuzione Linux supportata da Briefcase, passando un'immagine Docker come argomento. Per esempio, per creare un pacchetto DEB per Ubuntu 22.04 (Jammy), indipendentemente dal sistema operativo in uso, si può eseguire:

$ pacchetto briefcase --target ubuntu:jammy

Questo scaricherà l'immagine Docker per il sistema operativo selezionato, creerà un contenitore in grado di eseguire le build di Briefcase e costruirà il pacchetto dell'applicazione all'interno dell'immagine. Una volta completato, la cartella dist conterrà il pacchetto per la distribuzione Linux di destinazione.

(beeware-venv) C:\...>briefcase package

*************************************************************************
** AVVISO: Nessuna identità di firma fornita **
*************************************************************************

    Briefcase non firmerà l'app. Per fornire un'identità di firma,
    utilizza l'opzione `--identity`; oppure, per disabilitare esplicitamente la firma,
    utilizza `--adhoc-sign`.

*************************************************************************

[helloworld] Creazione MSI...
Compilazione del manifesto dell'applicazione...
Compilazione... completata

Compilazione del programma di installazione dell'applicazione...
helloworld.wxs
helloworld-manifest.wxs
Compilazione... completata

Collegamento del programma di installazione dell'applicazione...
Collegamento... completato

[helloworld] Pacchetto creato in dist\Hello_World-0.0.1.msi

In questo esempio, abbiamo usato l'opzione --adhoc-sign, cioè stiamo firmando la nostra applicazione con credenziali ad hoc, credenziali temporanee che funzioneranno solo sul vostro computer. Abbiamo fatto questo per mantenere il tutorial semplice. L'impostazione delle identità di firma del codice è un po' complicata e sono richieste solo se si intende distribuire la propria applicazione ad altri. Se stessimo pubblicando un'applicazione reale da utilizzare, dovremmo specificare delle credenziali reali.

Quando si è pronti a pubblicare un'applicazione reale, consultare la guida Briefcase How-To su Impostazione di un'identità di firma del codice macOS

Una volta completato questo passaggio, la cartella dist conterrà un file chiamato Hello_World-0.0.1.msi. Se si fa doppio clic su questo programma di installazione per eseguirlo, si dovrebbe seguire il consueto processo di installazione di Windows. Una volta completata l'installazione, nel menu di avvio sarà presente una voce "Hello World".

Prossimi passi

Ora la nostra applicazione è stata confezionata per essere distribuita su piattaforme desktop. Ma cosa succede quando dobbiamo aggiornare il codice della nostra applicazione? Come facciamo a inserire gli aggiornamenti nella nostra applicazione pacchettizzata? Consultate Tutorial 4 per scoprirlo…