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
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
473
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')
476
497
if 'bdist_wininst' in sys.argv:
498
519
'data_files': find_docs(),
499
520
# for building pyrex extensions
500
'cmdclass': {'build_ext': build_ext_if_possible},
521
'cmdclass': command_classes,
503
524
ARGS.update(META_INFO)
504
525
ARGS.update(BZRLIB)
526
PKG_DATA['package_data']['bzrlib'].append('locale/*/LC_MESSAGES/*.mo')
505
527
ARGS.update(PKG_DATA)
509
531
elif 'py2exe' in sys.argv:
534
555
install_data.run(self)
536
557
py2exe = self.distribution.get_command_obj('py2exe', False)
537
optimize = py2exe.optimize
558
# GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
559
# time before living with docstring stripping
538
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))
539
570
byte_compile(compile_names,
540
571
optimize=optimize,
541
572
force=self.force, prefix=self.install_dir,
542
573
dry_run=self.dry_run)
547
self.outfiles.extend([f + suffix for f in compile_names])
574
self.outfiles.extend([f + 'o' for f in compile_names])
548
575
# end of class install_data_with_bytecompile
550
577
target = py2exe.build_exe.Target(script = "bzr",
558
585
company_name = "Canonical Ltd.",
559
586
comments = META_INFO['description'],
588
gui_target = copy.copy(target)
589
gui_target.dest_base = "bzrw"
562
591
packages = BZRLIB['packages']
563
592
packages.remove('bzrlib')
648
677
console_targets = [target,
649
678
'tools/win32/bzr_postinstall.py',
652
data_files = topics_files + plugins_files
680
gui_targets = [gui_target]
681
data_files = topics_files + plugins_files + I18N_FILES
654
683
if 'qbzr' in plugins:
655
684
get_qbzr_py2exe_info(includes, excludes, packages, data_files)
657
686
if 'svn' in plugins:
658
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)
660
695
if "TBZR" in os.environ:
661
696
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
662
697
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
681
716
# print this warning to stderr as output is redirected, so it is seen
682
717
# at build time. Also to stdout so it appears in the log
683
718
for f in (sys.stderr, sys.stdout):
685
"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")
687
722
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
689
dll_excludes.extend(["MSWSOCK.dll", "MSVCP60.dll", "powrprof.dll"])
724
dll_excludes.extend(["MSWSOCK.dll",
690
729
options_list = {"py2exe": {"packages": packages + list(additional_packages),
691
730
"includes": includes,
692
731
"excludes": excludes,
693
732
"dll_excludes": dll_excludes,
694
733
"dist_dir": "win32_bzr.exe",
735
"custom_boot_script":
736
"tools/win32/py2exe_boot_common.py",
699
setup(options=options_list,
700
console=console_targets,
702
zipfile='lib/library.zip',
703
data_files=data_files,
704
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,
708
761
# ad-hoc for easy_install
712
765
# easy_install one
713
766
DATA_FILES = [('man/man1', ['bzr.1'])]
715
if sys.platform != 'win32':
716
# see https://wiki.kubuntu.org/Apport/DeveloperHowTo
718
# checking the paths and hardcoding the check for root is a bit gross,
719
# but I don't see a cleaner way to find out the locations in a way
720
# that's going to align with the hardcoded paths in apport.
721
if os.geteuid() == 0:
723
('/usr/share/apport/package-hooks',
724
['apport/source_bzr.py']),
725
('/etc/apport/crashdb.conf.d/',
726
['apport/bzr-crashdb.conf']),]
768
DATA_FILES = DATA_FILES + I18N_FILES
729
770
ARGS = {'scripts': ['bzr'],
730
771
'data_files': DATA_FILES,