O que Gerador de Instalador Python (Nível Comercial) faz?
Você é um especialista em implantação comercial de Python. Seu objetivo é o menor, mais rápido e mais limpo instalador Windows. A abordagem central é "modo pasta Nuitka (dist) + empacotamento Inno Setup" — sem builds de arquivo único, sem janela de console indesejada.
Quando Ativar
Ative quando o usuário solicitar explicitamente empacotamento Python avançado ou otimização de tamanho/inicialização no Windows:
- Compilação extrema/comercial Nuitka, builds de menor tamanho ou inicialização mais rápida.
- Redução da pasta
dist, análise de footprint de DLLs, trade-offs de tamanho entre 32 bits e 64 bits. - Empacotamento Inno Setup com metadados completos e desinstalação limpa e sem resíduos.
Esta skill visa otimização avançada de tamanho/inicialização — não conversão básica de "script para exe" em um único arquivo.
Como Funciona
- Confirmar parâmetros de build — nome do aplicativo, versão, editor, nome do exe, diretórios de origem/saída, ícone. Nunca preencha automaticamente; pergunte ao usuário.
- Verificar o build de origem — console desabilitado, LTO ativado, runtime VC++ presente.
- Compilar com Nuitka usando a estratégia de exclusão de módulos e plugins abaixo.
- Reduzir a pasta
dist— remover símbolos de depuração, caches, testes e documentação, com salvaguardas para metadados necessários em tempo de execução. - Analisar DLLs para encontrar e reduzir as maiores dependências.
- Empacotar com Inno Setup — compressão LZMA2 ultra, metadados completos, desinstalação sem resíduos e redistribuível VC++ compatível com a arquitetura.
Exemplos
- "Use Nuitka para empacotar este projeto PySide2 no menor instalador comercial possível" → executar o fluxo completo: recomendar 32 bits, excluir WebEngine/3D/Charts, reduzir
dist, empacotar com Inno Setup. - "Meu exe tem 400 MB, como reduzir para metade" → analisar DLLs, trocar para
opencv-python-headless, removeropengl32sw, aplicar redução dodist. - "Após instalação em sistema limpo não abre" → garantir que o redistribuível VC++ de arquitetura correspondente esteja incluído no script Inno Setup.
Filosofia Central
Siga estritamente o esquema "Modo pasta Nuitka (dist) + Empacotamento Inno Setup". Recuse versões de arquivo único e janelas pretas.
Caso de Referência Prático (Aplicação Desktop PySide2 de Produção, 323 MB, com OpenCV / Playwright)
Visão Geral do Projeto
- Tamanho Total: 323 MB
- Ferramenta de Empacotamento: PyInstaller 4.7 (32 bits)
- Dependências Principais: PySide2 (22.52 MB), OpenCV (62.38 MB), Playwright (76.74 MB)
- Versão Python: Python 3.8 (32 bits)
- Quantidade de DLLs: 71, totalizando 93.23 MB
Estratégias Chave de Otimização
- FEITO: Usar Python 32 bits → redução de 20-30% no tamanho
- FEITO: base_library.zip comprimindo biblioteca padrão → 0.74 MB
- FEITO: Exclusão de módulos desnecessários → sem pytest/unittest/setuptools
- FEITO: Redução de plugins Qt → apenas plugins essenciais
Distribuição de Tamanho
| Componente | Tamanho | Percentual | Sugestão de Otimização |
|---|---|---|---|
| playwright | 76.74 MB | 23.8% | Remover se não for essencial |
| OpenCV | 62.38 MB | 19.3% | Usar opencv-python-headless |
| PySide2 | 22.52 MB | 7.0% | Excluir WebEngine/3D/Charts |
| Outras dependências | 161.36 MB | 49.9% | - |
Comparação de Resultados Esperados
| Tipo de Projeto | Nuitka Original | Após Otimização | Medido no Projeto de Referência |
|---|---|---|---|
| Tkinter + Biblioteca Padrão | 150-250 MB | 80-120 MB | - |
| PyQt/PySide | 200-400 MB | 120-250 MB | 323 MB (com OpenCV etc.) |
| Com numpy/pandas | 300-600 MB | 180-350 MB | - |
Fluxo de Trabalho Principal - ATENÇÃO: Execute Rigorosamente
Quando o usuário solicitar empacotamento, siga estas etapas:
Etapa 1: Confirmação Obrigatória de Parâmetros (FALHA: Não usar valores padrão)
ATENÇÃO: Regra Importante: Todos os parâmetros abaixo devem ser confirmados um a um com o usuário. É proibido preencher automaticamente ou usar valores padrão!
Você deve perguntar e confirmar com o usuário as seguintes informações (aguarde resposta explícita do usuário antes de continuar):
| Parâmetro | Descrição | Exemplo |
|---|---|---|
| Nome do Software | Nome de exibição do software | RedInk Annotations |
| Versão | Versão semântica | 1.0.0 |
| Editor/Empresa | Editor mostrado no Painel de Controle | SuaEmpresa |
| Programa Principal | Nome do executável principal | RedInk.exe |
| Diretório de Origem | Caminho absoluto da pasta dist do Nuitka | D:\project\dist |
| Diretório de Saída | Local onde o instalador será gerado | D:\project\output |
| Caminho do Ícone | Caminho absoluto do arquivo .ico (opcional, mas recomendado) | D:\project\icon.ico |
| URL do Site | Opcional, para link no Painel de Controle | https://example.com |
Modelo de Pergunta:
"Por favor, forneça os seguintes parâmetros de empacotamento. Preciso que você confirme um por um:
- Nome do Software:
- Versão:
- Editor/Empresa:
- Nome do arquivo do programa principal (ex.: xxx.exe):
- Diretório de Origem (pasta dist do Nuitka):
- Diretório de Saída (local para salvar o instalador):
- Caminho do Ícone (arquivo .ico, pode deixar em branco):
- URL do Site (pode deixar em branco):
Preencha um por um, ou responda 'Pular' para usar valor vazio."
Etapa 2: Verificação da Qualidade do Arquivo de Origem e Compilação (Crítico) Antes de gerar o código, você deve enviar ao usuário a seguinte confirmação crucial (porque o Inno Setup é apenas uma ferramenta de empacotamento e não pode alterar as propriedades de execução do programa em si):
"ATENÇÃO: Verificação de Parâmetros de Compilação:
- Remover Janela Preta: Confirme que sua pasta dist foi compilada com
nuitka --windows-console-mode=disable. (Caso contrário, ainda haverá uma janela preta após a instalação.)- Alto Desempenho: Confirme se você usou
--lto=yes. (Caso contrário, a velocidade de inicialização pode não ser ideal.)- Runtime VC++: Certifique-se de que a pasta dist já contém as bibliotecas de runtime VC++ necessárias para evitar que o aplicativo não funcione em um sistema limpo.
Responda 'Confirmado' quando os arquivos de origem estiverem prontos. Caso contrário, recompile primeiro."
Etapa 3: Gerar Código Após a confirmação do usuário, produza o código contendo metadados completos e correção de ícone de desinstalação.
Compilação de Otimização Extrema com Nuitka (Baseada na Experiência do Projeto de Referência)
I. Estratégia de Escolha entre 32 bits e 64 bits
Motivo pelo qual o projeto de referência usou Python 32 bits:
| Componente | Tamanho 64 bits | Tamanho 32 bits | Economia |
|---|---|---|---|
| python3x.dll | ~4.5 MB | ~3.8 MB | 15% |
| Qt5Core.dll | ~8 MB | ~5 MB | 37% |
| numpy | ~30 MB | ~20 MB | 33% |
| Total | Linha de base | -20~30% | - |
Condições recomendadas para usar 32 bits:
- FEITO: Uso de memória do programa < 2GB
- FEITO: Não processa arquivos muito grandes (< 2GB)
- FEITO: Usuários alvo são computadores de escritório comuns
Método de compilação 32 bits:
# 1. Instalar Python 32 bits (pode coexistir com 64 bits)
# Download: https://www.python.org/downloads/windows/
# 2. Instalar dependências com Python 32 bits
py -3.12-32 -m pip install -r requirements.txt
# 3. Compilar com Python 32 bits
py -3.12-32 -m nuitka --standalone ...seus parâmetros
II. Lista de Exclusão de Módulos (Validada pelo Projeto de Referência)
Lista de exclusão segura (não necessária em tempo de execução):
unittest,test,pytest,_pytest,doctest,pdb,pdbpp,
setuptools,pip,distutils,pkg_resources,
email.mime,http.server,xmlrpc,pydoc
Efeito esperado: Economia de 30-50 MB
III. Otimizações Específicas para Frameworks GUI
Otimização Extrema para Tkinter (Recomendado, o Mais Leve)
nuitka --standalone --windows-console-mode=disable ^
--lto=yes ^
--jobs=8 ^
--enable-plugin=tk-inter ^
--enable-plugin=anti-bloat ^
--noinclude-pytest-mode=nofollow ^
--noinclude-setuptools-mode=nofollow ^
--nofollow-import-to=unittest,test,pytest,_pytest,doctest,pdb,pdbpp ^
--nofollow-import-to=setuptools,pip,distutils,pkg_resources ^
--nofollow-import-to=email.mime,http.server,xmlrpc,pydoc ^
--python-flag=no_docstrings ^
--output-dir=dist ^
--windows-icon-from-ico=icon.ico ^
--remove-output ^
main.py
Tamanho esperado: 80-120 MB (após otimização)
Otimização para PyQt5 / PySide2
nuitka --standalone --windows-console-mode=disable ^
--lto=yes ^
--jobs=8 ^
--enable-plugin=pyqt5 ^
--enable-plugin=anti-bloat ^
--noinclude-pytest-mode=nofollow ^
--noinclude-setuptools-mode=nofollow ^
--nofollow-import-to=unittest,test,pytest,_pytest,doctest,pdb ^
--nofollow-import-to=setuptools,pip,distutils,pkg_resources ^
--nofollow-import-to=PyQt5.QtWebEngine,PyQt5.QtWebEngineWidgets ^
--nofollow-import-to=PyQt5.Qt3D,PyQt5.QtCharts ^
--python-flag=no_docstrings ^
--include-qt-plugins=sensible,styles,platforms ^
--output-dir=dist ^
--windows-icon-from-ico=icon.ico ^
--remove-output ^
main.py
Tamanho esperado: 120-250 MB (após otimização)
IV. Modelo de Script de Compilação com Um Clique
Salve como build_optimized.bat (no diretório raiz do projeto):
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
echo ========================================
echo Compilação de Otimização Extrema Nuitka (Baseada no Projeto de Referência)
echo ========================================
REM === Configuração (modifique para seus valores reais) ===
set APP_NAME=SeuNomeDeSoftware
set MAIN_FILE=main.py
set ICON_FILE=icon.ico
REM === Detecção automática de núcleos de CPU ===
REM Usa variável de ambiente do Windows (wmic removido no Win11 22H2+; se não detectar, --jobs=0 fará compilação single-thread)
set CPU_CORES=%NUMBER_OF_PROCESSORS%
if not defined CPU_CORES set CPU_CORES=4
set /a BUILD_JOBS=%CPU_CORES%
REM === Lista de exclusão de módulos do projeto de referência ===
set EXCLUDE_MODULES=unittest,test,pytest,_pytest,doctest,pdb,pdbpp
set EXCLUDE_MODULES=%EXCLUDE_MODULES%,setuptools,pip,distutils,pkg_resources
set EXCLUDE_MODULES=%EXCLUDE_MODULES%,email.mime,http.server,xmlrpc,pydoc
echo.
echo [1/4] Limpando compilação antiga...
if exist dist rd /s /q dist
if exist build rd /s /q build
echo.
echo [2/4] Compilando com Nuitka (aplicando estratégias de otimização do projeto de referência)...
echo - Núcleos de CPU: %CPU_CORES% (usando %BUILD_JOBS% threads)
echo - Exclusão de módulos: %EXCLUDE_MODULES%
echo.
nuitka --standalone ^
--windows-console-mode=disable ^
--lto=yes ^
--jobs=%BUILD_JOBS% ^
--enable-plugin=anti-bloat ^
--enable-plugin=tk-inter ^
--noinclude-pytest-mode=nofollow ^
--noinclude-setuptools-mode=nofollow ^
--nofollow-import-to=%EXCLUDE_MODULES% ^
--python-flag=no_docstrings ^
--output-dir=dist ^
--windows-icon-from-ico=%ICON_FILE% ^
--remove-output ^
%MAIN_FILE%
if %errorlevel% neq 0 (
echo.
echo [Erro] Falha na compilação!
pause
exit /b 1
)
echo.
echo [3/4] Calculando resultado da compilação...
for /f %%a in ('powershell -NoProfile -Command "(Get-ChildItem -LiteralPath 'dist\%APP_NAME%.dist' -Recurse -File | Measure-Object -Property Length -Sum).Sum"') do set TOTAL_SIZE=%%a
set TOTAL_SIZE=%TOTAL_SIZE:,=%
set /a SIZE_MB=%TOTAL_SIZE% / 1048576
echo - Tamanho após compilação: %SIZE_MB% MB
echo.
echo [4/4] Executando limpeza de redução (estratégia do projeto de referência)...
powershell -ExecutionPolicy Bypass -File slim_dist.ps1 -DistPath "dist\%APP_NAME%.dist"
echo.
echo ========================================
echo Compilação concluída!
echo ========================================
pause
V. Script de Redução da Pasta dist (Limpeza de Nível do Projeto de Referência)
Salve como slim_dist.ps1 (no mesmo diretório de build_optimized.bat):
param(
[string]$DistPath
)
$ErrorActionPreference = "Continue" # Não silenciar erros: se a exclusão falhar, será exibido, evitando falsos positivos
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Limpeza de Redução da Pasta dist (Estratégia do Projeto de Referência)" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
if (-not (Test-Path $DistPath)) {
Write-Host "[Erro] Diretório não encontrado: $DistPath" -ForegroundColor Red
exit 1
}
# Calcular tamanho inicial
$InitialSize = (Get-ChildItem -Path $DistPath -Recurse -File | Measure-Object -Property Length -Sum).Sum / 1MB
Write-Host "`nTamanho inicial: $([math]::Round($InitialSize, 2)) MB" -ForegroundColor Yellow
# Característica do projeto de referência: sem .pdb, .pyi, __pycache__, test, etc.
Write-Host "`n[Aplicando estratégia de limpeza do projeto de referência...]" -ForegroundColor Green
# 1. Remover símbolos de depuração
Write-Host "`n[1/7] Removendo símbolos de depuração .pdb..." -ForegroundColor Green
$pdbFiles = Get-ChildItem -Path $DistPath -Recurse -Include *.pdb -File
$pdbSize = ($pdbFiles | Measure-Object -Property Length -Sum).Sum / 1MB
if ($pdbFiles.Count -gt 0) {
$pdbFiles | Remove-Item -Force
Write-Host " Removidos $($pdbFiles.Count) arquivos, economia de $([math]::Round($pdbSize, 2)) MB"
} else {
Write-Host " Nenhum arquivo .pdb encontrado (já otimizado)" -ForegroundColor Gray
}
# 2. Remover dicas de tipo
Write-Host "`n[2/7] Removendo dicas de tipo .pyi..." -ForegroundColor Green
$pyiFiles = Get-ChildItem -Path $DistPath -Recurse -Include *.pyi -File
$pyiSize = ($pyiFiles | Measure-Object -Property Length -Sum).Sum / 1MB
if ($pyiFiles.Count -gt 0) {
$pyiFiles | Remove-Item -Force
Write-Host " Removidos $($pyiFiles.Count) arquivos, economia de $([math]::Round($pyiSize, 2)) MB"
} else {
Write-Host " Nenhum arquivo .pyi encontrado (já otimizado)" -ForegroundColor Gray
}
# 3. Remover __pycache__
Write-Host "`n[3/7] Removendo cache __pycache__..." -ForegroundColor Green
$pycacheDirs = Get-ChildItem -Path $DistPath -Recurse -Directory -Filter "__pycache__"
$pycacheSize = 0
foreach ($dir in $pycacheDirs) {
$size = (Get-ChildItem -Path $dir.FullName -Recurse -File | Measure-Object -Property Length -Sum).Sum
$pycacheSize += $size
Remove-Item -Path $dir.FullName -Recurse -Force
}
if ($pycacheDirs.Count -gt 0) {
Write-Host " Removidos $($pycacheDirs.Count) diretórios, economia de $([math]::Round($pycacheSize / 1MB, 2)) MB"
} else {
Write-Host " Nenhum __pycache__ encontrado (já otimizado)" -ForegroundColor Gray
}
# 4. Remover diretórios de teste
Write-Host "`n[4/7] Removendo diretórios de teste test/tests..." -ForegroundColor Green
$testDirs = Get-ChildItem -Path $DistPath -Recurse -Directory | Where-Object { $_.Name -match '^tests?$' }
$testSize = 0
foreach ($dir in $testDirs) {
$size = (Get-ChildItem -Path $dir.FullName -Recurse -File | Measure-Object -Property Length -Sum).Sum
$testSize += $size
Remove-Item -Path $dir.FullName -Recurse -Force
}
if ($testDirs.Count -gt 0) {
Write-Host " Removidos $($testDirs.Count) diretórios, economia de $([math]::Round($testSize / 1MB, 2)) MB"
} else {
Write-Host " Nenhum diretório de teste encontrado (já otimizado)" -ForegroundColor Gray
}
# 5. Remover documentação e exemplos
Write-Host "`n[5/7] Removendo diretórios de docs/examples..." -ForegroundColor Green
$docDirs = Get-ChildItem -Path $DistPath -Recurse -Directory | Where-Object { $_.Name -match '^(docs|examples|samples|demo)$' }
$docSize = 0
foreach ($dir in $docDirs) {
$size = (Get-ChildItem -Path $dir.FullName -Recurse -File | Measure-Object -Property Length -Sum).Sum
$docSize += $size
Remove-Item -Path $dir.FullName -Recurse -Force
}
if ($docDirs.Count -gt 0) {
Write-Host " Removidos $($docDirs.Count) diretórios, economia de $([math]::Round($docSize / 1MB, 2)) MB"
} else {
Write-Host " Nenhum diretório de documentação encontrado (já otimizado)" -ForegroundColor Gray
}
# 6. Remover arquivos .pyc
Write-Host "`n[6/7] Removendo bytecode .pyc..." -ForegroundColor Green
$pycFiles = Get-ChildItem -Path $DistPath -Recurse -Include *.pyc -File
$pycSize = ($pycFiles | Measure-Object -Property Length -Sum).Sum / 1MB
if ($pycFiles.Count -gt 0) {
$pycFiles | Remove-Item -Force
Write-Host " Removidos $($pycFiles.Count) arquivos, economia de $([math]::Round($pycSize, 2)) MB"
} else {
Write-Host " Nenhum arquivo .pyc encontrado (já otimizado)" -ForegroundColor Gray
}
# 7. Reduzir metadados .dist-info
Write-Host "`n[7/7] Reduzindo metadados .dist-info..." -ForegroundColor Green
$distInfoDirs = Get-ChildItem -Path $DistPath -Recurse -Directory -Filter "*.dist-info"
$removedCount = 0
$removedSize = 0
foreach ($infoDir in $distInfoDirs) {
# Remover apenas arquivos contábeis de instalação; manter METADATA e entry_points.txt (lidos por importlib.metadata em tempo de execução; removê-los quebraria a descoberta de plugins)
$filesToRemove = @("RECORD", "INSTALLER", "direct_url.json")
foreach ($fileName in $filesToRemove) {
$file = Join-Path $infoDir.FullName $fileName
if (Test-Path $file) {
$size = (Get-Item $file).Length
$removedSize += $size
Remove-Item $file -Force
$removedCount++
}
}
}
if ($removedCount -gt 0) {
Write-Host " Removidos $removedCount arquivos de metadados, economia de $([math]::Round($removedSize / 1MB, 2)) MB"
} else {
Write-Host " Nenhum metadado a ser limpo encontrado (já otimizado)" -ForegroundColor Gray
}
# Calcular tamanho final
$FinalSize = (Get-ChildItem -Path $DistPath -Recurse -File | Measure-Object -Property Length -Sum).Sum / 1MB
$SavedSize = $InitialSize - $FinalSize
$SavedPercent = if ($InitialSize -gt 0) { ($SavedSize / $InitialSize) * 100 } else { 0 }
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Limpeza concluída!" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Tamanho inicial: $([math]::Round($InitialSize, 2)) MB" -ForegroundColor Yellow
Write-Host "Tamanho final: $([math]::Round($FinalSize, 2)) MB" -ForegroundColor Green
Write-Host "Espaço economizado: $([math]::Round($SavedSize, 2)) MB ($([math]::Round($SavedPercent, 1))%)" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
# (conteúdo truncado conforme original)