Сама программа несложная, написалась относительно быстро. Намного больше времени отъела сборка ее под винду. Понятно, что выбранные инструменты (Python3 + Qt5) не родные, а универстальные, но что потребуется столько времени затратить на сборку, я не предполагал.
Соответственно, хочется поделиться практикой, может кому еще придется стучаться лбом в эту стену.
Под катом выстраданная инструкция как легко собирать PyQt5 приложения в single-file.exe не требующий инсталлятора.
Наиболее известные решения для моей задачи — сборки python приложений в .exe это: py2exe, cx_freeze и pyinstaller. Про каждый написано много всего. Но очень часто авторы грешат халтурой — легко и быстро собирается программа и запускается… на том же самом компьютере. Надо ли говорить, что это две большие разницы — запуск на дев-среде и у пользователя? У меня-то и так заработает безо всяких сборок и танцев с бубном. Кроме того — кто из пользователей будет ставить себе Qt?
Для каждого инструмента есть туториал. Но у каждого были свои проблемы: один не запускался (pyinstaller до сих пор поддерживает 3-й питон в экспериментальном режиме), другой собрал то, что не смог запустить, третий вообще долгое время ничего не собирал, ругая все вокруг.
После долгой борьбы был выбран py2exe.
Секрет успеха в правильной установке компонент из правильных источников (я не даю прямые ссылки, т.к. они все равно устареют, пишу что где искать):
- Win XP 32-bit (или другая, которую вы возьмете за базу — я специально взял самую старую систему)
- Python 3.4 — устанавливаем с http://ift.tt/1INnLTf Windows x86 msi installer. Можно сразу добавить C:\Python34\ в %PATH%
- PyWin32 — ставим с sf.net файл pywin32-219.win32.py3.4.exe
- Qt5.5 — ставим с официального сайта qt.io. Одновременно с ним ставится компилятор mingw4.9.2
- После установки добавляем C:\Qt\Tools\mingw492_32\bin в %PATH%.
- Git for Windows — он нам нужен в любом случае, ставим с git-scm.com
- PyQt5 — качаем и ставим riverbankcomputing.co.uk win32 x86 installer
- SIP — я так и не понял почему, но тот же самый riverbankcomputing.co.uk не удосужился собрать служебный модулек, поэтому качаем win сорцы, распаковываем, дальше удобно продолжить работу в консоли Git Bash:
- python configure.py -p win32-g++
- mingw32-make.exe
- mingw32-make.exe install.
- Само собой, инсталляция не сработает (. К счастью, нам нужно поставить всего 3 файла. Идем руками в подпапку sipgen/ folder и копируем sip.exe в C:\Python34.
- Затем иде в ../siplib и
- copy sip.pyd c:\python34\Lib\site-packages
- strip /c/Python34/Lib/site-packages/sip.pyd
- наконец, копируем .h-файл:
- cp sip.h /c/Python34/include/
- py2exe — ставим родным способом: python -m pip install py2exe
- pyreadline — так же: python -m pip install pyinstaller
- 7-Zip — c сайта 7-zip.org качаем x86 exe
- 7-zip extra — полезные дополнения качаем оттуда же, распаковываем в папку с установленным 7-zip folder. На конфликты txt-файлов можно забить.
- Resource Hacker — качаем angusj.com — впрочем, если вы не собираетесь заменять дефолтную пиктограмму программы на свою, то она вам не потребуется. Либо ее можно заменить на windres, которая идет в комплекте с mingw — но у меня уже было сделано с RH.
Делюсь своим setup.py:
from distutils.core import setup
import os, sys
import py2exe
from glob import glob
import PyQt5
NAME="Proga"
qt_platform_plugins = [("platforms", glob(PyQt5.__path__[0] + r'\plugins\platforms\*.*'))]
data_files.extend(qt_platform_plugins)
msvc_dlls = [('.', glob(r'C:\Windows\System32\msvc?100.dll'))]
data_files.extend(msvc_dlls)
# print(data_files)
sys.argv.append('py2exe')
setup(
data_files=data_files,
windows=[
{
"script": "pyftp1.py",
"icon_resources": [(0, "resources/favicon.ico")]
}
],
# zipfile=None,
options={
"py2exe": {
"includes":["sip", "atexit",], # даже если мы нигде не используем atexit его надо добавить, sip указываем явно - сборщики часто про него забывают
# "packages": ['PyQt5'],
"compressed": True,
"dist_dir": "dist/" + NAME,
# "bundle_files": 0, # не сработало ( с этой опцией на выходе прога не может найти msvc*.dll
# "zipfile": None, # тоже лишнее
"optimize": 2,
}
}
)
Это программа-минимум. Теперь можно собирать само приложение:
python setup.py py2exe
На выходе получаем папку с готовой прогой в dist.
Это хорошо, но не всегда удобно для пользователей. На эту папку можно натравить создаватель инсталляторов, типа Inno Setup и получить msi. В моем случае, надо было обеспечить работоспособность программы с минимальными правами пользователей — точно без права установки либ.
Поэтому я пошел дальше и запаковал в 1 файл с помощью 7-zip. Схема такая: создаем 7z-архив и к нему пристыковывается специальная SFX-голова и конфиг. Голова распаковывает архив во временную папку, смотрит в конфиг и запускает нужный exe-файл. Собирается примерно так:
cat 7zS.sfx resources/config.txt Proga.7z > Proga.exe
В файле конфига можно указать разные опции, я задал минимум:
;!@Install@!UTF-8!
Title="Proga"
RunProgram="Proga\\pyftp1.exe"
;!@InstallEnd@!
Единственный недостаток — некрасивая картинка у exe файла — стандартный распаковщик. Тут-то и подменяем ему картинку на нужную нам:
RESHACKER.exe -addoverwrite Proga.exe, Proga.exe, resources/favicon.ico, ICONGROUP, MAINICON, 0
Чтобы не мучаться с этим всем в консоли, я сделал небольшой Makefile:
# start settings
DIST=dist
# change NAME also in setup.py and resource/config.txt
NAME=Proga
EXT=exe
# final name and location of the built program
FINAL=$(DIST)/$(NAME).$(EXT)
# external programs
7ZIPDIR="C:\Program Files\7-Zip"
RESHACKER="/c/Program\ Files/Resource\ Hacker/ResourceHacker.exe"
# intermediate steps
# no icon version of program
NOICON=$(DIST)/$(NAME)_no_icon.$(EXT)
# name of .7z archive
7Z_BASENAME=$(NAME).7z
7Z=$(DIST)/$(7Z_BASENAME)
# folder with ready .exe
PROGDIR=$(DIST)/$(NAME)
all: $(FINAL)
$(FINAL): $(NOICON)
# change icon
"$(RESHACKER)" -addoverwrite $(NOICON), $(FINAL), resources/favicon.ico, ICONGROUP, MAINICON, 0
$(NOICON): $(7Z)
#build autorunning sfx with default icon
cat $(7ZIPDIR)/7zS.sfx resources/config.txt $(7Z) > $(NOICON)
$(7Z): exe
# compress program folder to .7z
cd $(DIST); $(7ZIPDIR)\\\7z.exe a $(7Z_BASENAME) $(NAME)
exe: $(DIST)
# build program itself
python setup.py py2exe
$(DIST):
# create dist directory
# echo $(DIST)/
clean:
rm -rf $(DIST)/*
Теперь можно очень легко пересобирать прогу:
mingw492-make.exe clean all
Успехов в сборке!
Расскажите про свой опыт!
This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий