197
197
except DistutilsPlatformError, e:
198
198
if not self.allow_python_fallback:
199
199
log.warn('\n Cannot build extensions.\n'
200
' Use --allow-python-fallback to use slower'
201
' python implementations instead.\n')
200
' Use "build_ext --allow-python-fallback" to use'
201
' slower python implementations instead.\n')
204
204
log.warn('\n Extensions cannot be built.\n'
209
209
build_ext.build_extension(self, ext)
210
210
except CCompilerError:
211
211
if not self.allow_python_fallback:
212
log.warn('\n Failed to build "%s".\n'
213
' Use --allow-python-fallback to use slower'
214
' python implementations instead.\n'
212
log.warn('\n Cannot build extension "%s".\n'
213
' Use "build_ext --allow-python-fallback" to use'
214
' slower python implementations instead.\n'
217
217
log.warn('\n Building of "%s" extension failed.\n'
224
224
unavailable_files = []
227
def add_pyrex_extension(module_name, **kwargs):
227
def add_pyrex_extension(module_name, libraries=None):
228
228
"""Add a pyrex module to build.
230
230
This will use Pyrex to auto-generate the .c file if it is available.
240
240
path = module_name.replace('.', '/')
241
241
pyrex_name = path + '.pyx'
242
242
c_name = path + '.c'
244
if sys.platform == 'win32':
245
# pyrex uses the macro WIN32 to detect the platform, even though it should
246
# be using something like _WIN32 or MS_WINDOWS, oh well, we can give it the
248
define_macros.append(('WIN32', None))
244
ext_modules.append(Extension(module_name, [pyrex_name], **kwargs))
250
ext_modules.append(Extension(module_name, [pyrex_name],
251
define_macros=define_macros, libraries=libraries))
246
253
if not os.path.isfile(c_name):
247
254
unavailable_files.append(c_name)
249
ext_modules.append(Extension(module_name, [c_name], **kwargs))
256
ext_modules.append(Extension(module_name, [c_name],
257
define_macros=define_macros, libraries=libraries))
252
260
add_pyrex_extension('bzrlib._btree_serializer_c')
261
add_pyrex_extension('bzrlib._chunks_to_lines_pyx')
253
262
add_pyrex_extension('bzrlib._knit_load_data_c')
254
263
if sys.platform == 'win32':
255
264
add_pyrex_extension('bzrlib._dirstate_helpers_c',
258
# pyrex uses the macro WIN32 to detect the platform, even though it should
259
# be using something like _WIN32 or MS_WINDOWS, oh well, we can give it the
261
add_pyrex_extension('bzrlib._walkdirs_win32',
262
define_macros=[('WIN32', None)])
265
libraries=['Ws2_32'])
266
add_pyrex_extension('bzrlib._walkdirs_win32')
264
268
if have_pyrex and pyrex_version == '0.9.4.1':
265
269
# Pyrex 0.9.4.1 fails to compile this extension correctly
287
291
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
292
gui_targets, data_files):
289
293
packages.append('tbzrcommands')
291
295
# ModuleFinder can't handle runtime changes to __path__, but
337
341
excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
338
342
win32ui crawler.Crawler""".split())
344
# NOTE: We still create a DLL version of the Python implemented shell
345
# extension for testing purposes - but it is *not* registered by
346
# default - our C++ one is instead. To discourage people thinking
347
# this DLL is still necessary, its called 'tbzr_old.dll'
341
349
modules=["tbzr"],
342
350
create_exe = False, # we only want a .dll
351
dest_base = 'tbzr_old',
344
353
com_targets.append(tbzr)
346
355
# tbzrcache executables - a "console" version for debugging and a
347
356
# GUI version that is generally used.
348
357
tbzrcache = dict(
349
script = os.path.join(tbzr_root, "Scripts", "tbzrcache.py"),
358
script = os.path.join(tbzr_root, "scripts", "tbzrcache.py"),
350
359
icon_resources = icon_resources,
351
360
other_resources = other_resources,
360
369
# ditto for the tbzrcommand tool
361
370
tbzrcommand = dict(
362
script = os.path.join(tbzr_root, "Scripts", "tbzrcommand.py"),
371
script = os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
363
372
icon_resources = [(0,'bzr.ico')],
365
374
console_targets.append(tbzrcommand)
367
376
tbzrcommandw["dest_base"]="tbzrcommandw"
368
377
gui_targets.append(tbzrcommandw)
372
script = os.path.join(tbzr_root, "Scripts", "tbzrtest.py"),
374
console_targets.append(tbzrtest)
376
# A utility to see python output from the shell extension - this will
377
# die when we get a c++ extension
378
# any .py file from pywin32's win32 lib will do (other than
379
# win32traceutil itself that is)
381
win32_lib_dir = os.path.dirname(winerror.__file__)
382
tracer = dict(script = os.path.join(win32_lib_dir, "win32traceutil.py"),
383
dest_base="tbzr_tracer")
379
# A utility to see python output from both C++ and Python based shell
381
tracer = dict(script=os.path.join(tbzr_root, "scripts", "tbzrtrace.py"))
384
382
console_targets.append(tracer)
384
# The C++ implemented shell extensions.
385
dist_dir = os.path.join(tbzr_root, "shellext", "cpp", "tbzrshellext",
387
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x86.dll')]))
388
data_files.append(('', [os.path.join(dist_dir, 'tbzrshellext_x64.dll')]))
387
391
def get_qbzr_py2exe_info(includes, excludes, packages):
388
392
# PyQt4 itself still escapes the plugin detection code for some reason...
404
408
os.environ["PATH"] = path + os.pathsep + qt_dir
411
def get_svn_py2exe_info(includes, excludes, packages):
412
packages.append('subvertpy')
407
415
if 'bdist_wininst' in sys.argv:
547
555
for root, dirs, files in os.walk('bzrlib/plugins'):
548
556
if root == 'bzrlib/plugins':
549
557
plugins = set(dirs)
558
# We ship plugins as normal files on the file-system - however,
559
# the build process can cause *some* of these plugin files to end
560
# up in library.zip. Thus, we saw (eg) "plugins/svn/test" in
561
# library.zip, and then saw import errors related to that as the
562
# rest of the svn plugin wasn't. So we tell py2exe to leave the
563
# plugins out of the .zip file
564
excludes.extend(["bzrlib.plugins." + d for d in dirs])
552
567
if os.path.splitext(i)[1] not in [".py", ".pyd", ".dll", ".mo"]:
588
data_files = topics_files + plugins_files
574
590
if 'qbzr' in plugins:
575
591
get_qbzr_py2exe_info(includes, excludes, packages)
594
get_svn_py2exe_info(includes, excludes, packages)
577
596
if "TBZR" in os.environ:
578
597
# TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
579
598
# TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
580
599
# can be downloaded from (username=guest, blank password):
581
600
# http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays/version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
582
if not os.path.isfile(os.environ.get('TORTOISE_OVERLAYS_MSI_WIN32',
584
raise RuntimeError("Please set TORTOISE_OVERLAYS_MSI_WIN32 to the"
585
" location of the Win32 TortoiseOverlays .msi"
601
# Ditto for TORTOISE_OVERLAYS_MSI_X64, pointing at *-x64.msi.
602
for needed in ('TORTOISE_OVERLAYS_MSI_WIN32',
603
'TORTOISE_OVERLAYS_MSI_X64'):
604
if not os.path.isfile(os.environ.get(needed, '<nofile>')):
605
raise RuntimeError("Please set %s to the"
606
" location of the relevant TortoiseOverlays"
607
" .msi installer file" % needed)
587
608
get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
609
gui_targets, data_files)
590
611
# print this warning to stderr as output is redirected, so it is seen
591
612
# at build time. Also to stdout so it appears in the log
596
617
# MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
598
dll_excludes.append("MSWSOCK.dll")
619
dll_excludes.extend(["MSWSOCK.dll", "MSVCP60.dll", "powrprof.dll"])
599
620
options_list = {"py2exe": {"packages": packages + list(additional_packages),
600
621
"includes": includes,
601
622
"excludes": excludes,
610
631
windows=gui_targets,
611
632
com_server=com_targets,
612
633
zipfile='lib/library.zip',
613
data_files=topics_files + plugins_files,
634
data_files=data_files,
614
635
cmdclass={'install_data': install_data_with_bytecompile},