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
7
# Reinvocation stolen from bzr, we need python2.4 by virtue of bzr_man
8
# including bzrlib.help
13
version_info = sys.version_info
14
except AttributeError:
15
version_info = 1, 5 # 1.5 or older
17
REINVOKE = "__BZR_REINVOKE"
19
KNOWN_PYTHONS = ('python2.4',)
21
if version_info < NEED_VERS:
22
if not os.environ.has_key(REINVOKE):
23
# mutating os.environ doesn't work in old Pythons
24
os.putenv(REINVOKE, "1")
25
for python in KNOWN_PYTHONS:
27
os.execvp(python, [python] + sys.argv)
30
print >>sys.stderr, "bzr: error: cannot find a suitable python interpreter"
31
print >>sys.stderr, " (need %d.%d or later)" % NEED_VERS
3
"""Installation script for brz.
5
'./setup.py install', or
6
'./setup.py --help' for more options
15
if sys.version_info < (2, 7):
16
sys.stderr.write("[ERROR] Not a supported Python version. Need 2.7+\n")
33
if hasattr(os, "unsetenv"):
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': breezy.__version__,
40
'author': 'Canonical Ltd',
41
'author_email': 'bazaar@lists.canonical.com',
42
'maintainer': 'Breezy Developers',
43
'url': 'https://www.breezy-vcs.org/',
44
'description': 'Friendly distributed version control system',
45
'license': 'GNU GPL v2',
46
'download_url': 'https://launchpad.net/brz/+download',
47
'long_description': get_long_description(),
49
'Development Status :: 6 - Mature',
50
'Environment :: Console',
51
'Intended Audience :: Developers',
52
'Intended Audience :: System Administrators',
53
'License :: OSI Approved :: GNU General Public License (GPL)',
54
'Operating System :: Microsoft :: Windows',
55
'Operating System :: OS Independent',
56
'Operating System :: POSIX',
57
'Programming Language :: Python',
58
'Programming Language :: C',
59
'Topic :: Software Development :: Version Control',
63
# The list of packages is automatically generated later. Add other things
64
# that are part of BZRLIB here.
67
PKG_DATA = {# install files from selftest suite
68
'package_data': {'breezy': ['doc/api/*.txt',
69
'tests/test_patches_data/*',
70
'help_topics/en/*.txt',
71
'tests/ssl_certs/ca.crt',
72
'tests/ssl_certs/server_without_pass.key',
73
'tests/ssl_certs/server_with_pass.key',
74
'tests/ssl_certs/server.crt',
78
for filepath in glob.glob("breezy/locale/*/LC_MESSAGES/*.mo"):
79
langfile = filepath[len("breezy/locale/"):]
80
targetpath = os.path.dirname(os.path.join("share/locale", langfile))
81
I18N_FILES.append((targetpath, [filepath]))
83
def get_breezy_packages():
84
"""Recurse through the breezy directory, and extract the package names"""
87
base_path = os.path.dirname(os.path.abspath(breezy.__file__))
88
for root, dirs, files in os.walk(base_path):
89
if '__init__.py' in files:
90
assert root.startswith(base_path)
91
# Get just the path below breezy
92
package_path = root[len(base_path):]
93
# Remove leading and trailing slashes
94
package_path = package_path.strip('\\/')
96
package_name = 'breezy'
98
package_name = ('breezy.' +
99
package_path.replace('/', '.').replace('\\', '.'))
100
packages.append(package_name)
101
return sorted(packages)
104
BZRLIB['packages'] = get_breezy_packages()
107
from distutils import log
37
108
from distutils.core import setup
109
from distutils.version import LooseVersion
38
110
from distutils.command.install_scripts import install_scripts
111
from distutils.command.install_data import install_data
39
112
from distutils.command.build import build
41
114
###############################
45
118
class my_install_scripts(install_scripts):
46
119
""" Customized install_scripts distutils action.
47
Create bzr.bat for win32.
120
Create brz.bat for win32.
53
123
install_scripts.run(self) # standard action
55
125
if sys.platform == "win32":
57
scripts_dir = self.install_dir
58
script_path = os.path.join(scripts_dir, "bzr")
59
batch_str = "@%s %s %%*\n" % (sys.executable, script_path)
60
batch_path = script_path + ".bat"
127
scripts_dir = os.path.join(sys.prefix, 'Scripts')
128
script_path = self._quoted_path(os.path.join(scripts_dir,
130
python_exe = self._quoted_path(sys.executable)
131
args = self._win_batch_args()
132
batch_str = "@%s %s %s" % (python_exe, script_path, args)
133
batch_path = os.path.join(self.install_dir, "brz.bat")
61
134
f = file(batch_path, "w")
62
135
f.write(batch_str)
64
print "Created:", batch_path
66
print "ERROR: Unable to create %s: %s" % (batch_path, e)
137
print(("Created: %s" % batch_path))
139
e = sys.exc_info()[1]
140
print(("ERROR: Unable to create %s: %s" % (batch_path, e)))
142
def _quoted_path(self, path):
144
return '"' + path + '"'
148
def _win_batch_args(self):
149
from breezy.win32utils import winver
150
if winver == 'Windows NT':
153
return '%1 %2 %3 %4 %5 %6 %7 %8 %9'
154
#/class my_install_scripts
69
157
class bzr_build(build):
70
158
"""Customized build distutils action.
162
sub_commands = build.sub_commands + [
163
('build_mo', lambda _: True),
77
generate_docs.main(argv=["bzr", "man"])
169
from tools import generate_docs
170
generate_docs.main(argv=["brz", "man"])
79
173
########################
81
175
########################
86
author_email='mbp@sourcefrog.net',
87
url='http://www.bazaar-ng.org/',
88
description='Friendly distributed version control system',
96
'bzrlib.store.revision',
97
'bzrlib.store.versioned',
99
'bzrlib.tests.blackbox',
100
'bzrlib.tests.branch_implementations',
101
'bzrlib.tests.bzrdir_implementations',
102
'bzrlib.tests.interrepository_implementations',
103
'bzrlib.tests.interversionedfile_implementations',
104
'bzrlib.tests.repository_implementations',
105
'bzrlib.tests.revisionstore_implementations',
106
'bzrlib.tests.workingtree_implementations',
108
'bzrlib.transport.http',
111
'bzrlib.util.elementtree',
112
'bzrlib.util.effbot.org',
113
'bzrlib.util.configobj',
116
cmdclass={'install_scripts': my_install_scripts, 'build': bzr_build},
117
data_files=[('man/man1', ['bzr.1'])],
118
# todo: install the txt files from bzrlib.doc.api.
177
from breezy.bzr_distutils import build_mo
179
command_classes = {'install_scripts': my_install_scripts,
181
'build_mo': build_mo,
183
from distutils import log
184
from distutils.errors import CCompilerError, DistutilsPlatformError
185
from distutils.extension import Extension
188
from Cython.Distutils import build_ext
189
from Cython.Compiler.Version import version as cython_version
192
# try to build the extension from the prior generated source.
194
print("The python package 'Cython' is not available."
195
" If the .c files are available,")
196
print("they will be built,"
197
" but modifying the .pyx files will not rebuild them.")
199
from distutils.command.build_ext import build_ext
202
cython_version_info = LooseVersion(cython_version)
205
class build_ext_if_possible(build_ext):
207
user_options = build_ext.user_options + [
208
('allow-python-fallback', None,
209
"When an extension cannot be built, allow falling"
210
" back to the pure-python implementation.")
213
def initialize_options(self):
214
build_ext.initialize_options(self)
215
self.allow_python_fallback = False
220
except DistutilsPlatformError:
221
e = sys.exc_info()[1]
222
if not self.allow_python_fallback:
223
log.warn('\n Cannot build extensions.\n'
224
' Use "build_ext --allow-python-fallback" to use'
225
' slower python implementations instead.\n')
228
log.warn('\n Extensions cannot be built.\n'
229
' Using the slower Python implementations instead.\n')
231
def build_extension(self, ext):
233
build_ext.build_extension(self, ext)
234
except CCompilerError:
235
if not self.allow_python_fallback:
236
log.warn('\n Cannot build extension "%s".\n'
237
' Use "build_ext --allow-python-fallback" to use'
238
' slower python implementations instead.\n'
241
log.warn('\n Building of "%s" extension failed.\n'
242
' Using the slower Python implementation instead.'
246
# Override the build_ext if we have Cython available
247
command_classes['build_ext'] = build_ext_if_possible
248
unavailable_files = []
251
def add_cython_extension(module_name, libraries=None, extra_source=[]):
252
"""Add a cython module to build.
254
This will use Cython to auto-generate the .c file if it is available.
255
Otherwise it will fall back on the .c file. If the .c file is not
256
available, it will warn, and not add anything.
258
You can pass any extra options to Extension through kwargs. One example is
261
:param module_name: The python path to the module. This will be used to
262
determine the .pyx and .c files to use.
264
path = module_name.replace('.', '/')
265
cython_name = path + '.pyx'
268
if sys.platform == 'win32':
269
# cython uses the macro WIN32 to detect the platform, even though it
270
# should be using something like _WIN32 or MS_WINDOWS, oh well, we can
271
# give it the right value.
272
define_macros.append(('WIN32', None))
274
source = [cython_name]
276
if not os.path.isfile(c_name):
277
unavailable_files.append(c_name)
281
source.extend(extra_source)
282
include_dirs = ['breezy']
283
ext_modules.append(Extension(module_name, source,
284
define_macros=define_macros, libraries=libraries,
285
include_dirs=include_dirs))
288
add_cython_extension('breezy._simple_set_pyx')
289
ext_modules.append(Extension('breezy._static_tuple_c',
290
['breezy/_static_tuple_c.c']))
291
add_cython_extension('breezy._annotator_pyx')
292
add_cython_extension('breezy._bencode_pyx')
293
add_cython_extension('breezy._chunks_to_lines_pyx')
294
add_cython_extension('breezy.bzr._groupcompress_pyx',
295
extra_source=['breezy/bzr/diff-delta.c'])
296
add_cython_extension('breezy.bzr._knit_load_data_pyx')
297
add_cython_extension('breezy._known_graph_pyx')
298
add_cython_extension('breezy._rio_pyx')
299
if sys.platform == 'win32':
300
add_cython_extension('breezy.bzr._dirstate_helpers_pyx',
301
libraries=['Ws2_32'])
302
add_cython_extension('breezy._walkdirs_win32')
304
add_cython_extension('breezy.bzr._dirstate_helpers_pyx')
305
add_cython_extension('breezy._readdir_pyx')
306
add_cython_extension('breezy.bzr._chk_map_pyx')
307
ext_modules.append(Extension('breezy._patiencediff_c',
308
['breezy/_patiencediff_c.c']))
309
add_cython_extension('breezy.bzr._btree_serializer_pyx')
312
if unavailable_files:
313
print('C extension(s) not found:')
314
print((' %s' % ('\n '.join(unavailable_files),)))
315
print('The python versions will be used instead.')
319
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
320
gui_targets, data_files):
321
packages.append('tbzrcommands')
323
# ModuleFinder can't handle runtime changes to __path__, but
324
# win32com uses them. Hook this in so win32com.shell is found.
327
import cPickle as pickle
328
for p in win32com.__path__[1:]:
329
modulefinder.AddPackagePath("win32com", p)
330
for extra in ["win32com.shell"]:
332
m = sys.modules[extra]
333
for p in m.__path__[1:]:
334
modulefinder.AddPackagePath(extra, p)
336
# TBZR points to the TBZR directory
337
tbzr_root = os.environ["TBZR"]
339
# Ensure tbreezy itself is on sys.path
340
sys.path.append(tbzr_root)
342
packages.append("tbreezy")
344
# collect up our icons.
346
ico_root = os.path.join(tbzr_root, 'tbreezy', 'resources')
347
icos = [] # list of (path_root, relative_ico_path)
348
# First always brz's icon and its in the root of the brz tree.
349
icos.append(('', 'brz.ico'))
350
for root, dirs, files in os.walk(ico_root):
351
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root)+1:])
352
for f in files if f.endswith('.ico')])
353
# allocate an icon ID for each file and the full path to the ico
354
icon_resources = [(rid, os.path.join(ico_dir, ico_name))
355
for rid, (ico_dir, ico_name) in enumerate(icos)]
356
# create a string resource with the mapping. Might as well save the
357
# runtime some effort and write a pickle.
358
# Runtime expects unicode objects with forward-slash seps.
359
fse = sys.getfilesystemencoding()
360
map_items = [(f.replace('\\', '/').decode(fse), rid)
361
for rid, (_, f) in enumerate(icos)]
362
ico_map = dict(map_items)
363
# Create a new resource type of 'ICON_MAP', and use ID=1
364
other_resources = [ ("ICON_MAP", 1, pickle.dumps(ico_map))]
366
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
367
win32ui crawler.Crawler""".split())
369
# tbzrcache executables - a "console" version for debugging and a
370
# GUI version that is generally used.
372
script = os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
373
icon_resources = icon_resources,
374
other_resources = other_resources,
376
console_targets.append(tbzrcache)
378
# Make a windows version which is the same except for the base name.
379
tbzrcachew = tbzrcache.copy()
380
tbzrcachew["dest_base"]="tbzrcachew"
381
gui_targets.append(tbzrcachew)
383
# ditto for the tbzrcommand tool
385
script = os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
386
icon_resources = icon_resources,
387
other_resources = other_resources,
389
console_targets.append(tbzrcommand)
390
tbzrcommandw = tbzrcommand.copy()
391
tbzrcommandw["dest_base"]="tbzrcommandw"
392
gui_targets.append(tbzrcommandw)
394
# A utility to see python output from both C++ and Python based shell
396
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
397
console_targets.append(tracer)
399
# The C++ implemented shell extensions.
400
dist_dir = os.path.join(tbzr_root, "shellext", "build")
401
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x86.dll')]))
402
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x64.dll')]))
405
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
406
# PyQt4 itself still escapes the plugin detection code for some reason...
407
includes.append('PyQt4.QtCore')
408
includes.append('PyQt4.QtGui')
409
includes.append('PyQt4.QtTest')
410
includes.append('sip') # extension module required for Qt.
411
packages.append('pygments') # colorizer for qbzr
412
packages.append('docutils') # html formatting
413
includes.append('win32event') # for qsubprocess stuff
414
# the qt binaries might not be on PATH...
415
# They seem to install to a place like C:\Python25\PyQt4\*
416
# Which is not the same as C:\Python25\Lib\site-packages\PyQt4
417
pyqt_dir = os.path.join(sys.prefix, "PyQt4")
418
pyqt_bin_dir = os.path.join(pyqt_dir, "bin")
419
if os.path.isdir(pyqt_bin_dir):
420
path = os.environ.get("PATH", "")
421
if pyqt_bin_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
422
os.environ["PATH"] = path + os.pathsep + pyqt_bin_dir
423
# also add all imageformat plugins to distribution
424
# We will look in 2 places, dirname(PyQt4.__file__) and pyqt_dir
425
base_dirs_to_check = []
426
if os.path.isdir(pyqt_dir):
427
base_dirs_to_check.append(pyqt_dir)
433
pyqt4_base_dir = os.path.dirname(PyQt4.__file__)
434
if pyqt4_base_dir != pyqt_dir:
435
base_dirs_to_check.append(pyqt4_base_dir)
436
if not base_dirs_to_check:
437
log.warn("Can't find PyQt4 installation -> not including imageformat"
441
for base_dir in base_dirs_to_check:
442
plug_dir = os.path.join(base_dir, 'plugins', 'imageformats')
443
if os.path.isdir(plug_dir):
444
for fname in os.listdir(plug_dir):
445
# Include plugin dlls, but not debugging dlls
446
fullpath = os.path.join(plug_dir, fname)
447
if fname.endswith('.dll') and not fname.endswith('d4.dll'):
448
files.append(fullpath)
450
data_files.append(('imageformats', files))
452
log.warn('PyQt4 was found, but we could not find any imageformat'
453
' plugins. Are you sure your configuration is correct?')
456
def get_svn_py2exe_info(includes, excludes, packages):
457
packages.append('subvertpy')
458
packages.append('sqlite3')
461
def get_git_py2exe_info(includes, excludes, packages):
462
packages.append('dulwich')
465
def get_fastimport_py2exe_info(includes, excludes, packages):
466
# This is the python-fastimport package, not to be confused with the
467
# brz-fastimport plugin.
468
packages.append('fastimport')
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\\Breezy', relative)
485
target = 'Doc\\Breezy'
486
docs.append((target, r))
489
# python's distutils-based win32 installer
490
ARGS = {'scripts': ['brz', 'tools/win32/brz-win32-bdist-postinstall.py'],
491
'ext_modules': ext_modules,
493
'data_files': find_docs(),
494
# for building cython extensions
495
'cmdclass': command_classes,
498
ARGS.update(META_INFO)
500
PKG_DATA['package_data']['breezy'].append('locale/*/LC_MESSAGES/*.mo')
501
ARGS.update(PKG_DATA)
505
elif 'py2exe' in sys.argv:
509
# pick real brz version
513
for i in breezy.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 = "brz",
553
icon_resources = [(0,'brz.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('breezy')
567
packages = [i for i in packages if not i.startswith('breezy.plugins')]
569
for i in glob.glob('breezy\\*.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.7'):
577
additional_packages.add('xml.etree')
580
warnings.warn('Unknown Python version.\n'
581
'Please check setup.py script for compatibility.')
583
# Although we currently can't enforce it, we consider it an error for
584
# py2exe to report any files are "missing". Such modules we know aren't
585
# used should be listed here.
586
excludes = """Tkinter psyco ElementPath r_hmac
587
ImaginaryModule cElementTree elementtree.ElementTree
588
Crypto.PublicKey._fastmath
590
resource validate""".split()
593
# email package from std python library use lazy import,
594
# so we need to explicitly add all package
595
additional_packages.add('email')
596
# And it uses funky mappings to conver to 'Oldname' to 'newname'. As
597
# a result, packages like 'email.Parser' show as missing. Tell py2exe
600
for oldname in getattr(email, '_LOWERNAMES', []):
601
excludes.append("email." + oldname)
602
for oldname in getattr(email, '_MIMENAMES', []):
603
excludes.append("email.MIME" + oldname)
605
# text files for help topis
606
text_topics = glob.glob('breezy/help_topics/en/*.txt')
607
topics_files = [('lib/help_topics/en', text_topics)]
611
# XXX - should we consider having the concept of an 'official' build,
612
# which hard-codes the list of plugins, gets more upset if modules are
614
plugins = None # will be a set after plugin sniffing...
615
for root, dirs, files in os.walk('breezy/plugins'):
616
if root == 'breezy/plugins':
618
# We ship plugins as normal files on the file-system - however,
619
# the build process can cause *some* of these plugin files to end
620
# up in library.zip. Thus, we saw (eg) "plugins/svn/test" in
621
# library.zip, and then saw import errors related to that as the
622
# rest of the svn plugin wasn't. So we tell py2exe to leave the
623
# plugins out of the .zip file
624
excludes.extend(["breezy.plugins." + d for d in dirs])
627
# Throw away files we don't want packaged. Note that plugins may
628
# have data files with all sorts of extensions so we need to
629
# be conservative here about what we ditch.
630
ext = os.path.splitext(i)[1]
631
if ext.endswith('~') or ext in [".pyc", ".swp"]:
633
if i == '__init__.py' and root == 'breezy/plugins':
635
x.append(os.path.join(root, i))
637
target_dir = root[len('breezy/'):] # install to 'plugins/...'
638
plugins_files.append((target_dir, x))
639
# find modules for built-in plugins
640
import tools.package_mf
641
mf = tools.package_mf.CustomModuleFinder()
642
mf.run_package('breezy/plugins')
643
packs, mods = mf.get_result()
644
additional_packages.update(packs)
645
includes.extend(mods)
647
console_targets = [target,
648
'tools/win32/bzr_postinstall.py',
650
gui_targets = [gui_target]
651
data_files = topics_files + plugins_files + I18N_FILES
653
if 'qbzr' in plugins:
654
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
657
get_svn_py2exe_info(includes, excludes, packages)
660
get_git_py2exe_info(includes, excludes, packages)
662
if 'fastimport' in plugins:
663
get_fastimport_py2exe_info(includes, excludes, packages)
665
if "TBZR" in os.environ:
666
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
667
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
668
# can be downloaded from (username=guest, blank password):
669
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays
670
# look for: version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
671
# Ditto for TORTOISE_OVERLAYS_MSI_X64, pointing at *-x64.msi.
672
for needed in ('TORTOISE_OVERLAYS_MSI_WIN32',
673
'TORTOISE_OVERLAYS_MSI_X64'):
674
url = ('http://guest:@tortoisesvn.tigris.org/svn/tortoisesvn'
676
if not os.path.isfile(os.environ.get(needed, '<nofile>')):
678
"\nPlease set %s to the location of the relevant"
679
"\nTortoiseOverlays .msi installer file."
680
" The installers can be found at"
682
"\ncheck in the version-X.Y.Z/bin/ subdir" % (needed, url))
683
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
684
gui_targets, data_files)
686
# print this warning to stderr as output is redirected, so it is seen
687
# at build time. Also to stdout so it appears in the log
688
for f in (sys.stderr, sys.stdout):
689
f.write("Skipping TBZR binaries - "
690
"please set TBZR to a directory to enable\n")
692
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
694
dll_excludes.extend(["MSWSOCK.dll",
699
options_list = {"py2exe": {"packages": packages + list(additional_packages),
700
"includes": includes,
701
"excludes": excludes,
702
"dll_excludes": dll_excludes,
703
"dist_dir": "win32_bzr.exe",
705
"custom_boot_script":
706
"tools/win32/py2exe_boot_common.py",
710
# We want the libaray.zip to have optimize = 2, but the exe to have
711
# optimize = 1, so that .py files that get compilied at run time
712
# (e.g. user installed plugins) dont have their doc strings removed.
713
class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
714
def build_executable(self, *args, **kwargs):
716
py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
719
if __name__ == '__main__':
720
command_classes['install_data'] = install_data_with_bytecompile
721
command_classes['py2exe'] = py2exe_no_oo_exe
722
setup(options=options_list,
723
console=console_targets,
725
zipfile='lib/library.zip',
726
data_files=data_files,
727
cmdclass=command_classes,
731
# ad-hoc for easy_install
733
if not 'bdist_egg' in sys.argv:
734
# generate and install brz.1 only with plain install, not the
736
DATA_FILES = [('man/man1', ['brz.1'])]
738
DATA_FILES = DATA_FILES + I18N_FILES
740
ARGS = {'scripts': ['brz'],
741
'data_files': DATA_FILES,
742
'cmdclass': command_classes,
743
'ext_modules': ext_modules,
746
ARGS.update(META_INFO)
748
ARGS.update(PKG_DATA)
750
if __name__ == '__main__':