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.rst')
27
with open(readme, 'rb') as f:
32
# META INFORMATION FOR SETUP
33
# see http://docs.python.org/dist/meta-data.html
36
'version': breezy.__version__,
37
'maintainer': 'Breezy Developers',
38
'maintainer_email': 'team@breezy-vcs.org',
39
'url': 'https://www.breezy-vcs.org/',
40
'description': 'Friendly distributed version control system',
41
'license': 'GNU GPL v2',
42
'download_url': 'https://launchpad.net/brz/+download',
43
'long_description': get_long_description(),
45
'Development Status :: 6 - Mature',
46
'Environment :: Console',
47
'Intended Audience :: Developers',
48
'Intended Audience :: System Administrators',
49
'License :: OSI Approved :: GNU General Public License (GPL)',
50
'Operating System :: Microsoft :: Windows',
51
'Operating System :: OS Independent',
52
'Operating System :: POSIX',
53
'Programming Language :: Python',
54
'Programming Language :: C',
55
'Topic :: Software Development :: Version Control',
61
'fastimport': ['fastimport>=0.9.8'],
65
# The list of packages is automatically generated later. Add other things
66
# that are part of BREEZY here.
69
PKG_DATA = {# install files from selftest suite
70
'package_data': {'breezy': ['doc/api/*.txt',
71
'tests/test_patches_data/*',
72
'help_topics/en/*.txt',
73
'tests/ssl_certs/ca.crt',
74
'tests/ssl_certs/server_without_pass.key',
75
'tests/ssl_certs/server_with_pass.key',
76
'tests/ssl_certs/server.crt',
80
for filepath in glob.glob("breezy/locale/*/LC_MESSAGES/*.mo"):
81
langfile = filepath[len("breezy/locale/"):]
82
targetpath = os.path.dirname(os.path.join("share/locale", langfile))
83
I18N_FILES.append((targetpath, [filepath]))
85
def get_breezy_packages():
86
"""Recurse through the breezy directory, and extract the package names"""
89
base_path = os.path.dirname(os.path.abspath(breezy.__file__))
90
for root, dirs, files in os.walk(base_path):
91
if '__init__.py' in files:
92
assert root.startswith(base_path)
93
# Get just the path below breezy
94
package_path = root[len(base_path):]
95
# Remove leading and trailing slashes
96
package_path = package_path.strip('\\/')
98
package_name = 'breezy'
100
package_name = ('breezy.' +
101
package_path.replace('/', '.').replace('\\', '.'))
102
packages.append(package_name)
103
return sorted(packages)
106
BREEZY['packages'] = get_breezy_packages()
109
from distutils import log
37
110
from distutils.core import setup
111
from distutils.version import LooseVersion
38
112
from distutils.command.install_scripts import install_scripts
113
from distutils.command.install_data import install_data
39
114
from distutils.command.build import build
41
116
###############################
45
120
class my_install_scripts(install_scripts):
46
121
""" Customized install_scripts distutils action.
47
Create bzr.bat for win32.
122
Create brz.bat for win32.
53
125
install_scripts.run(self) # standard action
55
127
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"
61
f = file(batch_path, "w")
64
print "Created:", batch_path
66
print "ERROR: Unable to create %s: %s" % (batch_path, e)
129
scripts_dir = os.path.join(sys.prefix, 'Scripts')
130
script_path = self._quoted_path(os.path.join(scripts_dir,
132
python_exe = self._quoted_path(sys.executable)
133
args = self._win_batch_args()
134
batch_str = "@%s %s %s" % (python_exe, script_path, args)
135
batch_path = os.path.join(self.install_dir, "brz.bat")
136
with file(batch_path, "w") as f:
138
print(("Created: %s" % batch_path))
140
e = sys.exc_info()[1]
141
print(("ERROR: Unable to create %s: %s" % (batch_path, e)))
143
def _quoted_path(self, path):
145
return '"' + path + '"'
149
def _win_batch_args(self):
150
from breezy.win32utils import winver
151
if winver == 'Windows NT':
154
return '%1 %2 %3 %4 %5 %6 %7 %8 %9'
155
#/class my_install_scripts
69
158
class bzr_build(build):
70
159
"""Customized build distutils action.
163
sub_commands = build.sub_commands + [
164
('build_mo', lambda _: True),
77
generate_docs.main(argv=["bzr", "man"])
170
from tools import generate_docs
171
generate_docs.main(argv=["brz", "man"])
79
174
########################
81
176
########################
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.
178
from breezy.bzr_distutils import build_mo
180
command_classes = {'install_scripts': my_install_scripts,
182
'build_mo': build_mo,
184
from distutils import log
185
from distutils.errors import CCompilerError, DistutilsPlatformError
186
from distutils.extension import Extension
189
from Cython.Distutils import build_ext
190
from Cython.Compiler.Version import version as cython_version
193
# try to build the extension from the prior generated source.
195
print("The python package 'Cython' is not available."
196
" If the .c files are available,")
197
print("they will be built,"
198
" but modifying the .pyx files will not rebuild them.")
200
from distutils.command.build_ext import build_ext
203
cython_version_info = LooseVersion(cython_version)
206
class build_ext_if_possible(build_ext):
208
user_options = build_ext.user_options + [
209
('allow-python-fallback', None,
210
"When an extension cannot be built, allow falling"
211
" back to the pure-python implementation.")
214
def initialize_options(self):
215
build_ext.initialize_options(self)
216
self.allow_python_fallback = False
221
except DistutilsPlatformError:
222
e = sys.exc_info()[1]
223
if not self.allow_python_fallback:
224
log.warn('\n Cannot build extensions.\n'
225
' Use "build_ext --allow-python-fallback" to use'
226
' slower python implementations instead.\n')
229
log.warn('\n Extensions cannot be built.\n'
230
' Using the slower Python implementations instead.\n')
232
def build_extension(self, ext):
234
build_ext.build_extension(self, ext)
235
except CCompilerError:
236
if not self.allow_python_fallback:
237
log.warn('\n Cannot build extension "%s".\n'
238
' Use "build_ext --allow-python-fallback" to use'
239
' slower python implementations instead.\n'
242
log.warn('\n Building of "%s" extension failed.\n'
243
' Using the slower Python implementation instead.'
247
# Override the build_ext if we have Cython available
248
command_classes['build_ext'] = build_ext_if_possible
249
unavailable_files = []
252
def add_cython_extension(module_name, libraries=None, extra_source=[]):
253
"""Add a cython module to build.
255
This will use Cython to auto-generate the .c file if it is available.
256
Otherwise it will fall back on the .c file. If the .c file is not
257
available, it will warn, and not add anything.
259
You can pass any extra options to Extension through kwargs. One example is
262
:param module_name: The python path to the module. This will be used to
263
determine the .pyx and .c files to use.
265
path = module_name.replace('.', '/')
266
cython_name = path + '.pyx'
269
if sys.platform == 'win32':
270
# cython uses the macro WIN32 to detect the platform, even though it
271
# should be using something like _WIN32 or MS_WINDOWS, oh well, we can
272
# give it the right value.
273
define_macros.append(('WIN32', None))
275
source = [cython_name]
277
if not os.path.isfile(c_name):
278
unavailable_files.append(c_name)
282
source.extend(extra_source)
283
include_dirs = ['breezy']
284
ext_modules.append(Extension(module_name, source,
285
define_macros=define_macros, libraries=libraries,
286
include_dirs=include_dirs))
289
add_cython_extension('breezy._simple_set_pyx')
290
ext_modules.append(Extension('breezy._static_tuple_c',
291
['breezy/_static_tuple_c.c']))
292
add_cython_extension('breezy._annotator_pyx')
293
add_cython_extension('breezy._bencode_pyx')
294
add_cython_extension('breezy._chunks_to_lines_pyx')
295
add_cython_extension('breezy.bzr._groupcompress_pyx',
296
extra_source=['breezy/bzr/diff-delta.c'])
297
add_cython_extension('breezy.bzr._knit_load_data_pyx')
298
add_cython_extension('breezy._known_graph_pyx')
299
add_cython_extension('breezy._rio_pyx')
300
if sys.platform == 'win32':
301
add_cython_extension('breezy.bzr._dirstate_helpers_pyx',
302
libraries=['Ws2_32'])
303
add_cython_extension('breezy._walkdirs_win32')
305
add_cython_extension('breezy.bzr._dirstate_helpers_pyx')
306
add_cython_extension('breezy._readdir_pyx')
307
add_cython_extension('breezy.bzr._chk_map_pyx')
308
ext_modules.append(Extension('breezy._patiencediff_c',
309
['breezy/_patiencediff_c.c']))
310
add_cython_extension('breezy.bzr._btree_serializer_pyx')
313
if unavailable_files:
314
print('C extension(s) not found:')
315
print((' %s' % ('\n '.join(unavailable_files),)))
316
print('The python versions will be used instead.')
320
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
321
gui_targets, data_files):
322
packages.append('tbzrcommands')
324
# ModuleFinder can't handle runtime changes to __path__, but
325
# win32com uses them. Hook this in so win32com.shell is found.
328
import cPickle as pickle
329
for p in win32com.__path__[1:]:
330
modulefinder.AddPackagePath("win32com", p)
331
for extra in ["win32com.shell"]:
333
m = sys.modules[extra]
334
for p in m.__path__[1:]:
335
modulefinder.AddPackagePath(extra, p)
337
# TBZR points to the TBZR directory
338
tbzr_root = os.environ["TBZR"]
340
# Ensure tbreezy itself is on sys.path
341
sys.path.append(tbzr_root)
343
packages.append("tbreezy")
345
# collect up our icons.
347
ico_root = os.path.join(tbzr_root, 'tbreezy', 'resources')
348
icos = [] # list of (path_root, relative_ico_path)
349
# First always brz's icon and its in the root of the brz tree.
350
icos.append(('', 'brz.ico'))
351
for root, dirs, files in os.walk(ico_root):
352
icos.extend([(ico_root, os.path.join(root, f)[len(ico_root)+1:])
353
for f in files if f.endswith('.ico')])
354
# allocate an icon ID for each file and the full path to the ico
355
icon_resources = [(rid, os.path.join(ico_dir, ico_name))
356
for rid, (ico_dir, ico_name) in enumerate(icos)]
357
# create a string resource with the mapping. Might as well save the
358
# runtime some effort and write a pickle.
359
# Runtime expects unicode objects with forward-slash seps.
360
fse = sys.getfilesystemencoding()
361
map_items = [(f.replace('\\', '/').decode(fse), rid)
362
for rid, (_, f) in enumerate(icos)]
363
ico_map = dict(map_items)
364
# Create a new resource type of 'ICON_MAP', and use ID=1
365
other_resources = [ ("ICON_MAP", 1, pickle.dumps(ico_map))]
367
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
368
win32ui crawler.Crawler""".split())
370
# tbzrcache executables - a "console" version for debugging and a
371
# GUI version that is generally used.
373
script = os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
374
icon_resources = icon_resources,
375
other_resources = other_resources,
377
console_targets.append(tbzrcache)
379
# Make a windows version which is the same except for the base name.
380
tbzrcachew = tbzrcache.copy()
381
tbzrcachew["dest_base"]="tbzrcachew"
382
gui_targets.append(tbzrcachew)
384
# ditto for the tbzrcommand tool
386
script = os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
387
icon_resources = icon_resources,
388
other_resources = other_resources,
390
console_targets.append(tbzrcommand)
391
tbzrcommandw = tbzrcommand.copy()
392
tbzrcommandw["dest_base"]="tbzrcommandw"
393
gui_targets.append(tbzrcommandw)
395
# A utility to see python output from both C++ and Python based shell
397
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
398
console_targets.append(tracer)
400
# The C++ implemented shell extensions.
401
dist_dir = os.path.join(tbzr_root, "shellext", "build")
402
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x86.dll')]))
403
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x64.dll')]))
406
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
407
# PyQt4 itself still escapes the plugin detection code for some reason...
408
includes.append('PyQt4.QtCore')
409
includes.append('PyQt4.QtGui')
410
includes.append('PyQt4.QtTest')
411
includes.append('sip') # extension module required for Qt.
412
packages.append('pygments') # colorizer for qbzr
413
packages.append('docutils') # html formatting
414
includes.append('win32event') # for qsubprocess stuff
415
# the qt binaries might not be on PATH...
416
# They seem to install to a place like C:\Python25\PyQt4\*
417
# Which is not the same as C:\Python25\Lib\site-packages\PyQt4
418
pyqt_dir = os.path.join(sys.prefix, "PyQt4")
419
pyqt_bin_dir = os.path.join(pyqt_dir, "bin")
420
if os.path.isdir(pyqt_bin_dir):
421
path = os.environ.get("PATH", "")
422
if pyqt_bin_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
423
os.environ["PATH"] = path + os.pathsep + pyqt_bin_dir
424
# also add all imageformat plugins to distribution
425
# We will look in 2 places, dirname(PyQt4.__file__) and pyqt_dir
426
base_dirs_to_check = []
427
if os.path.isdir(pyqt_dir):
428
base_dirs_to_check.append(pyqt_dir)
434
pyqt4_base_dir = os.path.dirname(PyQt4.__file__)
435
if pyqt4_base_dir != pyqt_dir:
436
base_dirs_to_check.append(pyqt4_base_dir)
437
if not base_dirs_to_check:
438
log.warn("Can't find PyQt4 installation -> not including imageformat"
442
for base_dir in base_dirs_to_check:
443
plug_dir = os.path.join(base_dir, 'plugins', 'imageformats')
444
if os.path.isdir(plug_dir):
445
for fname in os.listdir(plug_dir):
446
# Include plugin dlls, but not debugging dlls
447
fullpath = os.path.join(plug_dir, fname)
448
if fname.endswith('.dll') and not fname.endswith('d4.dll'):
449
files.append(fullpath)
451
data_files.append(('imageformats', files))
453
log.warn('PyQt4 was found, but we could not find any imageformat'
454
' plugins. Are you sure your configuration is correct?')
457
def get_svn_py2exe_info(includes, excludes, packages):
458
packages.append('subvertpy')
459
packages.append('sqlite3')
462
def get_git_py2exe_info(includes, excludes, packages):
463
packages.append('dulwich')
466
def get_fastimport_py2exe_info(includes, excludes, packages):
467
# This is the python-fastimport package, not to be confused with the
468
# brz-fastimport plugin.
469
packages.append('fastimport')
472
if 'bdist_wininst' in sys.argv:
475
for root, dirs, files in os.walk('doc'):
478
if (os.path.splitext(f)[1] in ('.html','.css','.png','.pdf')
479
or f == 'quick-start-summary.svg'):
480
r.append(os.path.join(root, f))
484
target = os.path.join('Doc\\Breezy', relative)
486
target = 'Doc\\Breezy'
487
docs.append((target, r))
490
# python's distutils-based win32 installer
491
ARGS = {'scripts': ['brz', 'tools/win32/brz-win32-bdist-postinstall.py'],
492
'ext_modules': ext_modules,
494
'data_files': find_docs(),
495
# for building cython extensions
496
'cmdclass': command_classes,
499
ARGS.update(META_INFO)
501
PKG_DATA['package_data']['breezy'].append('locale/*/LC_MESSAGES/*.mo')
502
ARGS.update(PKG_DATA)
506
elif 'py2exe' in sys.argv:
510
# pick real brz version
514
for i in breezy.version_info[:4]:
519
version_number.append(str(i))
520
version_str = '.'.join(version_number)
522
# An override to install_data used only by py2exe builds, which arranges
523
# to byte-compile any .py files in data_files (eg, our plugins)
524
# Necessary as we can't rely on the user having the relevant permissions
525
# to the "Program Files" directory to generate them on the fly.
526
class install_data_with_bytecompile(install_data):
528
from distutils.util import byte_compile
530
install_data.run(self)
532
py2exe = self.distribution.get_command_obj('py2exe', False)
533
# GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
534
# time before living with docstring stripping
536
compile_names = [f for f in self.outfiles if f.endswith('.py')]
537
# Round mtime to nearest even second so that installing on a FAT
538
# filesystem bytecode internal and script timestamps will match
539
for f in compile_names:
540
mtime = os.stat(f).st_mtime
541
remainder = mtime % 2
544
os.utime(f, (mtime, mtime))
545
byte_compile(compile_names,
547
force=self.force, prefix=self.install_dir,
548
dry_run=self.dry_run)
549
self.outfiles.extend([f + 'o' for f in compile_names])
550
# end of class install_data_with_bytecompile
552
target = py2exe.build_exe.Target(script = "brz",
554
icon_resources = [(0,'brz.ico')],
555
name = META_INFO['name'],
556
version = version_str,
557
description = META_INFO['description'],
558
author = META_INFO['author'],
559
copyright = "(c) Canonical Ltd, 2005-2010",
560
company_name = "Canonical Ltd.",
561
comments = META_INFO['description'],
563
gui_target = copy.copy(target)
564
gui_target.dest_base = "bzrw"
566
packages = BREEZY['packages']
567
packages.remove('breezy')
568
packages = [i for i in packages if not i.startswith('breezy.plugins')]
570
for i in glob.glob('breezy\\*.py'):
571
module = i[:-3].replace('\\', '.')
572
if module.endswith('__init__'):
573
module = module[:-len('__init__')]
574
includes.append(module)
576
additional_packages = set()
577
if sys.version.startswith('2.7'):
578
additional_packages.add('xml.etree')
581
warnings.warn('Unknown Python version.\n'
582
'Please check setup.py script for compatibility.')
584
# Although we currently can't enforce it, we consider it an error for
585
# py2exe to report any files are "missing". Such modules we know aren't
586
# used should be listed here.
587
excludes = """Tkinter psyco ElementPath r_hmac
588
ImaginaryModule cElementTree elementtree.ElementTree
589
Crypto.PublicKey._fastmath
591
resource validate""".split()
594
# email package from std python library use lazy import,
595
# so we need to explicitly add all package
596
additional_packages.add('email')
597
# And it uses funky mappings to conver to 'Oldname' to 'newname'. As
598
# a result, packages like 'email.Parser' show as missing. Tell py2exe
601
for oldname in getattr(email, '_LOWERNAMES', []):
602
excludes.append("email." + oldname)
603
for oldname in getattr(email, '_MIMENAMES', []):
604
excludes.append("email.MIME" + oldname)
606
# text files for help topis
607
text_topics = glob.glob('breezy/help_topics/en/*.txt')
608
topics_files = [('lib/help_topics/en', text_topics)]
612
# XXX - should we consider having the concept of an 'official' build,
613
# which hard-codes the list of plugins, gets more upset if modules are
615
plugins = None # will be a set after plugin sniffing...
616
for root, dirs, files in os.walk('breezy/plugins'):
617
if root == 'breezy/plugins':
619
# We ship plugins as normal files on the file-system - however,
620
# the build process can cause *some* of these plugin files to end
621
# up in library.zip. Thus, we saw (eg) "plugins/svn/test" in
622
# library.zip, and then saw import errors related to that as the
623
# rest of the svn plugin wasn't. So we tell py2exe to leave the
624
# plugins out of the .zip file
625
excludes.extend(["breezy.plugins." + d for d in dirs])
628
# Throw away files we don't want packaged. Note that plugins may
629
# have data files with all sorts of extensions so we need to
630
# be conservative here about what we ditch.
631
ext = os.path.splitext(i)[1]
632
if ext.endswith('~') or ext in [".pyc", ".swp"]:
634
if i == '__init__.py' and root == 'breezy/plugins':
636
x.append(os.path.join(root, i))
638
target_dir = root[len('breezy/'):] # install to 'plugins/...'
639
plugins_files.append((target_dir, x))
640
# find modules for built-in plugins
641
import tools.package_mf
642
mf = tools.package_mf.CustomModuleFinder()
643
mf.run_package('breezy/plugins')
644
packs, mods = mf.get_result()
645
additional_packages.update(packs)
646
includes.extend(mods)
648
console_targets = [target,
649
'tools/win32/bzr_postinstall.py',
651
gui_targets = [gui_target]
652
data_files = topics_files + plugins_files + I18N_FILES
654
if 'qbzr' in plugins:
655
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
658
get_svn_py2exe_info(includes, excludes, packages)
661
get_git_py2exe_info(includes, excludes, packages)
663
if 'fastimport' in plugins:
664
get_fastimport_py2exe_info(includes, excludes, packages)
666
if "TBZR" in os.environ:
667
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
668
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
669
# can be downloaded from (username=guest, blank password):
670
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays
671
# look for: version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
672
# Ditto for TORTOISE_OVERLAYS_MSI_X64, pointing at *-x64.msi.
673
for needed in ('TORTOISE_OVERLAYS_MSI_WIN32',
674
'TORTOISE_OVERLAYS_MSI_X64'):
675
url = ('http://guest:@tortoisesvn.tigris.org/svn/tortoisesvn'
677
if not os.path.isfile(os.environ.get(needed, '<nofile>')):
679
"\nPlease set %s to the location of the relevant"
680
"\nTortoiseOverlays .msi installer file."
681
" The installers can be found at"
683
"\ncheck in the version-X.Y.Z/bin/ subdir" % (needed, url))
684
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
685
gui_targets, data_files)
687
# print this warning to stderr as output is redirected, so it is seen
688
# at build time. Also to stdout so it appears in the log
689
for f in (sys.stderr, sys.stdout):
690
f.write("Skipping TBZR binaries - "
691
"please set TBZR to a directory to enable\n")
693
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
695
dll_excludes.extend(["MSWSOCK.dll",
700
options_list = {"py2exe": {"packages": packages + list(additional_packages),
701
"includes": includes,
702
"excludes": excludes,
703
"dll_excludes": dll_excludes,
704
"dist_dir": "win32_bzr.exe",
706
"custom_boot_script":
707
"tools/win32/py2exe_boot_common.py",
711
# We want the libaray.zip to have optimize = 2, but the exe to have
712
# optimize = 1, so that .py files that get compilied at run time
713
# (e.g. user installed plugins) dont have their doc strings removed.
714
class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
715
def build_executable(self, *args, **kwargs):
717
py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
720
if __name__ == '__main__':
721
command_classes['install_data'] = install_data_with_bytecompile
722
command_classes['py2exe'] = py2exe_no_oo_exe
723
setup(options=options_list,
724
console=console_targets,
726
zipfile='lib/library.zip',
727
data_files=data_files,
728
cmdclass=command_classes,
732
# ad-hoc for easy_install
734
if not 'bdist_egg' in sys.argv:
735
# generate and install brz.1 only with plain install, not the
737
DATA_FILES = [('man/man1', ['brz.1'])]
739
DATA_FILES = DATA_FILES + I18N_FILES
741
ARGS = {'scripts': ['brz'],
742
'data_files': DATA_FILES,
743
'cmdclass': command_classes,
744
'ext_modules': ext_modules,
747
ARGS.update(META_INFO)
749
ARGS.update(PKG_DATA)
751
if __name__ == '__main__':