~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to setup.py

Merge with __contains__

Show diffs side-by-side

added added

removed removed

Lines of Context:
95
95
 
96
96
from distutils.core import setup
97
97
from distutils.command.install_scripts import install_scripts
 
98
from distutils.command.install_data import install_data
98
99
from distutils.command.build import build
99
100
 
100
101
###############################
224
225
            ext_modules.append(Extension(module_name, [c_name], **kwargs))
225
226
 
226
227
 
 
228
add_pyrex_extension('bzrlib._btree_serializer_c')
227
229
add_pyrex_extension('bzrlib._dirstate_helpers_c')
228
230
add_pyrex_extension('bzrlib._knit_load_data_c')
 
231
add_pyrex_extension('bzrlib._readdir_pyx')
229
232
if sys.platform == 'win32':
230
233
    # pyrex uses the macro WIN32 to detect the platform, even though it should
231
234
    # be using something like _WIN32 or MS_WINDOWS, oh well, we can give it the
242
245
    print
243
246
 
244
247
 
 
248
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
 
249
                         gui_targets):
 
250
    packages.append('tbzrcommands')
 
251
 
 
252
    # ModuleFinder can't handle runtime changes to __path__, but
 
253
    # win32com uses them.  Hook this in so win32com.shell is found.
 
254
    import modulefinder
 
255
    import win32com
 
256
    for p in win32com.__path__[1:]:
 
257
        modulefinder.AddPackagePath("win32com", p)
 
258
    for extra in ["win32com.shell"]:
 
259
        __import__(extra)
 
260
        m = sys.modules[extra]
 
261
        for p in m.__path__[1:]:
 
262
            modulefinder.AddPackagePath(extra, p)
 
263
 
 
264
    # TBZR points to the TBZR directory
 
265
    tbzr_root = os.environ["TBZR"]
 
266
 
 
267
    # Ensure tbzrlib itself is on sys.path
 
268
    sys.path.append(tbzr_root)
 
269
 
 
270
    # Ensure our COM "entry-point" is on sys.path
 
271
    sys.path.append(os.path.join(tbzr_root, "shellext", "python"))
 
272
 
 
273
    packages.append("tbzrlib")
 
274
    excludes.extend("""pywin pywin.dialogs pywin.dialogs.list
 
275
                       win32ui crawler.Crawler""".split())
 
276
 
 
277
    tbzr = dict(
 
278
        modules=["tbzr"],
 
279
        create_exe = False, # we only want a .dll
 
280
    )
 
281
    com_targets.append(tbzr)
 
282
 
 
283
    # tbzrcache executables - a "console" version for debugging and a
 
284
    # GUI version that is generally used.
 
285
    tbzrcache = dict(
 
286
        script = os.path.join(tbzr_root, "Scripts", "tbzrcache.py"),
 
287
        icon_resources = [(0,'bzr.ico')],
 
288
    )
 
289
    console_targets.append(tbzrcache)
 
290
 
 
291
    # Make a windows version which is the same except for the base name.
 
292
    tbzrcachew = tbzrcache.copy()
 
293
    tbzrcachew["dest_base"]="tbzrcachew"
 
294
    gui_targets.append(tbzrcachew)
 
295
 
 
296
    # ditto for the tbzrcommand tool
 
297
    tbzrcommand = dict(
 
298
        script = os.path.join(tbzr_root, "Scripts", "tbzrcommand.py"),
 
299
        icon_resources = [(0,'bzr.ico')],
 
300
    )
 
301
    console_targets.append(tbzrcommand)
 
302
    tbzrcommandw = tbzrcommand.copy()
 
303
    tbzrcommandw["dest_base"]="tbzrcommandw"
 
304
    gui_targets.append(tbzrcommandw)
 
305
    
 
306
    # tbzr tests
 
307
    tbzrtest = dict(
 
308
        script = os.path.join(tbzr_root, "Scripts", "tbzrtest.py"),
 
309
    )
 
310
    console_targets.append(tbzrtest)
 
311
 
 
312
    # A utility to see python output from the shell extension - this will
 
313
    # die when we get a c++ extension
 
314
    # any .py file from pywin32's win32 lib will do (other than
 
315
    # win32traceutil itself that is)
 
316
    import winerror
 
317
    win32_lib_dir = os.path.dirname(winerror.__file__)
 
318
    tracer = dict(script = os.path.join(win32_lib_dir, "win32traceutil.py"),
 
319
                  dest_base="tbzr_tracer")
 
320
    console_targets.append(tracer)
 
321
 
 
322
 
 
323
def get_qbzr_py2exe_info(includes, excludes, packages):
 
324
    # PyQt4 itself still escapes the plugin detection code for some reason...
 
325
    packages.append('PyQt4')
 
326
    excludes.append('PyQt4.elementtree.ElementTree')
 
327
    includes.append('sip') # extension module required for Qt.
 
328
    packages.append('pygments') # colorizer for qbzr
 
329
    # but we can avoid many Qt4 Dlls.
 
330
    dll_excludes.extend(
 
331
        """QtAssistantClient4.dll QtCLucene4.dll QtDesigner4.dll
 
332
        QtHelp4.dll QtNetwork4.dll QtOpenGL4.dll QtScript4.dll
 
333
        QtSql4.dll QtTest4.dll QtWebKit4.dll QtXml4.dll
 
334
        qscintilla2.dll""".split())
 
335
    # the qt binaries might not be on PATH...
 
336
    qt_dir = os.path.join(sys.prefix, "PyQt4", "bin")
 
337
    path = os.environ.get("PATH","")
 
338
    if qt_dir.lower() not in [p.lower() for p in path.split(os.pathsep)]:
 
339
        os.environ["PATH"] = path + os.pathsep + qt_dir
 
340
 
 
341
 
245
342
if 'bdist_wininst' in sys.argv:
246
343
    def find_docs():
247
344
        docs = []
292
389
        version_number.append(str(i))
293
390
    version_str = '.'.join(version_number)
294
391
 
 
392
    # An override to install_data used only by py2exe builds, which arranges
 
393
    # to byte-compile any .py files in data_files (eg, our plugins)
 
394
    # Necessary as we can't rely on the user having the relevant permissions
 
395
    # to the "Program Files" directory to generate them on the fly.
 
396
    class install_data_with_bytecompile(install_data):
 
397
        def run(self):
 
398
            from distutils.util import byte_compile
 
399
 
 
400
            install_data.run(self)
 
401
 
 
402
            py2exe = self.distribution.get_command_obj('py2exe', False)
 
403
            optimize = py2exe.optimize
 
404
            compile_names = [f for f in self.outfiles if f.endswith('.py')]
 
405
            byte_compile(compile_names,
 
406
                         optimize=optimize,
 
407
                         force=self.force, prefix=self.install_dir,
 
408
                         dry_run=self.dry_run)
 
409
            if optimize:
 
410
                suffix = 'o'
 
411
            else:
 
412
                suffix = 'c'
 
413
            self.outfiles.extend([f + suffix for f in compile_names])
 
414
    # end of class install_data_with_bytecompile
 
415
 
295
416
    target = py2exe.build_exe.Target(script = "bzr",
296
417
                                     dest_base = "bzr",
297
418
                                     icon_resources = [(0,'bzr.ico')],
324
445
        import warnings
325
446
        warnings.warn('Unknown Python version.\n'
326
447
                      'Please check setup.py script for compatibility.')
 
448
 
 
449
    # Although we currently can't enforce it, we consider it an error for
 
450
    # py2exe to report any files are "missing".  Such modules we know aren't
 
451
    # used should be listed here.
 
452
    excludes = """Tkinter psyco ElementPath r_hmac
 
453
                  ImaginaryModule cElementTree elementtree.ElementTree
 
454
                  Crypto.PublicKey._fastmath
 
455
                  medusa medusa.filesys medusa.ftp_server
 
456
                  tools tools.doc_generate
 
457
                  resource validate""".split()
 
458
    dll_excludes = []
 
459
 
327
460
    # email package from std python library use lazy import,
328
461
    # so we need to explicitly add all package
329
462
    additional_packages.add('email')
 
463
    # And it uses funky mappings to conver to 'Oldname' to 'newname'.  As
 
464
    # a result, packages like 'email.Parser' show as missing.  Tell py2exe
 
465
    # to exclude them.
 
466
    import email
 
467
    for oldname in getattr(email, '_LOWERNAMES', []):
 
468
        excludes.append("email." + oldname)
 
469
    for oldname in getattr(email, '_MIMENAMES', []):
 
470
        excludes.append("email.MIME" + oldname)
330
471
 
331
472
    # text files for help topis
332
473
    text_topics = glob.glob('bzrlib/help_topics/en/*.txt')
334
475
 
335
476
    # built-in plugins
336
477
    plugins_files = []
 
478
    # XXX - should we consider having the concept of an 'official' build,
 
479
    # which hard-codes the list of plugins, gets more upset if modules are
 
480
    # missing, etc?
 
481
    plugins = None # will be a set after plugin sniffing...
337
482
    for root, dirs, files in os.walk('bzrlib/plugins'):
 
483
        if root == 'bzrlib/plugins':
 
484
            plugins = set(dirs)
338
485
        x = []
339
486
        for i in files:
340
 
            if not i.endswith('.py'):
 
487
            if os.path.splitext(i)[1] not in [".py", ".pyd", ".dll"]:
341
488
                continue
342
489
            if i == '__init__.py' and root == 'bzrlib/plugins':
343
490
                continue
351
498
    mf.run_package('bzrlib/plugins')
352
499
    packs, mods = mf.get_result()
353
500
    additional_packages.update(packs)
 
501
    includes.extend(mods)
 
502
 
 
503
    console_targets = [target,
 
504
                       'tools/win32/bzr_postinstall.py',
 
505
                       ]
 
506
    gui_targets = []
 
507
    com_targets = []
 
508
 
 
509
    if 'qbzr' in plugins:
 
510
        get_qbzr_py2exe_info(includes, excludes, packages)
 
511
 
 
512
    if "TBZR" in os.environ:
 
513
        # TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
 
514
        # TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
 
515
        # can be downloaded from (username=guest, blank password):
 
516
        # http://tortoisesvn.tigris.org/svn/tortoisesvn/TortoiseOverlays/version-1.0.4/bin/TortoiseOverlays-1.0.4.11886-win32.msi
 
517
        if not os.path.isfile(os.environ.get('TORTOISE_OVERLAYS_MSI_WIN32',
 
518
                                             '<nofile>')):
 
519
            raise RuntimeError("Please set TORTOISE_OVERLAYS_MSI_WIN32 to the"
 
520
                               " location of the Win32 TortoiseOverlays .msi"
 
521
                               " installer file")
 
522
        get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
 
523
                             gui_targets)
 
524
    else:
 
525
        # print this warning to stderr as output is redirected, so it is seen
 
526
        # at build time.  Also to stdout so it appears in the log
 
527
        for f in (sys.stderr, sys.stdout):
 
528
            print >> f, \
 
529
                "Skipping TBZR binaries - please set TBZR to a directory to enable"
354
530
 
355
531
    # MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
356
532
    # in on Vista.
 
533
    dll_excludes.append("MSWSOCK.dll")
357
534
    options_list = {"py2exe": {"packages": packages + list(additional_packages),
358
 
                               "includes": includes + mods,
359
 
                               "excludes": ["Tkinter", "medusa", "tools"],
360
 
                               "dll_excludes": ["MSWSOCK.dll"],
 
535
                               "includes": includes,
 
536
                               "excludes": excludes,
 
537
                               "dll_excludes": dll_excludes,
361
538
                               "dist_dir": "win32_bzr.exe",
 
539
                               "optimize": 1,
362
540
                              },
363
541
                   }
 
542
 
364
543
    setup(options=options_list,
365
 
          console=[target,
366
 
                   'tools/win32/bzr_postinstall.py',
367
 
                  ],
 
544
          console=console_targets,
 
545
          windows=gui_targets,
 
546
          com_server=com_targets,
368
547
          zipfile='lib/library.zip',
369
548
          data_files=topics_files + plugins_files,
 
549
          cmdclass={'install_data': install_data_with_bytecompile},
370
550
          )
371
551
 
372
552
else: