build web2py also with bbfreeze
This commit is contained in:
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user