PyQt ã§ã¯ãã¹ãã©ãããã©ã¼ã ãªãã¹ã¯ãããã¢ããªã±ã¼ã·ã§ã³ã
ããä½ã¶æããã¹ã¯ãããã¢ããªã±ã¼ã·ã§ã³ã«ã©ã£ã·ããªæãã§ã。ããã±ã¼ã¸ã³ã°ããã£ã¨ç°¡åã«ããã!ã¨ãããã¨ã§è²ã ã¨è©¦è¡é¯èª¤ãã¦ããã¾ãã。linux, mac ã¯ããæãã§ãã、Windows ã¯・・・ py2exe ã§ããªã¼ã¸ã³ã°ã®ã¿ãããã¦ãã¾ããã§ãã。é å¸ã¨ã¤ã³ã¹ãã¼ã«ã¯èªå解åæ¸åº«、ã¢ãããã¼ã、ã¢ã³ã¤ã³ã¹ãã¼ã«ã¯・・・。ããã§ä»å (ãã£ã¨) è¦ããã®ã Inno Setup ã WiX ã¨ãã£ã Windows ç¨ã®ããã±ã¼ã¸ãã«ãã§ã。åå¿é²ãã¦ã、Python ã§ã®ããã±ã¼ã¸ã³ã°ãã¾ã¨ãã¦ã¿ã¾ãã。
ããã±ã¼ã¸ã³ã°ã«ã¤ãã¦
大ãã 2 ã¤ã®ãã§ã¼ãºã«åããã¦ãã¾ã。
- ããªã¼ã¸ã³ã°: Python ãã³ãã«ãä»ã®å¿
è¦ãªã©ã¤ãã©ãªã¼ãå¯ãéã、å®è¡å¯è½å½¢å¼ã«ã¾ã¨ãã¾ã。
Windows 㨠OS X ã«ã¤ãã¦ã¯ä»¥ä¸ã®ã©ã¤ãã©ãªã§ããªã¼ã¸ã³ã°ãã¾ã。
Linux ãå«ãã¯ãã¹ãã©ãããã©ã¼ã ãªããªã¼ã¸ã³ã°ãã§ãã cx_Freeze ã¨ããã®ãããã¾ã。 - ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ãã«ã
-
- Windows: Microsoft Windows Installer ã¯ã¢ããã°ã¬ã¼ã、ã¢ã³ã¤ã³ã¹ãã¼ã«、ãã©ã³ã¶ã¯ã·ã§ã³å¦çã使ã£ãè¤æ°ããã±ã¼ã¸ã®ç®¡çã¨ãã®ä¾¿å©æ©è½ãæã£ã¦ãã¾ã。
-
- WiX (Wikipedia): MSI å½¢å¼ã§ãã«ãããããã® MS 製ã®ãªã¼ãã³ã½ã¼ã¹ãã¼ã«ã§ã。WXS ã¨ãã XML ãã¡ã¤ã«ãä½æã、ãããå ã«ãã«ããã¾ã。
- Inno Setup (æ¥æ¬ããã¥ã¡ã³ã): Windows ã¤ã³ã¹ãã¼ã© (Setup.exe) ãä½æãããªã¼ãã³ã½ã¼ã¹ãã¼ã«ã§ã。Delphi ã§æ¸ããã¦ãã¾ã。
- NSIS (Wikipedia): å¤æ©è½。ã¹ã¯ãªããé§ååã®Windowsç¨ã¤ã³ã¹ãã¼ã«ã·ã¹ãã 。Mozilla, Google, BitTorrent ãªã©ã«ã使ããã¦ãã¾ã。
- ä»ã«ãããããã§ã。
- OS X: hdiutil: py2app ã§ã§ãã *.app ã *.dmg ã«ãã¦ããããããã§ã (使ã£ããã¨ããã¾ãã)。
ã¯ãã¹ãã©ãããã©ã¼ã 㪠setup.py ã®æ¸ãæ¹
Windows 㨠OS X ã®ããªã¼ã¸ã³ã°ã¯、py2exe 㨠py2app ãããã®ã§ç°¡åã§ã。ãã©ãããã©ã¼ã æ å ±ãåå¾ã、åãã©ãããã©ã¼ã ã«å¯¾ãã¦ããªã¼ã¸ã³ã°ãã¾ã。ããããªã³ã¼ããè¦ã¾ããã、åãåããã³ã¼ãã¯å¤§ãã 2 種é¡ããã¾ãã。ç§ã¯ç°¡åãªã®ã§åè ã使ã£ã¦ãã¾ã。
import sys if sys.platform == 'win32': u"""Windows ç¨ã®ããªã¼ã¸ã³ã°""" import py2exe # å¦ç if sys.platform == 'darwin': u"""OS X ç¨ã®ããªã¼ã¸ã³ã°""" import py2app # å¦ç if sys.platform == 'linux2': u"""Linux ç¨ã®ãã«ã""" import subprocess u""" makeself çã§ã¤ã³ã¹ãã¼ã©ãä½æããã³ãã³ããå®è¡:: ret = subprocess.Popen("makeself ...") ret.wait() cx_Freeze ã§ãããã¨æãã¾ã。 """
import platform if platform.system() in ['Windows', 'Microsoft']: u"""Windows ç¨ã®ããªã¼ã¸ã³ã°""" # çç¥ if platform.system() == 'Darwin': u"""OS X ç¨ã®ããªã¼ã¸ã³ã°""" # çç¥ if platform.system() == 'Linux': u"""Linux ç¨ã®ãã«ã""" # çç¥
Inno Setup ã«ãããã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ãã«ã
Inno Setup 㯠distutils ã®æ¡å¼µã¢ã¸ã¥ã¼ã«ã pypi ã«æä¾ããã¦ãã¾ã。ãªã®ã§、ä¸è¨ã® setup.py ã«ã¡ãã£ã¨è¿½å ããã°、Windows ã«ã¤ãã¦ã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ãã«ããããªããæ軽ã«ãªãã¾ã。
ç°å¢ã®æ§ç¯
- Visual C++ (Windows Platform SDK): py2exe ã«ãå¿ è¦
- Inno Setup QuickStart Pack: IStools Script Editor çã®ãµã¼ããã¼ãã£ã¢ããªã³ãªã©ãå«ã¾ãã¾ã
- innosetup Pythono ã©ã¤ãã©ãª: Inno Setup ç¨ã©ã¤ãã©ãª
setup.py ã®æ¸ãæ¹
PyQt ã¢ããªã±ã¼ã·ã§ã³ã®ãã£ã¬ã¯ããªæ§æã¯ä»¥ä¸ã®ããã«ãã¾ãã。
- path/to/project: ããã¸ã§ã¯ããã£ã¬ã¯ããª
-
- dist: ããã±ã¼ã¸ãä¿åããããã£ã¬ã¯ã㪠(èªåçã«ä½æããã¾ã)
- test: PyQt ã¢ããªã±ã¼ã·ã§ã³ãã£ã¬ã¯ããª
-
- media: ã¢ã¤ã³ã³ãã¡ã¤ã«ãªã©ã®ãªã½ã¼ã¹ãä¿åãããã£ã¬ã¯ããª
-
- test.ico: ã¢ã¤ã³ã³ãã¡ã¤ã«
- main.py: ã¡ã¤ã³ã¹ã¯ãªãã
- setup.py: ããã±ã¼ã¸ã³ã°ç¨ã¹ã¯ãªãã
- README: ã¢ããªã±ã¼ã·ã§ã³æ¦è¦ãè¨è¼ãããã¡ã¤ã« (Windows ã®å ´å㯠cp932 ã«ä¿å)
- LICENSE: ã©ã¤ã»ã³ã¹ãè¨è¼ãããã¡ã¤ã« (cp932)
#!/usr/bin/env python2.6 # -*- coding: utf-8 -*- import os import sys, subprocess from distutils.core import setup ######################################## # ã³ã³ãã¤ã«ãªãã·ã§ã³è¨å® # ######################################## # ãã¤ããªå NAME = u"test" # ãã¼ã¸ã§ã³æ å ± VERSION = "1.0.0" # èä½æ¨© AUTHOR = "Kosei Kitahara" # ã¡ã¼ã« EMAIL = "[email protected]" # URL u""" AppID ãçæããããã«ç¨ãããããã、ã¢ããªã±ã¼ã·ã§ã³æ¯ã«ã¦ãã¼ã¯ã«ãã """ URL = "http://example.com/test" # ããã±ã¼ã¸ æ¦è¦ DESCRIPTION = u"ãã¹ãç¨ã¢ããªã±ã¼ã·ã§ã³" # Python ãã¤ãã³ã¼ãã®æé©åãªãã·ã§ã³ (0: None, 1: -O, 2: -OO) OPTIMIZE = 2 # å§ç¸®ãªãã·ã§ã³ (0: å§ç¸®ããªã, 1: å§ç¸®ãã) COMPRESSED = 1 # ãã³ãã«ãªãã·ã§ã³ (1: åç¬, 3: åå¥) BUNDLE_FILES = 3 # ä¾åã©ã¤ãã©ãªã®è§£æ±º INCLUDES = ["sip", "ctypes", ] EXCLUDES = ["_ssl", "tcl", "tkinter", "Tkconstants", "Tkinter", ] DLL_EXCLUDES = ["tcl84.dll", "tk84.dll", ] # ãã£ã¬ã¯ããª, ãã¡ã¤ã«ãªã© BASE_DIR = os.path.abspath(os.path.dirname(__file__)) APPLICATION_DIR = os.path.join(BASE_DIR, "test") DIST_DIR = os.path.join(BASE_DIR, "dist") MAIN_SCRIPT_NAME = os.path.join(APPLICATION_DIR, "main.py") ICON_FILE_NAME = os.path.join(APPLICATION_DIR, "media", "test.ico") LICENSE_FILE_NAME = os.path.join(BASE_DIR, "LICENSE") ######################################## # ã¦ã¼ãã£ãªãã£é¢æ° # ######################################## def get_win32ui_files(): u"""win32ui ä¾å dll ã®åå¾""" import win32ui win32ui_dir = os.path.dirname(win32ui.__file__) return [os.path.join(win32ui_dir, i) for i in [ "mfc90.dll", "mfc90u.dll", "mfcm90.dll", "mfcm90u.dll", "Microsoft.VC90.MFC.manifest", ]] WIN32UI_MFCFILES = get_win32ui_files() def get_pyqt4_imageformats_plugin_files(): u"""PyQt4 ã®ç»åã³ã¼ããã¯ä¾å dll ã®åå¾""" import PyQt4 pyqt4_dir = os.path.dirname(PyQt4.__file__) return [os.path.join(pyqt4_dir, "plugins", "imageformats", i) for i in [ "qgif4.dll", "qico4.dll", "qjpeg4.dll", "qmng4.dll", "qsvg4.dll", "qtiff4.dll", ]] PYQT4_IMAGEFORMATS = get_pyqt4_imageformats_plugin_files() ######################################## # ãã«ãã¹ã¯ãªãã # ######################################## # Linux, OS X ã¯çç¥ if sys.platform == 'win32': u"""Windows ç¨ã®ããªã¼ã¸ã³ã°""" import py2exe, innosetup # py2exe, innosetup å ±éãã«ããªãã·ã§ã³ DATA_FILES = [ ("Microsoft.VC90.MFC", WIN32UI_MFCFILES), ("imageformats", PYQT4_IMAGEFORMATS), ] ICON_RESOURCES = [(1, ICON_FILE_NAME), ] PY2EXE_OPTIONS = { "includes": INCLUDES, "excludes": EXCLUDES, "dll_excludes": DLL_EXCLUDES, "compressed": COMPRESSED, "optimize": OPTIMIZE, "bundle_files": BUNDLE_FILES, } # innosetup ãã«ããªãã·ã§ã³ u""" 'inno_script' ã¯、.iss ãã¡ã¤ã«åãæå®ãããã¨ãã§ãã¾ãã、 ããã©ã«ãã§ãç¨æããã¦ããã®ã§、大å¤ä¾¿å©ã§ã。 """ INNOSETUP_OPTIONS = { "inno_script": innosetup.DEFAULT_ISS, "bundle_vcr": True, "zip": False, } setup( name=NAME, version=VERSION, license=LICENSE_FILE_NAME, author=AUTHOR, author_email=EMAIL, description=DESCRIPTION, url=URL, data_files=DATA_FILES, options={ "py2exe" : PY2EXE_OPTIONS, "innosetup": INNOSETUP_OPTIONS}, windows=[{ "script" : MAIN_SCRIPT_NAME, "icon_resources": ICON_RESOURCES}], zipfile="test.lib", )
py2exe ã®è¨å®ãç¶æ¿ãã¦ãããã®ã§、大å¤ä¾¿å©ã§ãã。
ããã±ã¼ã¸ã³ã°å¦çã®å®è¡
以ä¸ã®ã³ãã³ããå®è¡ããã¨、ããã±ã¼ã¸ã³ã°ãã¦ããã¾ã。
python setup.py innosetup
ãã¡ãã setup.py py2exe
ãåä½ãã¾ã。innosetup ã® run ã¡ã½ãã㯠py2exe ãç¶æ¿ãã¦ãã、dist ãã£ã¬ã¯ããªã«ä½æããã©ã¤ãã©ãªãå®è¡ãã¡ã¤ã«ã¯ py2exe ã¨åæ§ã§ã。ããã¨ã¯å¥ã«ä»¥ä¸ã®ãã¡ã¤ã«ãä½æããã¾ã。
- Microsoft.VC90.CRT.manifest
- distutils.iss: ã¤ã³ã¹ãã¼ã©ä½æç¨ ISS ãã¡ã¤ã«
- test-1.0.0-setup.exe: ã¤ã³ã¹ãã¼ã©ãã¡ã¤ã«。ãã¡ã¤ã«å㯠settings.py ã§è¨å®ãã [ã¢ããªã±ã¼ã·ã§ã³å]-[ãã¼ã¸ã§ã³]-setup.exe ã«ãªãã¾ã。
å®è¡ãã㨠Inno Setup Compiler ãèªåçã«èµ·åã、ä½æãã distutils.iss ãã¡ã¤ã«ãå ã«ã¤ã³ã¹ãã¼ã©ã¼ãä½æããã¾ã。éä¸ã§ã¨ã©ã¼ãåºãã、innosetup.py ãä¿®æ£ã、åºåãã ISS ãã¡ã¤ã«ãå¤æ´ãã¾ãããï½
ã¡ãªã¿ã«、ç§ã®ç°å¢ã§ã¯ä»¥ä¸ãä¿®æ£ãã¾ãã。
218c218 < return win32api.LoadResource(handle, restype, name).decode('utf_8') --- > return win32api.LoadResource(handle, restype, name).decode('utf-8') 525c525 < iss_metadata['MinVersion'] = '5.0,4.0' --- > iss_metadata['MinVersion'] = '0,5.0' 546c546 < fp.write('%s=%s\n' % (k, iss_metadata[k], )) --- > fp.write(unicode('%s=%s\n' % (k, iss_metadata[k], )).encode("utf-8")) 779c779 < fp.write('#define %s "%s"\n' % (k, consts[k], )) --- > fp.write(unicode('#define %s "%s"\n' % (k, consts[k], )).encode("utf-8"))
ããã§ãã¹ã¯ãããã¢ããªã±ã¼ã·ã§ã³ã®é å¸ãããªã楽ã«ãªãã¾ããã!ã¦ãã³ã¼ãã¤ã³ã¹ãã¼ã©ãªã©ã«ã¤ãã¦ã¯ããã¡ãã£ã¨èª¿ã¹ãå¿ è¦ãããã¾ãã・・・。
è¿½è¨ (2010-08-18)
試ãã¦ãªãã§ãã、bdist_nsi ã¨ãã NSS I ç¨ã® distutils æ¡å¼µã¢ã¸ã¥ã¼ã«ã pypi ã«ç»é²ããã¦ãã¾ãã。ã½ã¼ã¹ãè¦ãã¨、Python 3 ã«ã対å¿ãã¦ãã (Python 2 㯠3 ã¸å¤æ)、py2exe ã¯ä½¿ã£ã¦ãªãããã§ãã。ããã¯ããã!
ã³ã¡ã³ã
ã³ã¡ã³ããæ稿