1
1
#! /usr/bin/env python
3
# This is an installation script for bzr. Run it with
4
# './setup.py install', or
5
# './setup.py --help' for more options
3
"""Installation script for bzr.
5
'./setup.py install', or
6
'./setup.py --help' for more options
14
if sys.version_info < (2, 4):
15
sys.stderr.write("[ERROR] Not a supported Python version. Need 2.4+\n")
18
# NOTE: The directory containing setup.py, whether run by 'python setup.py' or
19
# './setup.py' or the equivalent with another path, should always be at the
20
# start of the path, so this should find the right one...
23
def get_long_description():
24
dirname = os.path.dirname(__file__)
25
readme = os.path.join(dirname, 'README')
26
f = open(readme, 'rb')
34
# META INFORMATION FOR SETUP
35
# see http://docs.python.org/dist/meta-data.html
38
'version': bzrlib.__version__,
39
'author': 'Canonical Ltd',
40
'author_email': 'bazaar@lists.canonical.com',
41
'url': 'http://bazaar.canonical.com/',
42
'description': 'Friendly distributed version control system',
43
'license': 'GNU GPL v2',
44
'download_url': 'https://launchpad.net/bzr/+download',
45
'long_description': get_long_description(),
47
'Development Status :: 6 - Mature',
48
'Environment :: Console',
49
'Intended Audience :: Developers',
50
'Intended Audience :: System Administrators',
51
'License :: OSI Approved :: GNU General Public License (GPL)',
52
'Operating System :: Microsoft :: Windows',
53
'Operating System :: OS Independent',
54
'Operating System :: POSIX',
55
'Programming Language :: Python',
56
'Programming Language :: C',
57
'Topic :: Software Development :: Version Control',
61
# The list of packages is automatically generated later. Add other things
62
# that are part of BZRLIB here.
65
PKG_DATA = {# install files from selftest suite
66
'package_data': {'bzrlib': ['doc/api/*.txt',
67
'tests/test_patches_data/*',
68
'help_topics/en/*.txt',
69
'tests/ssl_certs/ca.crt',
70
'tests/ssl_certs/server_without_pass.key',
71
'tests/ssl_certs/server_with_pass.key',
72
'tests/ssl_certs/server.crt'
77
def get_bzrlib_packages():
78
"""Recurse through the bzrlib directory, and extract the package names"""
81
base_path = os.path.dirname(os.path.abspath(bzrlib.__file__))
82
for root, dirs, files in os.walk(base_path):
83
if '__init__.py' in files:
84
assert root.startswith(base_path)
85
# Get just the path below bzrlib
86
package_path = root[len(base_path):]
87
# Remove leading and trailing slashes
88
package_path = package_path.strip('\\/')
90
package_name = 'bzrlib'
92
package_name = ('bzrlib.' +
93
package_path.replace('/', '.').replace('\\', '.'))
94
packages.append(package_name)
95
return sorted(packages)
98
BZRLIB['packages'] = get_bzrlib_packages()
101
from distutils import log
7
102
from distutils.core import setup
9
# more sophisticated setup script, based on pychecker setup.py
11
from distutils.command.build_scripts import build_scripts
103
from distutils.command.install_scripts import install_scripts
104
from distutils.command.install_data import install_data
105
from distutils.command.build import build
14
107
###############################
15
108
# Overridden distutils actions
16
109
###############################
18
class my_build_scripts(build_scripts):
19
"""Customized build_scripts distutils action.
111
class my_install_scripts(install_scripts):
112
""" Customized install_scripts distutils action.
21
113
Create bzr.bat for win32.
116
install_scripts.run(self) # standard action
25
118
if sys.platform == "win32":
26
bat_path = os.path.join(self.build_dir, "bzr.bat")
27
self.scripts.append(bat_path)
28
self.mkpath(self.build_dir)
29
scripts_dir = self.distribution.get_command_obj("install").\
31
self.execute(func=self._create_bat,
32
args=[bat_path, scripts_dir],
33
msg="Create %s" % bat_path)
34
build_scripts.run(self) # invoke "standard" action
36
def _create_bat(self, bat_path, scripts_dir):
37
""" Creates the batch file for bzr on win32.
40
script_path = os.path.join(scripts_dir, "bzr")
41
bat_str = "@%s %s %%*\n" % (sys.executable, script_path)
42
file(bat_path, "w").write(bat_str)
45
print "ERROR: Unable to create %s: %s" % (bat_path, e)
120
scripts_dir = os.path.join(sys.prefix, 'Scripts')
121
script_path = self._quoted_path(os.path.join(scripts_dir,
123
python_exe = self._quoted_path(sys.executable)
124
args = self._win_batch_args()
125
batch_str = "@%s %s %s" % (python_exe, script_path, args)
126
batch_path = os.path.join(self.install_dir, "bzr.bat")
127
f = file(batch_path, "w")
130
print("Created: %s" % batch_path)
132
e = sys.exc_info()[1]
133
print("ERROR: Unable to create %s: %s" % (batch_path, e))
135
def _quoted_path(self, path):
137
return '"' + path + '"'
141
def _win_batch_args(self):
142
from bzrlib.win32utils import winver
143
if winver == 'Windows NT':
146
return '%1 %2 %3 %4 %5 %6 %7 %8 %9'
147
#/class my_install_scripts
150
class bzr_build(build):
151
"""Customized build distutils action.
158
from tools import generate_docs
159
generate_docs.main(argv=["bzr", "man"])
49
162
########################
51
164
########################
56
author_email='mbp@sourcefrog.net',
57
url='http://www.bazaar-ng.org/',
58
description='Friendly distributed version control system',
64
'bzrlib.util.elementtree',
65
'bzrlib.util.effbot.org',
166
command_classes = {'install_scripts': my_install_scripts,
168
from distutils import log
169
from distutils.errors import CCompilerError, DistutilsPlatformError
170
from distutils.extension import Extension
174
from Pyrex.Distutils import build_ext
175
from Pyrex.Compiler.Version import version as pyrex_version
177
print("No Pyrex, trying Cython...")
178
from Cython.Distutils import build_ext
179
from Cython.Compiler.Version import version as pyrex_version
182
# try to build the extension from the prior generated source.
184
print("The python package 'Pyrex' is not available."
185
" If the .c files are available,")
186
print("they will be built,"
187
" but modifying the .pyx files will not rebuild them.")
189
from distutils.command.build_ext import build_ext
192
pyrex_version_info = tuple(map(int, pyrex_version.split('.')))
195
class build_ext_if_possible(build_ext):
197
user_options = build_ext.user_options + [
198
('allow-python-fallback', None,
199
"When an extension cannot be built, allow falling"
200
" back to the pure-python implementation.")
203
def initialize_options(self):
204
build_ext.initialize_options(self)
205
self.allow_python_fallback = False
210
except DistutilsPlatformError:
211
e = sys.exc_info()[1]
212
if not self.allow_python_fallback:
213
log.warn('\n Cannot build extensions.\n'
214
' Use "build_ext --allow-python-fallback" to use'
215
' slower python implementations instead.\n')
218
log.warn('\n Extensions cannot be built.\n'
219
' Using the slower Python implementations instead.\n')
221
def build_extension(self, ext):
223
build_ext.build_extension(self, ext)
224
except CCompilerError:
225
if not self.allow_python_fallback:
226
log.warn('\n Cannot build extension "%s".\n'
227
' Use "build_ext --allow-python-fallback" to use'
228
' slower python implementations instead.\n'
231
log.warn('\n Building of "%s" extension failed.\n'
232
' Using the slower Python implementation instead.'
236
# Override the build_ext if we have Pyrex available
237
command_classes['build_ext'] = build_ext_if_possible
238
unavailable_files = []
241
def add_pyrex_extension(module_name, libraries=None, extra_source=[]):
242
"""Add a pyrex module to build.
244
This will use Pyrex to auto-generate the .c file if it is available.
245
Otherwise it will fall back on the .c file. If the .c file is not
246
available, it will warn, and not add anything.
248
You can pass any extra options to Extension through kwargs. One example is
251
:param module_name: The python path to the module. This will be used to
252
determine the .pyx and .c files to use.
254
path = module_name.replace('.', '/')
255
pyrex_name = path + '.pyx'
258
if sys.platform == 'win32':
259
# pyrex uses the macro WIN32 to detect the platform, even though it
260
# should be using something like _WIN32 or MS_WINDOWS, oh well, we can
261
# give it the right value.
262
define_macros.append(('WIN32', None))
264
source = [pyrex_name]
266
if not os.path.isfile(c_name):
267
unavailable_files.append(c_name)
271
source.extend(extra_source)
272
ext_modules.append(Extension(module_name, source,
273
define_macros=define_macros, libraries=libraries))
276
add_pyrex_extension('bzrlib._annotator_pyx')
277
add_pyrex_extension('bzrlib._bencode_pyx')
278
add_pyrex_extension('bzrlib._chunks_to_lines_pyx')
279
add_pyrex_extension('bzrlib._groupcompress_pyx',
280
extra_source=['bzrlib/diff-delta.c'])
281
add_pyrex_extension('bzrlib._knit_load_data_pyx')
282
add_pyrex_extension('bzrlib._known_graph_pyx')
283
add_pyrex_extension('bzrlib._rio_pyx')
284
if sys.platform == 'win32':
285
add_pyrex_extension('bzrlib._dirstate_helpers_pyx',
286
libraries=['Ws2_32'])
287
add_pyrex_extension('bzrlib._walkdirs_win32')
289
if have_pyrex and pyrex_version_info[:3] == (0,9,4):
290
# Pyrex 0.9.4.1 fails to compile this extension correctly
291
# The code it generates re-uses a "local" pointer and
292
# calls "PY_DECREF" after having set it to NULL. (It mixes PY_XDECREF
293
# which is NULL safe with PY_DECREF which is not.)
294
# <https://bugs.launchpad.net/bzr/+bug/449372>
295
# <https://bugs.launchpad.net/bzr/+bug/276868>
296
print('Cannot build extension "bzrlib._dirstate_helpers_pyx" using')
297
print('your version of pyrex "%s". Please upgrade your pyrex'
299
print('install. For now, the non-compiled (python) version will')
300
print('be used instead.')
302
add_pyrex_extension('bzrlib._dirstate_helpers_pyx')
303
add_pyrex_extension('bzrlib._readdir_pyx')
304
add_pyrex_extension('bzrlib._chk_map_pyx')
305
ext_modules.append(Extension('bzrlib._patiencediff_c',
306
['bzrlib/_patiencediff_c.c']))
307
if have_pyrex and pyrex_version_info < (0, 9, 6, 3):
309
print('Your Pyrex/Cython version %s is too old to build the simple_set' % (
311
print('and static_tuple extensions.')
312
print('Please upgrade to at least Pyrex 0.9.6.3')
314
# TODO: Should this be a fatal error?
316
# We only need 0.9.6.3 to build _simple_set_pyx, but static_tuple depends
318
add_pyrex_extension('bzrlib._simple_set_pyx')
319
ext_modules.append(Extension('bzrlib._static_tuple_c',
320
['bzrlib/_static_tuple_c.c']))
321
add_pyrex_extension('bzrlib._btree_serializer_pyx')
324
if unavailable_files:
325
print('C extension(s) not found:')
326
print(' %s' % ('\n '.join(unavailable_files),))
327
print('The python versions will be used instead.')
331
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
332
gui_targets, data_files):
333
packages.append('tbzrcommands')
335
# ModuleFinder can't handle runtime changes to __path__, but
336
# win32com uses them. Hook this in so win32com.shell is found.
339
import cPickle as pickle
340
for p in win32com.__path__[1:]:
341
modulefinder.AddPackagePath("win32com", p)
342
for extra in ["win32com.shell"]:
344
m = sys.modules[extra]
345
for p in m.__path__[1:]:
346
modulefinder.AddPackagePath(extra, p)
348
# TBZR points to the TBZR directory
349
tbzr_root = os.environ["TBZR"]
351
# Ensure tbzrlib itself is on sys.path
352
sys.path.append(tbzr_root)
354
packages.append("tbzrlib")
356
# collect up our icons.
358
ico_root = os.path.join(tbzr_root, 'tbzrlib', 'resources')
359
icos = [] # list of (path_root, relative_ico_path)
360
# First always bzr's icon and its in the root of the bzr tree.
361
icos.append(('', 'bzr.ico'))
362
for root, dirs, files in os.walk(ico_root):
363
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root)+1:])
364
for f in files if f.endswith('.ico')])
365
# allocate an icon ID for each file and the full path to the ico
366
icon_resources = [(rid, os.path.join(ico_dir, ico_name))
367
for rid, (ico_dir, ico_name) in enumerate(icos)]
368
# create a string resource with the mapping. Might as well save the
369
# runtime some effort and write a pickle.
370
# Runtime expects unicode objects with forward-slash seps.
371
fse = sys.getfilesystemencoding()
372
map_items = [(f.replace('\\', '/').decode(fse), rid)
373
for rid, (_, f) in enumerate(icos)]
374
ico_map = dict(map_items)
375
# Create a new resource type of 'ICON_MAP', and use ID=1
376
other_resources = [ ("ICON_MAP", 1, pickle.dumps(ico_map))]
378
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
379
win32ui crawler.Crawler""".split())
381
# tbzrcache executables - a "console" version for debugging and a
382
# GUI version that is generally used.
384
script = os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
385
icon_resources = icon_resources,
386
other_resources = other_resources,
388
console_targets.append(tbzrcache)
390
# Make a windows version which is the same except for the base name.
391
tbzrcachew = tbzrcache.copy()
392
tbzrcachew["dest_base"]="tbzrcachew"
393
gui_targets.append(tbzrcachew)
395
# ditto for the tbzrcommand tool
397
script = os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
398
icon_resources = [(0,'bzr.ico')],
400
console_targets.append(tbzrcommand)
401
tbzrcommandw = tbzrcommand.copy()
402
tbzrcommandw["dest_base"]="tbzrcommandw"
403
gui_targets.append(tbzrcommandw)
405
# A utility to see python output from both C++ and Python based shell
407
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
408
console_targets.append(tracer)
410
# The C++ implemented shell extensions.
411
dist_dir = os.path.join(tbzr_root, "shellext", "build")
412
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x86.dll')]))
413
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x64.dll')]))
416
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
417
# PyQt4 itself still escapes the plugin detection code for some reason...
418
includes.append('PyQt4.QtCore')
419
includes.append('PyQt4.QtGui')
420
includes.append('sip') # extension module required for Qt.
421
packages.append('pygments') # colorizer for qbzr
422
packages.append('docutils') # html formatting
423
includes.append('win32event') # for qsubprocess stuff
424
# the qt binaries might not be on PATH...
425
# They seem to install to a place like C:\Python25\PyQt4\*
426
# Which is not the same as C:\Python25\Lib\site-packages\PyQt4
427
pyqt_dir = os.path.join(sys.prefix, "PyQt4")
428
pyqt_bin_dir = os.path.join(pyqt_dir, "bin")
429
if os.path.isdir(pyqt_bin_dir):
430
path = os.environ.get("PATH", "")
431
if pyqt_bin_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
432
os.environ["PATH"] = path + os.pathsep + pyqt_bin_dir
433
# also add all imageformat plugins to distribution
434
# We will look in 2 places, dirname(PyQt4.__file__) and pyqt_dir
435
base_dirs_to_check = []
436
if os.path.isdir(pyqt_dir):
437
base_dirs_to_check.append(pyqt_dir)
443
pyqt4_base_dir = os.path.dirname(PyQt4.__file__)
444
if pyqt4_base_dir != pyqt_dir:
445
base_dirs_to_check.append(pyqt4_base_dir)
446
if not base_dirs_to_check:
447
log.warn("Can't find PyQt4 installation -> not including imageformat"
451
for base_dir in base_dirs_to_check:
452
plug_dir = os.path.join(base_dir, 'plugins', 'imageformats')
453
if os.path.isdir(plug_dir):
454
for fname in os.listdir(plug_dir):
455
# Include plugin dlls, but not debugging dlls
456
fullpath = os.path.join(plug_dir, fname)
457
if fname.endswith('.dll') and not fname.endswith('d4.dll'):
458
files.append(fullpath)
460
data_files.append(('imageformats', files))
462
log.warn('PyQt4 was found, but we could not find any imageformat'
463
' plugins. Are you sure your configuration is correct?')
466
def get_svn_py2exe_info(includes, excludes, packages):
467
packages.append('subvertpy')
468
packages.append('sqlite3')
471
if 'bdist_wininst' in sys.argv:
474
for root, dirs, files in os.walk('doc'):
477
if (os.path.splitext(f)[1] in ('.html','.css','.png','.pdf')
478
or f == 'quick-start-summary.svg'):
479
r.append(os.path.join(root, f))
483
target = os.path.join('Doc\\Bazaar', relative)
485
target = 'Doc\\Bazaar'
486
docs.append((target, r))
489
# python's distutils-based win32 installer
490
ARGS = {'scripts': ['bzr', 'tools/win32/bzr-win32-bdist-postinstall.py'],
491
'ext_modules': ext_modules,
493
'data_files': find_docs(),
494
# for building pyrex extensions
495
'cmdclass': {'build_ext': build_ext_if_possible},
498
ARGS.update(META_INFO)
500
ARGS.update(PKG_DATA)
504
elif 'py2exe' in sys.argv:
509
# pick real bzr version
513
for i in bzrlib.version_info[:4]:
518
version_number.append(str(i))
519
version_str = '.'.join(version_number)
521
# An override to install_data used only by py2exe builds, which arranges
522
# to byte-compile any .py files in data_files (eg, our plugins)
523
# Necessary as we can't rely on the user having the relevant permissions
524
# to the "Program Files" directory to generate them on the fly.
525
class install_data_with_bytecompile(install_data):
527
from distutils.util import byte_compile
529
install_data.run(self)
531
py2exe = self.distribution.get_command_obj('py2exe', False)
532
# GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
533
# time before living with docstring stripping
535
compile_names = [f for f in self.outfiles if f.endswith('.py')]
536
# Round mtime to nearest even second so that installing on a FAT
537
# filesystem bytecode internal and script timestamps will match
538
for f in compile_names:
539
mtime = os.stat(f).st_mtime
540
remainder = mtime % 2
543
os.utime(f, (mtime, mtime))
544
byte_compile(compile_names,
546
force=self.force, prefix=self.install_dir,
547
dry_run=self.dry_run)
548
self.outfiles.extend([f + 'o' for f in compile_names])
549
# end of class install_data_with_bytecompile
551
target = py2exe.build_exe.Target(script = "bzr",
553
icon_resources = [(0,'bzr.ico')],
554
name = META_INFO['name'],
555
version = version_str,
556
description = META_INFO['description'],
557
author = META_INFO['author'],
558
copyright = "(c) Canonical Ltd, 2005-2010",
559
company_name = "Canonical Ltd.",
560
comments = META_INFO['description'],
562
gui_target = copy.copy(target)
563
gui_target.dest_base = "bzrw"
565
packages = BZRLIB['packages']
566
packages.remove('bzrlib')
567
packages = [i for i in packages if not i.startswith('bzrlib.plugins')]
569
for i in glob.glob('bzrlib\\*.py'):
570
module = i[:-3].replace('\\', '.')
571
if module.endswith('__init__'):
572
module = module[:-len('__init__')]
573
includes.append(module)
575
additional_packages = set()
576
if sys.version.startswith('2.4'):
577
# adding elementtree package
578
additional_packages.add('elementtree')
579
elif sys.version.startswith('2.6') or sys.version.startswith('2.5'):
580
additional_packages.add('xml.etree')
583
warnings.warn('Unknown Python version.\n'
584
'Please check setup.py script for compatibility.')
586
# Although we currently can't enforce it, we consider it an error for
587
# py2exe to report any files are "missing". Such modules we know aren't
588
# used should be listed here.
589
excludes = """Tkinter psyco ElementPath r_hmac
590
ImaginaryModule cElementTree elementtree.ElementTree
591
Crypto.PublicKey._fastmath
592
medusa medusa.filesys medusa.ftp_server
594
resource validate""".split()
597
# email package from std python library use lazy import,
598
# so we need to explicitly add all package
599
additional_packages.add('email')
600
# And it uses funky mappings to conver to 'Oldname' to 'newname'. As
601
# a result, packages like 'email.Parser' show as missing. Tell py2exe
604
for oldname in getattr(email, '_LOWERNAMES', []):
605
excludes.append("email." + oldname)
606
for oldname in getattr(email, '_MIMENAMES', []):
607
excludes.append("email.MIME" + oldname)
609
# text files for help topis
610
text_topics = glob.glob('bzrlib/help_topics/en/*.txt')
611
topics_files = [('lib/help_topics/en', text_topics)]
615
# XXX - should we consider having the concept of an 'official' build,
616
# which hard-codes the list of plugins, gets more upset if modules are
618
plugins = None # will be a set after plugin sniffing...
619
for root, dirs, files in os.walk('bzrlib/plugins'):
620
if root == 'bzrlib/plugins':
622
# We ship plugins as normal files on the file-system - however,
623
# the build process can cause *some* of these plugin files to end
624
# up in library.zip. Thus, we saw (eg) "plugins/svn/test" in
625
# library.zip, and then saw import errors related to that as the
626
# rest of the svn plugin wasn't. So we tell py2exe to leave the
627
# plugins out of the .zip file
628
excludes.extend(["bzrlib.plugins." + d for d in dirs])
631
# Throw away files we don't want packaged. Note that plugins may
632
# have data files with all sorts of extensions so we need to
633
# be conservative here about what we ditch.
634
ext = os.path.splitext(i)[1]
635
if ext.endswith('~') or ext in [".pyc", ".swp"]:
637
if i == '__init__.py' and root == 'bzrlib/plugins':
639
x.append(os.path.join(root, i))
641
target_dir = root[len('bzrlib/'):] # install to 'plugins/...'
642
plugins_files.append((target_dir, x))
643
# find modules for built-in plugins
644
import tools.package_mf
645
mf = tools.package_mf.CustomModuleFinder()
646
mf.run_package('bzrlib/plugins')
647
packs, mods = mf.get_result()
648
additional_packages.update(packs)
649
includes.extend(mods)
651
console_targets = [target,
652
'tools/win32/bzr_postinstall.py',
654
gui_targets = [gui_target]
655
data_files = topics_files + plugins_files
657
if 'qbzr' in plugins:
658
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
661
get_svn_py2exe_info(includes, excludes, packages)
663
if "TBZR" in os.environ:
664
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
665
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
666
# can be downloaded from (username=guest, blank password):
667
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays
668
# look for: version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
669
# Ditto for TORTOISE_OVERLAYS_MSI_X64, pointing at *-x64.msi.
670
for needed in ('TORTOISE_OVERLAYS_MSI_WIN32',
671
'TORTOISE_OVERLAYS_MSI_X64'):
672
url = ('http://guest:@tortoisesvn.tigris.org/svn/tortoisesvn'
674
if not os.path.isfile(os.environ.get(needed, '<nofile>')):
676
"\nPlease set %s to the location of the relevant"
677
"\nTortoiseOverlays .msi installer file."
678
" The installers can be found at"
680
"\ncheck in the version-X.Y.Z/bin/ subdir" % (needed, url))
681
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
682
gui_targets, data_files)
684
# print this warning to stderr as output is redirected, so it is seen
685
# at build time. Also to stdout so it appears in the log
686
for f in (sys.stderr, sys.stdout):
687
f.write("Skipping TBZR binaries - "
688
"please set TBZR to a directory to enable\n")
690
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
692
dll_excludes.extend(["MSWSOCK.dll",
697
options_list = {"py2exe": {"packages": packages + list(additional_packages),
698
"includes": includes,
699
"excludes": excludes,
700
"dll_excludes": dll_excludes,
701
"dist_dir": "win32_bzr.exe",
703
"custom_boot_script":
704
"tools/win32/py2exe_boot_common.py",
708
# We want the libaray.zip to have optimize = 2, but the exe to have
709
# optimize = 1, so that .py files that get compilied at run time
710
# (e.g. user installed plugins) dont have their doc strings removed.
711
class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
712
def build_executable(self, *args, **kwargs):
714
py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
717
if __name__ == '__main__':
718
setup(options=options_list,
719
console=console_targets,
721
zipfile='lib/library.zip',
722
data_files=data_files,
723
cmdclass={'install_data': install_data_with_bytecompile,
724
'py2exe': py2exe_no_oo_exe},
728
# ad-hoc for easy_install
730
if not 'bdist_egg' in sys.argv:
731
# generate and install bzr.1 only with plain install, not the
733
DATA_FILES = [('man/man1', ['bzr.1'])]
736
ARGS = {'scripts': ['bzr'],
737
'data_files': DATA_FILES,
738
'cmdclass': command_classes,
739
'ext_modules': ext_modules,
742
ARGS.update(META_INFO)
744
ARGS.update(PKG_DATA)
746
if __name__ == '__main__':