From cf8ee0acac133999376241a75daf632945dc1d2b Mon Sep 17 00:00:00 2001 From: niphlod Date: Sat, 12 Oct 2013 14:25:30 +0200 Subject: [PATCH] build web2py also with bbfreeze --- extras/build_web2py/setup_exe.py | 165 ++++++++++++++++++------------- 1 file changed, 98 insertions(+), 67 deletions(-) diff --git a/extras/build_web2py/setup_exe.py b/extras/build_web2py/setup_exe.py index ed5910c5..1ca86327 100755 --- a/extras/build_web2py/setup_exe.py +++ b/extras/build_web2py/setup_exe.py @@ -1,17 +1,20 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -""" -Usage: - Install py2exe: http://sourceforge.net/projects/py2exe/files/ - Copy script to the web2py directory - c:\bin\python26\python setup_exe.py py2exe +#Adapted from http://bazaar.launchpad.net/~flavour/sahana-eden/trunk/view/head:/static/scripts/tools/standalone_exe.py -Adapted from http://bazaar.launchpad.net/~flavour/sahana-eden/trunk/view/head:/static/scripts/tools/standalone_exe.py +USAGE = """ +Usage: + Copy this and setup_exe.conf to web2py root folder + To build with py2exe: + Install py2exe: http://sourceforge.net/projects/py2exe/files/ + run python setup_exe.py py2exe + To build with bbfreeze: + Install bbfreeze: https://pypi.python.org/pypi/bbfreeze/ + run python setup_exe.py bbfreeze """ from distutils.core import setup -import py2exe from gluon.import_all import base_modules, contributed_modules from gluon.fileutils import readlines_file from glob import glob @@ -22,6 +25,28 @@ import sys import re import zipfile +if len(sys.argv) != 2 or not os.path.isfile('web2py.py'): + print USAGE + sys.exit(1) +BUILD_MODE = sys.argv[1] +if not BUILD_MODE in ('py2exe', 'bbfreeze'): + print USAGE + sys.exit(1) + +def unzip(source_filename, dest_dir): + with zipfile.ZipFile(source_filename) as zf: + zf.extractall(dest_dir) + +#borrowed from http://bytes.com/topic/python/answers/851018-how-zip-directory-python-using-zipfile +def recursive_zip(zipf, directory, folder=""): + for item in os.listdir(directory): + if os.path.isfile(os.path.join(directory, item)): + zipf.write(os.path.join(directory, item), folder + os.sep + item) + elif os.path.isdir(os.path.join(directory, item)): + recursive_zip( + zipf, os.path.join(directory, item), folder + os.sep + item) + + #read web2py version from VERSION file web2py_version_line = readlines_file('VERSION')[0] #use regular expression to get just the version number @@ -40,53 +65,75 @@ make_zip = Config.getboolean("Setup", "make_zip") zip_filename = Config.get("Setup", "zip_filename") remove_build_files = Config.getboolean("Setup", "remove_build_files") - # Python base version python_version = sys.version_info[:3] -# List of modules deprecated in python2.6 that are in the above set -py26_deprecated = ['mhlib', 'multifile', 'mimify', 'sets', 'MimeWriter'] - -if python_version > (2,5): - base_modules += ['json', 'multiprocessing', 'ldap'] - base_modules = list(set(base_modules).difference(set(py26_deprecated))) - - -#I don't know if this is even necessary if python_version > (2,5): # Python26 compatibility: http://www.py2exe.org/index.cgi/Tutorial#Step52 try: shutil.copytree('C:\Bin\Microsoft.VC90.CRT', 'dist/') except: - print "You MUST copy Microsoft.VC90.CRT folder into the dist directory" + print "You MUST copy Microsoft.VC90.CRT folder into the archive" +if BUILD_MODE == 'py2exe': + import py2exe -setup( - console=[{'script':'web2py.py', - 'icon_resources': [(0, 'extras/icons/web2py.ico')] - }], - windows=[{'script':'web2py.py', - 'icon_resources': [(1, 'extras/icons/web2py.ico')], - 'dest_base':'web2py_no_console' # MUST NOT be just 'web2py' otherwise it overrides the standard web2py.exe - }], - name="web2py", - version=web2py_version, - description="web2py web framework", - author="Massimo DiPierro", - license="LGPL v3", - data_files=[ - 'ABOUT', - 'LICENSE', - 'VERSION' - ], - options={'py2exe': { - 'packages': contributed_modules, - 'includes': base_modules, - }}, -) + setup( + console=[{'script':'web2py.py', + 'icon_resources': [(0, 'extras/icons/web2py.ico')] + }], + windows=[{'script':'web2py.py', + 'icon_resources': [(1, 'extras/icons/web2py.ico')], + 'dest_base':'web2py_no_console' # MUST NOT be just 'web2py' otherwise it overrides the standard web2py.exe + }], + name="web2py", + version=web2py_version, + description="web2py web framework", + author="Massimo DiPierro", + license="LGPL v3", + data_files=[ + 'ABOUT', + 'LICENSE', + 'VERSION' + ], + options={'py2exe': { + 'packages': contributed_modules, + 'includes': base_modules, + }}, + ) + #py2exe packages lots of duplicates in the library.zip, let's save some space + library_temp_dir = os.path.join('dist', 'library_temp') + library_zip_archive = os.path.join('dist', 'library.zip') + os.makedirs(library_temp_dir) + unzip(library_zip_archive, library_temp_dir) + os.unlink(library_zip_archive) + zipl = zipfile.ZipFile(library_zip_archive, "w", compression=zipfile.ZIP_DEFLATED) + recursive_zip(zipl, library_temp_dir) + zipl.close() + shutil.rmtree(library_temp_dir) + print "web2py binary successfully built" -print "web2py binary successfully built" +elif BUILD_MODE == 'bbfreeze': + modules = base_modules + contributed_modules + from bbfreeze import Freezer + f = Freezer(distdir="dist", includes=(modules)) + #f.addScript("web2py_gevent.py") + f.addScript("web2py.py") + #to make executable without GUI we need this trick + shutil.copy("web2py.py", "web2py_no_console.py") + f.addScript("web2py_no_console.py", gui_only=True) + f.setIcon('extras/icons/web2py.ico') + f() # starts the freezing process + os.unlink("web2py_no_console.py") + #add data_files + for req in ['ABOUT', 'LICENSE', 'VERSION']: + shutil.copy(req, os.path.join('dist', req)) + print "web2py binary successfully built" +try: + os.unlink('storage.sqlite') +except: + pass def copy_folders(source, destination): """Copy files & folders from source to destination (within dist/)""" @@ -95,7 +142,6 @@ def copy_folders(source, destination): shutil.copytree(os.path.join(source), os.path.join('dist', destination)) #should we remove Windows OS dlls user is unlikely to be able to distribute - if remove_msft_dlls: print "Deleted Microsoft files not licensed for open source distribution" print "You are still responsible for making sure you have the rights to distribute any other included files!" @@ -110,8 +156,6 @@ if remove_msft_dlls: os.unlink(os.path.join('dist', f)) except: print "unable to delete dist/" + f - #sys.exit(1) - #Should we include applications? if copy_apps: @@ -136,7 +180,6 @@ if copy_site_packages: else: #no worries, web2py will create the (empty) folder first run print "Skipping site-packages" - pass #should we copy project's scripts into dist/scripts if copy_scripts: @@ -145,31 +188,18 @@ if copy_scripts: else: #no worries, web2py will create the (empty) folder first run print "Skipping scripts" - pass - - -#borrowed from http://bytes.com/topic/python/answers/851018-how-zip-directory-python-using-zipfile -def recursive_zip(zipf, directory, folder=""): - for item in os.listdir(directory): - if os.path.isfile(os.path.join(directory, item)): - zipf.write(os.path.join(directory, item), folder + os.sep + item) - elif os.path.isdir(os.path.join(directory, item)): - recursive_zip( - zipf, os.path.join(directory, item), folder + os.sep + item) #should we create a zip file of the build? - if make_zip: - #to keep consistent with how official web2py windows zip file is setup, #create a web2py folder & copy dist's files into it shutil.copytree('dist', 'zip_temp/web2py') #create zip file - #use filename specified via command line - zipf = zipfile.ZipFile( - zip_filename + ".zip", "w", compression=zipfile.ZIP_DEFLATED) - path = 'zip_temp' # just temp so the web2py directory is included in our zip file - recursive_zip( - zipf, path) # leave the first folder as None, as path is root. + zipf = zipfile.ZipFile(zip_filename + ".zip", + "w", compression=zipfile.ZIP_DEFLATED) + # just temp so the web2py directory is included in our zip file + path = 'zip_temp' + # leave the first folder as None, as path is root. + recursive_zip(zipf, path) zipf.close() shutil.rmtree('zip_temp') print "Your Windows binary version of web2py can be found in " + \ @@ -178,10 +208,11 @@ if make_zip: #should py2exe build files be removed? if remove_build_files: - shutil.rmtree('build') + if BUILD_MODE == 'py2exe': + shutil.rmtree('build') shutil.rmtree('deposit') shutil.rmtree('dist') - print "py2exe build files removed" + print "build files removed" #final info if not make_zip and not remove_build_files: