← Blog
Windows Dev10 Giugno 2026·12 min di lettura

Compilare esecutibili Python standalone con Nuitka per azzerare l'overhead di macchina.

La guida definitiva per lanciare file .exe ultraveloci su Windows, eliminando la necessità di lenti pacchetti runtime con PyInstaller. È esattamente come ReelNox Studio e BackDrop_ arrivano ai veri utenti — incluso ogni errore che ho fatto per arrivarci.

Ti sta piacendo? C'è un ❤️ che ti aspetta in fondo.

Perché compilare Python

Se stai costruendo un'app desktop in Python e vuoi che una persona normale la esegua, "pip install" non è un'opzione. Non hanno Python installato, non vogliono installarlo, e non dovrebbero doverlo fare. Serve un vero .exe su cui fare doppio click. Questo significa compilare — trasformare il tuo codice Python interpretato e le sue dipendenze in qualcosa che gira senza un'installazione Python sulla macchina di destinazione.

Perché PyInstaller non era abbastanza buono

PyInstaller è stato il mio primo tentativo, e funziona — tecnicamente. Il problema è cosa fa realmente: pacchetta un interprete Python e tutte le tue dipendenze, poi le estrae in una cartella temp ogni volta che l'app parte (in modalità --onefile) o le distribuisce come cartella piena di file sciolti (in modalità --onedir). In entrambi i casi, stai ancora eseguendo bytecode interpretato attraverso un runtime Python incorporato all'avvio, non codice macchina compilato. L'avvio sembrava lento, il passaggio di estrazione in temp aggiungeva un ritardo visibile al primo lancio, e gli antivirus trattano "si estrae da sé in %TEMP% e inizia ad eseguire" come un'euristica da manuale per il malware — causando esattamente il problema di falso positivo che cercavo di evitare.

L'approccio corretto: Nuitka --standalone

Nuitka è un vero compilatore da Python a C. Non pacchetta un interprete — traduce il tuo codice Python in C, lo compila con un vero compilatore C, e lo collega in un eseguibile nativo reale. Il risultato gira come codice macchina compilato, non bytecode interpretato dentro un runtime incorporato. L'avvio è quasi istantaneo, e — fondamentale — non si estrae mai in una cartella temp a runtime, il che elimina il principale innesco per le euristiche antivirus. Il flag più importante è --standalone: produce una cartella autonoma con il tuo .exe e le sue dipendenze native proprio accanto, pronta da distribuire così com'è o da incapsulare in un installer.

Come farlo davvero

1Installa Nuitka: pip install nuitka (serve un compilatore C sulla macchina — MSVC su Windows, che l'installer di Nuitka può scaricare per te se non hai già Visual Studio Build Tools)
2Esegui la compilazione: python -m nuitka --standalone --enable-plugin=tk-inter --windows-console-mode=disable --output-dir=dist main.py
3Nuitka produce una cartella dist/main.dist/ contenente main.exe più ogni dipendenza nativa rilevata — questa intera cartella è ciò che distribuisci, non solo il .exe
4Incapsula quella cartella con un installer (io uso Inno Setup) così gli utenti hanno una normale esperienza di installazione Windows invece di una cartella sciolta di file
5Testa l'app installata su una VM Windows pulita senza Python installato, prima di rilasciarla — è l'unico modo per scoprire una DLL mancante o un percorso di asset che funzionava solo sulla tua macchina di sviluppo

I 3 errori che mi sono costati ore

⚠️ Dimenticare --enable-plugin=tk-inter

Se la tua GUI usa Tkinter o CustomTkinter e salti questo flag, l'app compilata non dà un errore evidente — semplicemente non carica il toolkit GUI e può crashare silenziosamente o mostrare una finestra vuota. Nuitka non include il supporto ai framework GUI di default; devi attivarlo per ogni framework.

⚠️ Usare --onefile invece di --standalone

--onefile è allettante perché produce un singolo .exe invece di una cartella. Non usarlo per nulla che intendi distribuire pubblicamente. Le build onefile si auto-estraggono comunque in una cartella temp a runtime — lo stesso comportamento che faceva scattare i falsi positivi con PyInstaller — e l'ho visto segnalato da Windows Defender come Wacatac o Sabsik puramente per quel pattern di estrazione, con codice completamente pulito. --standalone evita tutto questo.

⚠️ Risolvere i percorsi degli asset con __file__ invece di sys.executable

In uno script Python normale, __file__ punta alla posizione del tuo file sorgente. In una build standalone compilata, quell'assunzione si rompe. Usa Path(sys.executable).parent per trovare dove si trova realmente il tuo .exe sulla macchina dell'utente, e carica file di configurazione, icone e asset incorporati relativamente a quello — non relativamente a dove si trovava il sorgente durante lo sviluppo.

Cosa ottieni davvero

Sia ReelNox Studio che BackDrop_ vengono distribuiti come build Nuitka --standalone, firmate con un certificato DigiCert EV. L'avvio è istantaneo, Windows Defender non segnala nessuno dei due installer, e nessuna delle due app ha mai avuto bisogno di un runtime Python incorporato a cui l'utente deve pensare. La combinazione che conta è: --standalone (non --onefile) più una firma del codice corretta — insieme risolvono sia il problema delle prestazioni che il problema della fiducia che arrivano con la distribuzione di un'app Python come eseguibile Windows nativo.

Guardala in azione → ReelNox StudioCostruito con Nuitka --standalone, accelerazione GPU, firma EV

About

Patrick Chen — sviluppatore indipendente di Sublimearts.io. Scrivo dei problemi di build reali che ho incontrato distribuendo ReelNox Studio, BackDrop_ e TimePeek a veri utenti Windows — non tutorial generici.

Did you find this helpful?