build web2py also with bbfreeze

This commit is contained in:
niphlod
2013-10-12 14:25:30 +02:00
parent 5551a018ac
commit cf8ee0acac
+98 -67
View File
@@ -1,17 +1,20 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" #Adapted from http://bazaar.launchpad.net/~flavour/sahana-eden/trunk/view/head:/static/scripts/tools/standalone_exe.py
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 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 from distutils.core import setup
import py2exe
from gluon.import_all import base_modules, contributed_modules from gluon.import_all import base_modules, contributed_modules
from gluon.fileutils import readlines_file from gluon.fileutils import readlines_file
from glob import glob from glob import glob
@@ -22,6 +25,28 @@ import sys
import re import re
import zipfile 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 #read web2py version from VERSION file
web2py_version_line = readlines_file('VERSION')[0] web2py_version_line = readlines_file('VERSION')[0]
#use regular expression to get just the version number #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") zip_filename = Config.get("Setup", "zip_filename")
remove_build_files = Config.getboolean("Setup", "remove_build_files") remove_build_files = Config.getboolean("Setup", "remove_build_files")
# Python base version # Python base version
python_version = sys.version_info[:3] 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): if python_version > (2,5):
# Python26 compatibility: http://www.py2exe.org/index.cgi/Tutorial#Step52 # Python26 compatibility: http://www.py2exe.org/index.cgi/Tutorial#Step52
try: try:
shutil.copytree('C:\Bin\Microsoft.VC90.CRT', 'dist/') shutil.copytree('C:\Bin\Microsoft.VC90.CRT', 'dist/')
except: 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( setup(
console=[{'script':'web2py.py', console=[{'script':'web2py.py',
'icon_resources': [(0, 'extras/icons/web2py.ico')] 'icon_resources': [(0, 'extras/icons/web2py.ico')]
}], }],
windows=[{'script':'web2py.py', windows=[{'script':'web2py.py',
'icon_resources': [(1, 'extras/icons/web2py.ico')], 'icon_resources': [(1, 'extras/icons/web2py.ico')],
'dest_base':'web2py_no_console' # MUST NOT be just 'web2py' otherwise it overrides the standard web2py.exe 'dest_base':'web2py_no_console' # MUST NOT be just 'web2py' otherwise it overrides the standard web2py.exe
}], }],
name="web2py", name="web2py",
version=web2py_version, version=web2py_version,
description="web2py web framework", description="web2py web framework",
author="Massimo DiPierro", author="Massimo DiPierro",
license="LGPL v3", license="LGPL v3",
data_files=[ data_files=[
'ABOUT', 'ABOUT',
'LICENSE', 'LICENSE',
'VERSION' 'VERSION'
], ],
options={'py2exe': { options={'py2exe': {
'packages': contributed_modules, 'packages': contributed_modules,
'includes': base_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): def copy_folders(source, destination):
"""Copy files & folders from source to destination (within dist/)""" """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)) 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 #should we remove Windows OS dlls user is unlikely to be able to distribute
if remove_msft_dlls: if remove_msft_dlls:
print "Deleted Microsoft files not licensed for open source distribution" 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!" 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)) os.unlink(os.path.join('dist', f))
except: except:
print "unable to delete dist/" + f print "unable to delete dist/" + f
#sys.exit(1)
#Should we include applications? #Should we include applications?
if copy_apps: if copy_apps:
@@ -136,7 +180,6 @@ if copy_site_packages:
else: else:
#no worries, web2py will create the (empty) folder first run #no worries, web2py will create the (empty) folder first run
print "Skipping site-packages" print "Skipping site-packages"
pass
#should we copy project's scripts into dist/scripts #should we copy project's scripts into dist/scripts
if copy_scripts: if copy_scripts:
@@ -145,31 +188,18 @@ if copy_scripts:
else: else:
#no worries, web2py will create the (empty) folder first run #no worries, web2py will create the (empty) folder first run
print "Skipping scripts" 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? #should we create a zip file of the build?
if make_zip: 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 #create a web2py folder & copy dist's files into it
shutil.copytree('dist', 'zip_temp/web2py') shutil.copytree('dist', 'zip_temp/web2py')
#create zip file #create zip file
#use filename specified via command line zipf = zipfile.ZipFile(zip_filename + ".zip",
zipf = zipfile.ZipFile( "w", compression=zipfile.ZIP_DEFLATED)
zip_filename + ".zip", "w", compression=zipfile.ZIP_DEFLATED) # just temp so the web2py directory is included in our zip file
path = 'zip_temp' # just temp so the web2py directory is included in our zip file path = 'zip_temp'
recursive_zip( # leave the first folder as None, as path is root.
zipf, path) # leave the first folder as None, as path is root. recursive_zip(zipf, path)
zipf.close() zipf.close()
shutil.rmtree('zip_temp') shutil.rmtree('zip_temp')
print "Your Windows binary version of web2py can be found in " + \ print "Your Windows binary version of web2py can be found in " + \
@@ -178,10 +208,11 @@ if make_zip:
#should py2exe build files be removed? #should py2exe build files be removed?
if remove_build_files: if remove_build_files:
shutil.rmtree('build') if BUILD_MODE == 'py2exe':
shutil.rmtree('build')
shutil.rmtree('deposit') shutil.rmtree('deposit')
shutil.rmtree('dist') shutil.rmtree('dist')
print "py2exe build files removed" print "build files removed"
#final info #final info
if not make_zip and not remove_build_files: if not make_zip and not remove_build_files: