Python27, protobuf, py2exe e build_exe
Caloni, 2018-07-14 computer blogPara quem está tentando compilar um executável usando py2exe e protobuf, #ficadica: desista. Ele não vai funcionar ou se funcionar vai dar trabalho. Em vez disso melhor usar build_exe (através do pacote cx_freeze), que é um esquema marotinho que permite configurar tudo e há apenas um patchzinho que precisa ser feito.
Para entender como as coisas dão errado primeiro vamos instalar os requisitos de um pacote fictício em um ambiente virtualizado do Python (para evitar mexer na instalação padrão):
virtualenv python27 New python executable in blablabla\python27\Scripts\python.exe Installing setuptools, pip, wheel...done.
Depois instalamos os requisitos de nosso pacote fictício:
python27\Scripts\activate.bat (python27) pushd blablabla\MyFictionalPackage (python27) blablabla\MyFictionalPackage>pip install -r requirements.txt Installing protobuf, pyodbc, etc.
Agora vem a hora do erro. O protobuf que foi instalado possui um pequeno bug que impede que o build_exe obtenha essa dependência corretamente na hora de gerar o executável:
(python27) blablabla\MyFictionalPackage>python setup.py build_exe
running build_exe
Traceback (most recent call last):
// ... long lines of errors
"blablabla\python27\lib\site-packages\cx_Freeze\finder.py"
, line 351, in _ImportModule
raise ImportError("No module named %r" % name)
ImportError: No module named 'google.protobuf'
Para fazer funcionar há um pequeno patch: criar um arquivo __init__.py dentro da pasta google onde está instalado o pacote do protobuf. A ramificação do pacote fica em size-packages, google, protobuf. Você precisa criar este __init__.py dentro da pasta google. Após essa pequena operação já será possível gerar o executável com sucesso:
(python27) blablabla\MyFictionalPackage>python setup.py build_exe running build_exe copying blablabla\python27\lib\site-packages\cx_Freeze\bases\Console.exe -> build\exe.win32-2.7\MyFictionalPackage.exe copying C:\WINDOWS\SYSTEM32\python27.dll -> build\exe.win32-2.7\python27.dll install pywin32 extensions first writing zip file build\exe.win32-2.7\lib\library.zip Name File ---- ---- long list of files Missing modules: long list of modules This is not necessarily a problem - the modules may not be needed on this platform. copying file1 -> file2 etc
Agora ao listarmos os executáveis gerados encontraremos nosso amigo fictício:
(python27) blablabla\MyFictionalPackage>dir /s /b *.exe blablabla\MyFictionalPackage\build\exe.win32-2.7\MyFictionalPackage.exe
Nota: conteúdo do arquivo setup.py:
import sys
import os
from cx_Freeze import setup, Executable
exe = [
Executable('MyFictionalPackage.py')
]
option = { 'build_exe' : {
'path' : sys.path.append(os.getcwd()),
'includes' : ['google.protobuf', 'pkgutil',
'pyodbc', 'decimal'],
}
}
setup(name = "teste_cx_Freeze",
version = "0.1",
description = "",
options = option,
executables=exe
)