Roger, here's the setup.py that I use for my commercial app, for building executables on Mac and Win.
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys # ModuleFinder can't handle runtime changes to __path__, but win32com uses them try: import py2exe.mf as modulefinder import win32com for p in win32com.__path__[1:]: modulefinder.AddPackagePath("win32com", p) for extra in ["win32com.shell"]: #,"win32com.mapi" __import__(extra) m = sys.modules[extra] for p in m.__path__[1:]: modulefinder.AddPackagePath(extra, p) except ImportError: # no build path setup, no worries. pass import os import glob if sys.platform.startswith("win"): from distutils.core import setup import py2exe else: from setuptools import setup if sys.platform.startswith("darwin"): import py2app import dabo.icons from App import App daboDir = os.path.split(dabo.__file__)[0] # Find the location of the dabo icons: iconDir = os.path.split(dabo.icons.__file__)[0] iconSubDirs = [] def getIconSubDir(arg, dirname, fnames): if ".svn" not in dirname and "cards" not in dirname.lower() and dirname[-1] != "\\": icons = glob.glob(os.path.join(dirname, "*.png")) if icons: subdir = (os.path.join("resources", dirname[len(arg)+1:]), icons) iconSubDirs.append(subdir) os.path.walk(iconDir, getIconSubDir, iconDir) # locales: localeDir = "%s%slocale" % (daboDir, os.sep) #locales = [("dabo.locale", (os.path.join(daboDir, "locale", "dabo.pot"),))] locales = [] def getLocales(arg, dirname, fnames): if ".svn" not in dirname and dirname[-1] != "\\": #po_files = tuple(glob.glob(os.path.join(dirname, "*.po"))) mo_files = tuple(glob.glob(os.path.join(dirname, "*.mo"))) if mo_files: subdir = os.path.join("dabo.locale", dirname[len(arg)+1:]) locales.append((subdir, mo_files)) os.path.walk(localeDir, getLocales, localeDir) # The applications App object contains all the meta info: app = App(MainFormClass=None) _appName = app.getAppInfo("appName") _appShortName = app.getAppInfo("appShortName") _appFileStem = _appShortName.lower().replace(" ", "_") _appVersion = app.getAppInfo("appVersion") _appDescription = app.getAppInfo("appDescription") _copyright = app.getAppInfo("copyright") _authorName = app.getAppInfo("authorName") _authorEmail = app.getAppInfo("authorEmail") _authorURL = app.getAppInfo("authorURL") _authorPhone = app.getAppInfo("authorPhone") _appComments = ("This is custom software by %s.\r\n" "\r\n" "%s\r\n" "%s\r\n" "%s\r\n") % (_authorName, _authorEmail, _authorURL, _authorPhone) _appIcon = "./resources/icon_green.ico" _script = "main.py" manifest = open("sbs_studio.exe.manifest").read() class Target: def __init__(self, **kw): self.__dict__.update(kw) # for the versioninfo resources self.version = _appVersion self.company_name = _authorName self.copyright = _copyright self.name = _appName self.description = _appDescription self.comments = _appComments self.script=_script self.other_resources = [(24, 1, manifest)] if _appIcon is not None: self.icon_resources = [(1, _appIcon)] data_files=[("db/sqlite", glob.glob("db/sqlite/*.sql")), ("resources", glob.glob(os.path.join(iconDir, "*.ico"))), ("resources", glob.glob("resources/*")), ("reports", glob.glob("reports/*")), ("messages", glob.glob("messages/*")), ("db/updates", glob.glob("db/updates/*"))] data_files.extend(iconSubDirs) data_files.extend(locales) if sys.platform.startswith("win"): options = {"py2exe": {"packages": ["encodings", "wx", "ui", "biz", "db", "ss_common.lib.floatcanvas"], #"optimize": 1, #"compressed": 1, "excludes": ["matplotlib", "Tkconstants","Tkinter","tcl", "_imagingtk", "PIL._imagingtk", "ImageTk", "PIL.ImageTk", "FixTk",], 'typelibs' : [('{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}', 0, 1, 1)] } } setup(name=_appName, version=_appVersion, description=_appDescription, author=_authorName, author_email=_authorEmail, url=_authorURL, options=options, zipfile=None, windows=[Target()], data_files=data_files, ) # Write out the setup.iss file for inno: iss = open("setup.iss.txt").read() % locals() open("setup.iss", "wb").write(iss) elif sys.platform.startswith("darwin"): options = {"py2app": {"includes": ["App", "__version__", "constants", "db.updates", "ui", "biz", "ss_common.lib.floatcanvas", "encodings", "wx", "wx.lib.calendar", "wx.gizmos"], "optimize": 2, "excludes": ["matplotlib", "Tkconstants","Tkinter","tcl", "_imagingtk", "PIL._imagingtk", "ImageTk", "PIL.ImageTk", "FixTk", "wxPython", ], "argv_emulation": True, "resources": data_files, "plist": dict(CFBundleGetInfoString=_appVersion, CFBundleIdentifier="com.sanbenitoshutter.sbs_studio", LSPrefersPPC=False, NSHumanReadableCopyright=_copyright ), "iconfile": "resources/logo_green.icns", } } setup(name="SBS Studio", app=[_script], version=_appVersion, description=_appDescription, author=_authorName, author_email=_authorEmail, url=_authorURL, options=options, #data_files=data_files, setup_requires=["py2app"] )
Also note that you need to set your icon in either your form or application. I set it in initProperties() of my dApp subclass, like:
def initProperties(self): appName = "Shutter Studio" self.AboutFormClass = ui.FrmAbout if sys.platform == "win32" and platform.version() < "5.1": # Windows versions < XP need the .ico file or the transparency is messed up. self.Icon = "icon_green.ico" else: # Other platforms benefit from the png package of icons: self.Icon = ("icon_green_16px.png", "icon_green_22px.png", "icon_green_32px.png", "icon_green_48px.png", "icon_green_64px.png")
