13
if sys.version_info < (2, 4):
14
sys.stderr.write("[ERROR] Not a supported Python version. Need 2.4+\n")
15
if sys.version_info < (2, 6):
16
sys.stderr.write("[ERROR] Not a supported Python version. Need 2.6+\n")
17
19
# NOTE: The directory containing setup.py, whether run by 'python setup.py' or
37
39
'version': bzrlib.__version__,
38
40
'author': 'Canonical Ltd',
39
41
'author_email': 'bazaar@lists.canonical.com',
40
'url': 'http://www.bazaar.canonical.com/',
42
'url': 'http://bazaar.canonical.com/',
41
43
'description': 'Friendly distributed version control system',
42
44
'license': 'GNU GPL v2',
43
45
'download_url': 'https://launchpad.net/bzr/+download',
65
67
'package_data': {'bzrlib': ['doc/api/*.txt',
66
68
'tests/test_patches_data/*',
67
69
'help_topics/en/*.txt',
70
'tests/ssl_certs/ca.crt',
68
71
'tests/ssl_certs/server_without_pass.key',
69
72
'tests/ssl_certs/server_with_pass.key',
70
'tests/ssl_certs/server.crt'
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]))
75
82
def get_bzrlib_packages():
76
83
"""Recurse through the bzrlib directory, and extract the package names"""
99
106
from distutils import log
100
107
from distutils.core import setup
108
from distutils.version import LooseVersion
101
109
from distutils.command.install_scripts import install_scripts
102
110
from distutils.command.install_data import install_data
103
111
from distutils.command.build import build
125
133
f = file(batch_path, "w")
126
134
f.write(batch_str)
128
print "Created:", batch_path
130
print "ERROR: Unable to create %s: %s" % (batch_path, e)
136
print("Created: %s" % batch_path)
138
e = sys.exc_info()[1]
139
print("ERROR: Unable to create %s: %s" % (batch_path, e))
132
141
def _quoted_path(self, path):
161
174
########################
176
from bzrlib.bzr_distutils import build_mo
163
178
command_classes = {'install_scripts': my_install_scripts,
180
'build_mo': build_mo,
165
182
from distutils import log
166
183
from distutils.errors import CCompilerError, DistutilsPlatformError
167
184
from distutils.extension import Extension
188
from Cython.Distutils import build_ext
189
from Cython.Compiler.Version import version as pyrex_version
191
print("No Cython, trying Pyrex...")
171
192
from Pyrex.Distutils import build_ext
172
193
from Pyrex.Compiler.Version import version as pyrex_version
174
print "No Pyrex, trying Cython..."
175
from Cython.Distutils import build_ext
176
from Cython.Compiler.Version import version as pyrex_version
177
194
except ImportError:
178
195
have_pyrex = False
179
196
# try to build the extension from the prior generated source.
181
print ("The python package 'Pyrex' is not available."
182
" If the .c files are available,")
183
print ("they will be built,"
184
" but modifying the .pyx files will not rebuild them.")
198
print("The python package 'Pyrex' is not available."
199
" If the .c files are available,")
200
print("they will be built,"
201
" but modifying the .pyx files will not rebuild them.")
186
203
from distutils.command.build_ext import build_ext
188
205
have_pyrex = True
189
pyrex_version_info = tuple(map(int, pyrex_version.split('.')))
206
pyrex_version_info = LooseVersion(pyrex_version)
192
209
class build_ext_if_possible(build_ext):
206
223
build_ext.run(self)
207
except DistutilsPlatformError, e:
224
except DistutilsPlatformError:
225
e = sys.exc_info()[1]
208
226
if not self.allow_python_fallback:
209
227
log.warn('\n Cannot build extensions.\n'
210
228
' Use "build_ext --allow-python-fallback" to use'
281
299
add_pyrex_extension('bzrlib._dirstate_helpers_pyx',
282
300
libraries=['Ws2_32'])
283
301
add_pyrex_extension('bzrlib._walkdirs_win32')
286
if have_pyrex and pyrex_version_info[:3] == (0,9,4):
303
if have_pyrex and pyrex_version_info == LooseVersion("0.9.4.1"):
287
304
# Pyrex 0.9.4.1 fails to compile this extension correctly
288
305
# The code it generates re-uses a "local" pointer and
289
306
# calls "PY_DECREF" after having set it to NULL. (It mixes PY_XDECREF
290
307
# which is NULL safe with PY_DECREF which is not.)
291
# <https://bugs.edge.launchpad.net/bzr/+bug/449372>
292
# <https://bugs.edge.launchpad.net/bzr/+bug/276868>
293
print 'Cannot build extension "bzrlib._dirstate_helpers_pyx" using'
294
print 'your version of pyrex "%s". Please upgrade your pyrex' % (
296
print 'install. For now, the non-compiled (python) version will'
297
print 'be used instead.'
308
# <https://bugs.launchpad.net/bzr/+bug/449372>
309
# <https://bugs.launchpad.net/bzr/+bug/276868>
310
print('Cannot build extension "bzrlib._dirstate_helpers_pyx" using')
311
print('your version of pyrex "%s". Please upgrade your pyrex'
313
print('install. For now, the non-compiled (python) version will')
314
print('be used instead.')
299
316
add_pyrex_extension('bzrlib._dirstate_helpers_pyx')
300
317
add_pyrex_extension('bzrlib._readdir_pyx')
302
add_pyrex_extension('bzrlib._chk_map_pyx', libraries=[z_lib])
318
add_pyrex_extension('bzrlib._chk_map_pyx')
303
319
ext_modules.append(Extension('bzrlib._patiencediff_c',
304
320
['bzrlib/_patiencediff_c.c']))
305
if have_pyrex and pyrex_version_info < (0, 9, 6, 3):
307
print 'Your Pyrex/Cython version %s is too old to build the simple_set' % (
309
print 'and static_tuple extensions.'
310
print 'Please upgrade to at least Pyrex 0.9.6.3'
321
if have_pyrex and pyrex_version_info < LooseVersion("0.9.6.3"):
323
print('Your Pyrex/Cython version %s is too old to build the simple_set' % (
325
print('and static_tuple extensions.')
326
print('Please upgrade to at least Pyrex 0.9.6.3')
312
328
# TODO: Should this be a fatal error?
314
330
# We only need 0.9.6.3 to build _simple_set_pyx, but static_tuple depends
322
338
if unavailable_files:
323
print 'C extension(s) not found:'
324
print ' %s' % ('\n '.join(unavailable_files),)
325
print 'The python versions will be used instead.'
339
print('C extension(s) not found:')
340
print(' %s' % ('\n '.join(unavailable_files),))
341
print('The python versions will be used instead.')
329
345
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
393
409
# ditto for the tbzrcommand tool
394
410
tbzrcommand = dict(
395
411
script = os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
396
icon_resources = [(0,'bzr.ico')],
412
icon_resources = icon_resources,
413
other_resources = other_resources,
398
415
console_targets.append(tbzrcommand)
399
416
tbzrcommandw = tbzrcommand.copy()
414
431
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
415
432
# PyQt4 itself still escapes the plugin detection code for some reason...
416
packages.append('PyQt4')
417
excludes.append('PyQt4.elementtree.ElementTree')
418
excludes.append('PyQt4.uic.port_v3')
433
includes.append('PyQt4.QtCore')
434
includes.append('PyQt4.QtGui')
435
includes.append('PyQt4.QtTest')
419
436
includes.append('sip') # extension module required for Qt.
420
437
packages.append('pygments') # colorizer for qbzr
421
438
packages.append('docutils') # html formatting
422
439
includes.append('win32event') # for qsubprocess stuff
423
# but we can avoid many Qt4 Dlls.
425
"""QtAssistantClient4.dll QtCLucene4.dll QtDesigner4.dll
426
QtHelp4.dll QtNetwork4.dll QtOpenGL4.dll QtScript4.dll
427
QtSql4.dll QtTest4.dll QtWebKit4.dll QtXml4.dll
428
qscintilla2.dll""".split())
429
440
# the qt binaries might not be on PATH...
430
441
# They seem to install to a place like C:\Python25\PyQt4\*
431
442
# Which is not the same as C:\Python25\Lib\site-packages\PyQt4
471
482
def get_svn_py2exe_info(includes, excludes, packages):
472
483
packages.append('subvertpy')
484
packages.append('sqlite3')
487
def get_git_py2exe_info(includes, excludes, packages):
488
packages.append('dulwich')
491
def get_fastimport_py2exe_info(includes, excludes, packages):
492
# This is the python-fastimport package, not to be confused with the
493
# bzr-fastimport plugin.
494
packages.append('fastimport')
475
497
if 'bdist_wininst' in sys.argv:
497
519
'data_files': find_docs(),
498
520
# for building pyrex extensions
499
'cmdclass': {'build_ext': build_ext_if_possible},
521
'cmdclass': command_classes,
502
524
ARGS.update(META_INFO)
503
525
ARGS.update(BZRLIB)
526
PKG_DATA['package_data']['bzrlib'].append('locale/*/LC_MESSAGES/*.mo')
504
527
ARGS.update(PKG_DATA)
508
531
elif 'py2exe' in sys.argv:
533
555
install_data.run(self)
535
557
py2exe = self.distribution.get_command_obj('py2exe', False)
536
optimize = py2exe.optimize
558
# GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
559
# time before living with docstring stripping
537
561
compile_names = [f for f in self.outfiles if f.endswith('.py')]
562
# Round mtime to nearest even second so that installing on a FAT
563
# filesystem bytecode internal and script timestamps will match
564
for f in compile_names:
565
mtime = os.stat(f).st_mtime
566
remainder = mtime % 2
569
os.utime(f, (mtime, mtime))
538
570
byte_compile(compile_names,
539
571
optimize=optimize,
540
572
force=self.force, prefix=self.install_dir,
541
573
dry_run=self.dry_run)
546
self.outfiles.extend([f + suffix for f in compile_names])
574
self.outfiles.extend([f + 'o' for f in compile_names])
547
575
# end of class install_data_with_bytecompile
549
577
target = py2exe.build_exe.Target(script = "bzr",
553
581
version = version_str,
554
582
description = META_INFO['description'],
555
583
author = META_INFO['author'],
556
copyright = "(c) Canonical Ltd, 2005-2009",
584
copyright = "(c) Canonical Ltd, 2005-2010",
557
585
company_name = "Canonical Ltd.",
558
586
comments = META_INFO['description'],
588
gui_target = copy.copy(target)
589
gui_target.dest_base = "bzrw"
561
591
packages = BZRLIB['packages']
562
592
packages.remove('bzrlib')
572
602
if sys.version.startswith('2.4'):
573
603
# adding elementtree package
574
604
additional_packages.add('elementtree')
575
elif sys.version.startswith('2.5'):
605
elif sys.version.startswith('2.6') or sys.version.startswith('2.5'):
576
606
additional_packages.add('xml.etree')
624
654
excludes.extend(["bzrlib.plugins." + d for d in dirs])
627
if os.path.splitext(i)[1] not in [".py", ".pyd", ".dll", ".mo"]:
657
# Throw away files we don't want packaged. Note that plugins may
658
# have data files with all sorts of extensions so we need to
659
# be conservative here about what we ditch.
660
ext = os.path.splitext(i)[1]
661
if ext.endswith('~') or ext in [".pyc", ".swp"]:
629
663
if i == '__init__.py' and root == 'bzrlib/plugins':
643
677
console_targets = [target,
644
678
'tools/win32/bzr_postinstall.py',
647
data_files = topics_files + plugins_files
680
gui_targets = [gui_target]
681
data_files = topics_files + plugins_files + I18N_FILES
649
683
if 'qbzr' in plugins:
650
684
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
652
686
if 'svn' in plugins:
653
687
get_svn_py2exe_info(includes, excludes, packages)
690
get_git_py2exe_info(includes, excludes, packages)
692
if 'fastimport' in plugins:
693
get_fastimport_py2exe_info(includes, excludes, packages)
655
695
if "TBZR" in os.environ:
656
696
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
657
697
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
676
716
# print this warning to stderr as output is redirected, so it is seen
677
717
# at build time. Also to stdout so it appears in the log
678
718
for f in (sys.stderr, sys.stdout):
680
"Skipping TBZR binaries - please set TBZR to a directory to enable"
719
f.write("Skipping TBZR binaries - "
720
"please set TBZR to a directory to enable\n")
682
722
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
684
dll_excludes.extend(["MSWSOCK.dll", "MSVCP60.dll", "powrprof.dll"])
724
dll_excludes.extend(["MSWSOCK.dll",
685
729
options_list = {"py2exe": {"packages": packages + list(additional_packages),
686
730
"includes": includes,
687
731
"excludes": excludes,
688
732
"dll_excludes": dll_excludes,
689
733
"dist_dir": "win32_bzr.exe",
735
"custom_boot_script":
736
"tools/win32/py2exe_boot_common.py",
694
setup(options=options_list,
695
console=console_targets,
697
zipfile='lib/library.zip',
698
data_files=data_files,
699
cmdclass={'install_data': install_data_with_bytecompile},
740
# We want the libaray.zip to have optimize = 2, but the exe to have
741
# optimize = 1, so that .py files that get compilied at run time
742
# (e.g. user installed plugins) dont have their doc strings removed.
743
class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
744
def build_executable(self, *args, **kwargs):
746
py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
749
if __name__ == '__main__':
750
command_classes['install_data'] = install_data_with_bytecompile
751
command_classes['py2exe'] = py2exe_no_oo_exe
752
setup(options=options_list,
753
console=console_targets,
755
zipfile='lib/library.zip',
756
data_files=data_files,
757
cmdclass=command_classes,
703
761
# ad-hoc for easy_install
707
765
# easy_install one
708
766
DATA_FILES = [('man/man1', ['bzr.1'])]
768
DATA_FILES = DATA_FILES + I18N_FILES
711
770
ARGS = {'scripts': ['bzr'],
712
771
'data_files': DATA_FILES,