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] Generating application template...
Using app template: https://github.com/beeware/briefcase-macOS-app-template.git, branch v0.3.18
...
[helloworld] Installing support package...
...
[helloworld] Installing application code...
Installing src/helloworld... done
[helloworld] Installing requirements...
...
[helloworld] Installing application resources...
...
[helloworld] Removing unneeded app content...
Removing unneeded app bundle content... done
[helloworld] Created build/helloworld/macos/app
(beeware-venv) $ briefcase create
[helloworld] Finalizing application configuration...
Targeting ubuntu:jammy (Vendor base debian)
Determining glibc version... done
Targeting glibc 2.35
Targeting Python3.10
[helloworld] Generating application template...
Using app template: https://github.com/beeware/briefcase-linux-AppImage-template.git, branch v0.3.18
...
[helloworld] Installing support package...
No support package required.
[helloworld] Installing application code...
Installing src/helloworld... done
[helloworld] Installing requirements...
...
[helloworld] Installing application resources...
...
[helloworld] Removing unneeded app content...
Removing unneeded app bundle content... done
[helloworld] Created 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] Generating application template...
Using app template: https://github.com/beeware/briefcase-windows-app-template.git, branch v0.3.18
...
[helloworld] Installing support package...
...
[helloworld] Installing application code...
Installing src/helloworld... done
[helloworld] Installing requirements...
...
[helloworld] Installing application resources...
...
[helloworld] Created build\helloworld\windows\app
Probabilmente avete appena visto passare delle pagine di contenuto nel vostro terminale… cosa è successo? Briefcase ha fatto quanto segue:
-
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.
-
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.
-
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
pipnel programma di installazione dell'applicazione. -
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.
-
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 questa operazione, se si guarda nella cartella del
progetto, si dovrebbe vedere una cartella corrispondente alla propria
piattaforma (macOS, linux o windows) che contiene file aggiuntivi. Questa
è la configurazione di pacchettizzazione specifica della piattaforma per
l'applicazione.
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] Adhoc signing app...
...
Signing build/helloworld/macos/app/Hello World.app
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100.0% • 00:07
[helloworld] Built 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] Finalizing application configuration...
Targeting ubuntu:jammy (Vendor base debian)
Determining glibc version... done
Targeting glibc 2.35
Targeting Python3.10
[helloworld] Building application...
Build bootstrap binary...
make: Entering directory '/home/brutus/beeware-tutorial/helloworld/build/linux/ubuntu/jammy/bootstrap'
...
make: Leaving directory '/home/brutus/beeware-tutorial/helloworld/build/linux/ubuntu/jammy/bootstrap'
Building bootstrap binary... done
Installing license... done
Installing changelog... done
Installing man page... done
Updating file permissions... done
Stripping binary... done
[helloworld] Built 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
Setting stub app details... done
[helloworld] Built 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] Starting app...
===========================================================================
Configuring isolated Python...
Pre-initializing Python runtime...
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
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib/lib-dynload
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/app_packages
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/app
Configure argc/argv...
Initializing Python runtime...
Installing Python NSLog handler...
Running app module: helloworld
---------------------------------------------------------------------------
(beeware-venv) $ briefcase run
[helloworld] Finalizing application configuration...
Targeting ubuntu:jammy (Vendor base debian)
Determining glibc version... done
Targeting glibc 2.35
Targeting Python3.10
[helloworld] Starting app...
===========================================================================
Install path: /home/brutus/beeware-tutorial/helloworld/build/helloworld/linux/ubuntu/jammy/helloworld-0.0.1/usr
Pre-initializing Python runtime...
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
Configure argc/argv...
Initializing Python runtime...
Running app module: helloworld
---------------------------------------------------------------------------
(beeware-venv) C:\...>briefcase run
[helloworld] Starting app...
===========================================================================
Log started: 2023-04-23 04:47:45Z
PreInitializing Python runtime...
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
Configure argc/argv...
Initializing Python runtime...
Running app module: 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] Signing app...
*************************************************************************
** WARNING: Signing with an ad-hoc identity **
*************************************************************************
This app is being signed with an ad-hoc identity. The resulting
app will run on this computer, but will not run on anyone else's
computer.
To generate an app that can be distributed to others, you must
obtain an application distribution certificate from Apple, and
select the developer identity associated with that certificate
when running 'briefcase package'.
*************************************************************************
Signing app with ad-hoc identity...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100.0% • 00:07
[helloworld] Building DMG...
Building dist/Hello World-0.0.1.dmg
[helloworld] Packaged 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] Finalizing application configuration...
Targeting ubuntu:jammy (Vendor base debian)
Determining glibc version... done
Targeting glibc 2.35
Targeting Python3.10
[helloworld] Building .deb package...
Write Debian package control file... done
dpkg-deb: building package 'helloworld' in 'helloworld-0.0.1.deb'.
Building Debian package... done
[helloworld] Packaged 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] Finalizing application configuration...
Targeting fedora:40 (Vendor base rhel)
Determining glibc version... done
Targeting glibc 2.39
Targeting Python3.12
[helloworld] Building .rpm package...
Generating rpmbuild layout... done
Write RPM spec file... done
Building source archive... done
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.Kav9H7
+ umask 022
...
+ exit 0
Building RPM package... done
[helloworld] Packaged 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] Finalizing application configuration...
Targeting arch:20240101 (Vendor base arch)
Determining glibc version... done
Targeting glibc 2.38
Targeting Python3.12
[helloworld] Building .pkg.tar.zst package...
...
Building Arch package... done
[helloworld] Packaged 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:
$ briefcase package --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
*************************************************************************
** WARNING: No signing identity provided **
*************************************************************************
Briefcase will not sign the app. To provide a signing identity,
use the `--identity` option; or, to explicitly disable signing,
use `--adhoc-sign`.
*************************************************************************
[helloworld] Building MSI...
Compiling application manifest...
Compiling... done
Compiling application installer...
helloworld.wxs
helloworld-manifest.wxs
Compiling... done
Linking application installer...
Linking... done
[helloworld] Packaged 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…