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
15
if sys.version_info < (2, 6):
16
sys.stderr.write("[ERROR] Not a supported Python version. Need 2.6+\n")
19
# NOTE: The directory containing setup.py, whether run by 'python setup.py' or
20
# './setup.py' or the equivalent with another path, should always be at the
21
# start of the path, so this should find the right one...
24
def get_long_description():
25
dirname = os.path.dirname(__file__)
26
readme = os.path.join(dirname, 'README')
27
f = open(readme, 'rb')
35
# META INFORMATION FOR SETUP
36
# see http://docs.python.org/dist/meta-data.html
39
'version': bzrlib.__version__,
40
'author': 'Canonical Ltd',
41
'author_email': 'bazaar@lists.canonical.com',
42
'url': 'http://bazaar.canonical.com/',
43
'description': 'Friendly distributed version control system',
44
'license': 'GNU GPL v2',
45
'download_url': 'https://launchpad.net/bzr/+download',
46
'long_description': get_long_description(),
48
'Development Status :: 6 - Mature',
49
'Environment :: Console',
50
'Intended Audience :: Developers',
51
'Intended Audience :: System Administrators',
52
'License :: OSI Approved :: GNU General Public License (GPL)',
53
'Operating System :: Microsoft :: Windows',
54
'Operating System :: OS Independent',
55
'Operating System :: POSIX',
56
'Programming Language :: Python',
57
'Programming Language :: C',
58
'Topic :: Software Development :: Version Control',
62
# The list of packages is automatically generated later. Add other things
63
# that are part of BZRLIB here.
66
PKG_DATA = {# install files from selftest suite
67
'package_data': {'bzrlib': ['doc/api/*.txt',
68
'tests/test_patches_data/*',
69
'help_topics/en/*.txt',
70
'tests/ssl_certs/ca.crt',
71
'tests/ssl_certs/server_without_pass.key',
72
'tests/ssl_certs/server_with_pass.key',
73
'tests/ssl_certs/server.crt',
77
for filepath in glob.glob("bzrlib/locale/*/LC_MESSAGES/*.mo"):
78
langfile = filepath[len("bzrlib/locale/"):]
79
targetpath = os.path.dirname(os.path.join("share/locale", langfile))
80
I18N_FILES.append((targetpath, [filepath]))
82
def get_bzrlib_packages():
83
"""Recurse through the bzrlib directory, and extract the package names"""
86
base_path = os.path.dirname(os.path.abspath(bzrlib.__file__))
87
for root, dirs, files in os.walk(base_path):
88
if '__init__.py' in files:
89
assert root.startswith(base_path)
90
# Get just the path below bzrlib
91
package_path = root[len(base_path):]
92
# Remove leading and trailing slashes
93
package_path = package_path.strip('\\/')
95
package_name = 'bzrlib'
97
package_name = ('bzrlib.' +
98
package_path.replace('/', '.').replace('\\', '.'))
99
packages.append(package_name)
100
return sorted(packages)
103
BZRLIB['packages'] = get_bzrlib_packages()
106
from distutils import log
7
107
from distutils.core import setup
12
author_email='mbp@sourcefrog.net',
13
url='http://www.bazaar-ng.org/',
14
description='Friendly distributed version control system',
108
from distutils.command.install_scripts import install_scripts
109
from distutils.command.install_data import install_data
110
from distutils.command.build import build
112
###############################
113
# Overridden distutils actions
114
###############################
116
class my_install_scripts(install_scripts):
117
""" Customized install_scripts distutils action.
118
Create bzr.bat for win32.
121
install_scripts.run(self) # standard action
123
if sys.platform == "win32":
125
scripts_dir = os.path.join(sys.prefix, 'Scripts')
126
script_path = self._quoted_path(os.path.join(scripts_dir,
128
python_exe = self._quoted_path(sys.executable)
129
args = self._win_batch_args()
130
batch_str = "@%s %s %s" % (python_exe, script_path, args)
131
batch_path = os.path.join(self.install_dir, "bzr.bat")
132
f = file(batch_path, "w")
135
print("Created: %s" % batch_path)
137
e = sys.exc_info()[1]
138
print("ERROR: Unable to create %s: %s" % (batch_path, e))
140
def _quoted_path(self, path):
142
return '"' + path + '"'
146
def _win_batch_args(self):
147
from bzrlib.win32utils import winver
148
if winver == 'Windows NT':
151
return '%1 %2 %3 %4 %5 %6 %7 %8 %9'
152
#/class my_install_scripts
155
class bzr_build(build):
156
"""Customized build distutils action.
160
sub_commands = build.sub_commands + [
161
('build_mo', lambda _: True),
167
from tools import generate_docs
168
generate_docs.main(argv=["bzr", "man"])
171
########################
173
########################
175
from bzrlib.bzr_distutils import build_mo
177
command_classes = {'install_scripts': my_install_scripts,
179
'build_mo': build_mo,
181
from distutils import log
182
from distutils.errors import CCompilerError, DistutilsPlatformError
183
from distutils.extension import Extension
187
from Cython.Distutils import build_ext
188
from Cython.Compiler.Version import version as pyrex_version
190
print("No Cython, trying Pyrex...")
191
from Pyrex.Distutils import build_ext
192
from Pyrex.Compiler.Version import version as pyrex_version
195
# try to build the extension from the prior generated source.
197
print("The python package 'Pyrex' is not available."
198
" If the .c files are available,")
199
print("they will be built,"
200
" but modifying the .pyx files will not rebuild them.")
202
from distutils.command.build_ext import build_ext
205
pyrex_version_info = tuple(map(int, pyrex_version.rstrip("+").split('.')))
208
class build_ext_if_possible(build_ext):
210
user_options = build_ext.user_options + [
211
('allow-python-fallback', None,
212
"When an extension cannot be built, allow falling"
213
" back to the pure-python implementation.")
216
def initialize_options(self):
217
build_ext.initialize_options(self)
218
self.allow_python_fallback = False
223
except DistutilsPlatformError:
224
e = sys.exc_info()[1]
225
if not self.allow_python_fallback:
226
log.warn('\n Cannot build extensions.\n'
227
' Use "build_ext --allow-python-fallback" to use'
228
' slower python implementations instead.\n')
231
log.warn('\n Extensions cannot be built.\n'
232
' Using the slower Python implementations instead.\n')
234
def build_extension(self, ext):
236
build_ext.build_extension(self, ext)
237
except CCompilerError:
238
if not self.allow_python_fallback:
239
log.warn('\n Cannot build extension "%s".\n'
240
' Use "build_ext --allow-python-fallback" to use'
241
' slower python implementations instead.\n'
244
log.warn('\n Building of "%s" extension failed.\n'
245
' Using the slower Python implementation instead.'
249
# Override the build_ext if we have Pyrex available
250
command_classes['build_ext'] = build_ext_if_possible
251
unavailable_files = []
254
def add_pyrex_extension(module_name, libraries=None, extra_source=[]):
255
"""Add a pyrex module to build.
257
This will use Pyrex to auto-generate the .c file if it is available.
258
Otherwise it will fall back on the .c file. If the .c file is not
259
available, it will warn, and not add anything.
261
You can pass any extra options to Extension through kwargs. One example is
264
:param module_name: The python path to the module. This will be used to
265
determine the .pyx and .c files to use.
267
path = module_name.replace('.', '/')
268
pyrex_name = path + '.pyx'
271
if sys.platform == 'win32':
272
# pyrex uses the macro WIN32 to detect the platform, even though it
273
# should be using something like _WIN32 or MS_WINDOWS, oh well, we can
274
# give it the right value.
275
define_macros.append(('WIN32', None))
277
source = [pyrex_name]
279
if not os.path.isfile(c_name):
280
unavailable_files.append(c_name)
284
source.extend(extra_source)
285
ext_modules.append(Extension(module_name, source,
286
define_macros=define_macros, libraries=libraries))
289
add_pyrex_extension('bzrlib._annotator_pyx')
290
add_pyrex_extension('bzrlib._bencode_pyx')
291
add_pyrex_extension('bzrlib._chunks_to_lines_pyx')
292
add_pyrex_extension('bzrlib._groupcompress_pyx',
293
extra_source=['bzrlib/diff-delta.c'])
294
add_pyrex_extension('bzrlib._knit_load_data_pyx')
295
add_pyrex_extension('bzrlib._known_graph_pyx')
296
add_pyrex_extension('bzrlib._rio_pyx')
297
if sys.platform == 'win32':
298
add_pyrex_extension('bzrlib._dirstate_helpers_pyx',
299
libraries=['Ws2_32'])
300
add_pyrex_extension('bzrlib._walkdirs_win32')
302
if have_pyrex and pyrex_version_info[:3] == (0,9,4):
303
# Pyrex 0.9.4.1 fails to compile this extension correctly
304
# The code it generates re-uses a "local" pointer and
305
# calls "PY_DECREF" after having set it to NULL. (It mixes PY_XDECREF
306
# which is NULL safe with PY_DECREF which is not.)
307
# <https://bugs.launchpad.net/bzr/+bug/449372>
308
# <https://bugs.launchpad.net/bzr/+bug/276868>
309
print('Cannot build extension "bzrlib._dirstate_helpers_pyx" using')
310
print('your version of pyrex "%s". Please upgrade your pyrex'
312
print('install. For now, the non-compiled (python) version will')
313
print('be used instead.')
315
add_pyrex_extension('bzrlib._dirstate_helpers_pyx')
316
add_pyrex_extension('bzrlib._readdir_pyx')
317
add_pyrex_extension('bzrlib._chk_map_pyx')
318
ext_modules.append(Extension('bzrlib._patiencediff_c',
319
['bzrlib/_patiencediff_c.c']))
320
if have_pyrex and pyrex_version_info < (0, 9, 6, 3):
322
print('Your Pyrex/Cython version %s is too old to build the simple_set' % (
324
print('and static_tuple extensions.')
325
print('Please upgrade to at least Pyrex 0.9.6.3')
327
# TODO: Should this be a fatal error?
329
# We only need 0.9.6.3 to build _simple_set_pyx, but static_tuple depends
331
add_pyrex_extension('bzrlib._simple_set_pyx')
332
ext_modules.append(Extension('bzrlib._static_tuple_c',
333
['bzrlib/_static_tuple_c.c']))
334
add_pyrex_extension('bzrlib._btree_serializer_pyx')
337
if unavailable_files:
338
print('C extension(s) not found:')
339
print(' %s' % ('\n '.join(unavailable_files),))
340
print('The python versions will be used instead.')
344
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
345
gui_targets, data_files):
346
packages.append('tbzrcommands')
348
# ModuleFinder can't handle runtime changes to __path__, but
349
# win32com uses them. Hook this in so win32com.shell is found.
352
import cPickle as pickle
353
for p in win32com.__path__[1:]:
354
modulefinder.AddPackagePath("win32com", p)
355
for extra in ["win32com.shell"]:
357
m = sys.modules[extra]
358
for p in m.__path__[1:]:
359
modulefinder.AddPackagePath(extra, p)
361
# TBZR points to the TBZR directory
362
tbzr_root = os.environ["TBZR"]
364
# Ensure tbzrlib itself is on sys.path
365
sys.path.append(tbzr_root)
367
packages.append("tbzrlib")
369
# collect up our icons.
371
ico_root = os.path.join(tbzr_root, 'tbzrlib', 'resources')
372
icos = [] # list of (path_root, relative_ico_path)
373
# First always bzr's icon and its in the root of the bzr tree.
374
icos.append(('', 'bzr.ico'))
375
for root, dirs, files in os.walk(ico_root):
376
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root)+1:])
377
for f in files if f.endswith('.ico')])
378
# allocate an icon ID for each file and the full path to the ico
379
icon_resources = [(rid, os.path.join(ico_dir, ico_name))
380
for rid, (ico_dir, ico_name) in enumerate(icos)]
381
# create a string resource with the mapping. Might as well save the
382
# runtime some effort and write a pickle.
383
# Runtime expects unicode objects with forward-slash seps.
384
fse = sys.getfilesystemencoding()
385
map_items = [(f.replace('\\', '/').decode(fse), rid)
386
for rid, (_, f) in enumerate(icos)]
387
ico_map = dict(map_items)
388
# Create a new resource type of 'ICON_MAP', and use ID=1
389
other_resources = [ ("ICON_MAP", 1, pickle.dumps(ico_map))]
391
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
392
win32ui crawler.Crawler""".split())
394
# tbzrcache executables - a "console" version for debugging and a
395
# GUI version that is generally used.
397
script = os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
398
icon_resources = icon_resources,
399
other_resources = other_resources,
401
console_targets.append(tbzrcache)
403
# Make a windows version which is the same except for the base name.
404
tbzrcachew = tbzrcache.copy()
405
tbzrcachew["dest_base"]="tbzrcachew"
406
gui_targets.append(tbzrcachew)
408
# ditto for the tbzrcommand tool
410
script = os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
411
icon_resources = icon_resources,
412
other_resources = other_resources,
414
console_targets.append(tbzrcommand)
415
tbzrcommandw = tbzrcommand.copy()
416
tbzrcommandw["dest_base"]="tbzrcommandw"
417
gui_targets.append(tbzrcommandw)
419
# A utility to see python output from both C++ and Python based shell
421
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
422
console_targets.append(tracer)
424
# The C++ implemented shell extensions.
425
dist_dir = os.path.join(tbzr_root, "shellext", "build")
426
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x86.dll')]))
427
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x64.dll')]))
430
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
431
# PyQt4 itself still escapes the plugin detection code for some reason...
432
includes.append('PyQt4.QtCore')
433
includes.append('PyQt4.QtGui')
434
includes.append('sip') # extension module required for Qt.
435
packages.append('pygments') # colorizer for qbzr
436
packages.append('docutils') # html formatting
437
includes.append('win32event') # for qsubprocess stuff
438
# the qt binaries might not be on PATH...
439
# They seem to install to a place like C:\Python25\PyQt4\*
440
# Which is not the same as C:\Python25\Lib\site-packages\PyQt4
441
pyqt_dir = os.path.join(sys.prefix, "PyQt4")
442
pyqt_bin_dir = os.path.join(pyqt_dir, "bin")
443
if os.path.isdir(pyqt_bin_dir):
444
path = os.environ.get("PATH", "")
445
if pyqt_bin_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
446
os.environ["PATH"] = path + os.pathsep + pyqt_bin_dir
447
# also add all imageformat plugins to distribution
448
# We will look in 2 places, dirname(PyQt4.__file__) and pyqt_dir
449
base_dirs_to_check = []
450
if os.path.isdir(pyqt_dir):
451
base_dirs_to_check.append(pyqt_dir)
457
pyqt4_base_dir = os.path.dirname(PyQt4.__file__)
458
if pyqt4_base_dir != pyqt_dir:
459
base_dirs_to_check.append(pyqt4_base_dir)
460
if not base_dirs_to_check:
461
log.warn("Can't find PyQt4 installation -> not including imageformat"
465
for base_dir in base_dirs_to_check:
466
plug_dir = os.path.join(base_dir, 'plugins', 'imageformats')
467
if os.path.isdir(plug_dir):
468
for fname in os.listdir(plug_dir):
469
# Include plugin dlls, but not debugging dlls
470
fullpath = os.path.join(plug_dir, fname)
471
if fname.endswith('.dll') and not fname.endswith('d4.dll'):
472
files.append(fullpath)
474
data_files.append(('imageformats', files))
476
log.warn('PyQt4 was found, but we could not find any imageformat'
477
' plugins. Are you sure your configuration is correct?')
480
def get_svn_py2exe_info(includes, excludes, packages):
481
packages.append('subvertpy')
482
packages.append('sqlite3')
485
def get_git_py2exe_info(includes, excludes, packages):
486
packages.append('dulwich')
489
def get_fastimport_py2exe_info(includes, excludes, packages):
490
# This is the python-fastimport package, not to be confused with the
491
# bzr-fastimport plugin.
492
packages.append('fastimport')
495
if 'bdist_wininst' in sys.argv:
498
for root, dirs, files in os.walk('doc'):
501
if (os.path.splitext(f)[1] in ('.html','.css','.png','.pdf')
502
or f == 'quick-start-summary.svg'):
503
r.append(os.path.join(root, f))
507
target = os.path.join('Doc\\Bazaar', relative)
509
target = 'Doc\\Bazaar'
510
docs.append((target, r))
513
# python's distutils-based win32 installer
514
ARGS = {'scripts': ['bzr', 'tools/win32/bzr-win32-bdist-postinstall.py'],
515
'ext_modules': ext_modules,
517
'data_files': find_docs(),
518
# for building pyrex extensions
519
'cmdclass': command_classes,
522
ARGS.update(META_INFO)
524
PKG_DATA['package_data']['bzrlib'].append('locale/*/LC_MESSAGES/*.mo')
525
ARGS.update(PKG_DATA)
529
elif 'py2exe' in sys.argv:
533
# pick real bzr version
537
for i in bzrlib.version_info[:4]:
542
version_number.append(str(i))
543
version_str = '.'.join(version_number)
545
# An override to install_data used only by py2exe builds, which arranges
546
# to byte-compile any .py files in data_files (eg, our plugins)
547
# Necessary as we can't rely on the user having the relevant permissions
548
# to the "Program Files" directory to generate them on the fly.
549
class install_data_with_bytecompile(install_data):
551
from distutils.util import byte_compile
553
install_data.run(self)
555
py2exe = self.distribution.get_command_obj('py2exe', False)
556
# GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
557
# time before living with docstring stripping
559
compile_names = [f for f in self.outfiles if f.endswith('.py')]
560
# Round mtime to nearest even second so that installing on a FAT
561
# filesystem bytecode internal and script timestamps will match
562
for f in compile_names:
563
mtime = os.stat(f).st_mtime
564
remainder = mtime % 2
567
os.utime(f, (mtime, mtime))
568
byte_compile(compile_names,
570
force=self.force, prefix=self.install_dir,
571
dry_run=self.dry_run)
572
self.outfiles.extend([f + 'o' for f in compile_names])
573
# end of class install_data_with_bytecompile
575
target = py2exe.build_exe.Target(script = "bzr",
577
icon_resources = [(0,'bzr.ico')],
578
name = META_INFO['name'],
579
version = version_str,
580
description = META_INFO['description'],
581
author = META_INFO['author'],
582
copyright = "(c) Canonical Ltd, 2005-2010",
583
company_name = "Canonical Ltd.",
584
comments = META_INFO['description'],
586
gui_target = copy.copy(target)
587
gui_target.dest_base = "bzrw"
589
packages = BZRLIB['packages']
590
packages.remove('bzrlib')
591
packages = [i for i in packages if not i.startswith('bzrlib.plugins')]
593
for i in glob.glob('bzrlib\\*.py'):
594
module = i[:-3].replace('\\', '.')
595
if module.endswith('__init__'):
596
module = module[:-len('__init__')]
597
includes.append(module)
599
additional_packages = set()
600
if sys.version.startswith('2.4'):
601
# adding elementtree package
602
additional_packages.add('elementtree')
603
elif sys.version.startswith('2.6') or sys.version.startswith('2.5'):
604
additional_packages.add('xml.etree')
607
warnings.warn('Unknown Python version.\n'
608
'Please check setup.py script for compatibility.')
610
# Although we currently can't enforce it, we consider it an error for
611
# py2exe to report any files are "missing". Such modules we know aren't
612
# used should be listed here.
613
excludes = """Tkinter psyco ElementPath r_hmac
614
ImaginaryModule cElementTree elementtree.ElementTree
615
Crypto.PublicKey._fastmath
616
medusa medusa.filesys medusa.ftp_server
618
resource validate""".split()
621
# email package from std python library use lazy import,
622
# so we need to explicitly add all package
623
additional_packages.add('email')
624
# And it uses funky mappings to conver to 'Oldname' to 'newname'. As
625
# a result, packages like 'email.Parser' show as missing. Tell py2exe
628
for oldname in getattr(email, '_LOWERNAMES', []):
629
excludes.append("email." + oldname)
630
for oldname in getattr(email, '_MIMENAMES', []):
631
excludes.append("email.MIME" + oldname)
633
# text files for help topis
634
text_topics = glob.glob('bzrlib/help_topics/en/*.txt')
635
topics_files = [('lib/help_topics/en', text_topics)]
639
# XXX - should we consider having the concept of an 'official' build,
640
# which hard-codes the list of plugins, gets more upset if modules are
642
plugins = None # will be a set after plugin sniffing...
643
for root, dirs, files in os.walk('bzrlib/plugins'):
644
if root == 'bzrlib/plugins':
646
# We ship plugins as normal files on the file-system - however,
647
# the build process can cause *some* of these plugin files to end
648
# up in library.zip. Thus, we saw (eg) "plugins/svn/test" in
649
# library.zip, and then saw import errors related to that as the
650
# rest of the svn plugin wasn't. So we tell py2exe to leave the
651
# plugins out of the .zip file
652
excludes.extend(["bzrlib.plugins." + d for d in dirs])
655
# Throw away files we don't want packaged. Note that plugins may
656
# have data files with all sorts of extensions so we need to
657
# be conservative here about what we ditch.
658
ext = os.path.splitext(i)[1]
659
if ext.endswith('~') or ext in [".pyc", ".swp"]:
661
if i == '__init__.py' and root == 'bzrlib/plugins':
663
x.append(os.path.join(root, i))
665
target_dir = root[len('bzrlib/'):] # install to 'plugins/...'
666
plugins_files.append((target_dir, x))
667
# find modules for built-in plugins
668
import tools.package_mf
669
mf = tools.package_mf.CustomModuleFinder()
670
mf.run_package('bzrlib/plugins')
671
packs, mods = mf.get_result()
672
additional_packages.update(packs)
673
includes.extend(mods)
675
console_targets = [target,
676
'tools/win32/bzr_postinstall.py',
678
gui_targets = [gui_target]
679
data_files = topics_files + plugins_files + I18N_FILES
681
if 'qbzr' in plugins:
682
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
685
get_svn_py2exe_info(includes, excludes, packages)
688
get_git_py2exe_info(includes, excludes, packages)
690
if 'fastimport' in plugins:
691
get_fastimport_py2exe_info(includes, excludes, packages)
693
if "TBZR" in os.environ:
694
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
695
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
696
# can be downloaded from (username=guest, blank password):
697
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays
698
# look for: version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
699
# Ditto for TORTOISE_OVERLAYS_MSI_X64, pointing at *-x64.msi.
700
for needed in ('TORTOISE_OVERLAYS_MSI_WIN32',
701
'TORTOISE_OVERLAYS_MSI_X64'):
702
url = ('http://guest:@tortoisesvn.tigris.org/svn/tortoisesvn'
704
if not os.path.isfile(os.environ.get(needed, '<nofile>')):
706
"\nPlease set %s to the location of the relevant"
707
"\nTortoiseOverlays .msi installer file."
708
" The installers can be found at"
710
"\ncheck in the version-X.Y.Z/bin/ subdir" % (needed, url))
711
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
712
gui_targets, data_files)
714
# print this warning to stderr as output is redirected, so it is seen
715
# at build time. Also to stdout so it appears in the log
716
for f in (sys.stderr, sys.stdout):
717
f.write("Skipping TBZR binaries - "
718
"please set TBZR to a directory to enable\n")
720
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
722
dll_excludes.extend(["MSWSOCK.dll",
727
options_list = {"py2exe": {"packages": packages + list(additional_packages),
728
"includes": includes,
729
"excludes": excludes,
730
"dll_excludes": dll_excludes,
731
"dist_dir": "win32_bzr.exe",
733
"custom_boot_script":
734
"tools/win32/py2exe_boot_common.py",
738
# We want the libaray.zip to have optimize = 2, but the exe to have
739
# optimize = 1, so that .py files that get compilied at run time
740
# (e.g. user installed plugins) dont have their doc strings removed.
741
class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
742
def build_executable(self, *args, **kwargs):
744
py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
747
if __name__ == '__main__':
748
command_classes['install_data'] = install_data_with_bytecompile
749
command_classes['py2exe'] = py2exe_no_oo_exe
750
setup(options=options_list,
751
console=console_targets,
753
zipfile='lib/library.zip',
754
data_files=data_files,
755
cmdclass=command_classes,
759
# ad-hoc for easy_install
761
if not 'bdist_egg' in sys.argv:
762
# generate and install bzr.1 only with plain install, not the
764
DATA_FILES = [('man/man1', ['bzr.1'])]
766
DATA_FILES = DATA_FILES + I18N_FILES
768
ARGS = {'scripts': ['bzr'],
769
'data_files': DATA_FILES,
770
'cmdclass': command_classes,
771
'ext_modules': ext_modules,
774
ARGS.update(META_INFO)
776
ARGS.update(PKG_DATA)
778
if __name__ == '__main__':