Commits

Ronald Oussoren  committed b553b8d

Add --force-system-tk option to py2app (issue #92)

This changeset adds an option '--force-system-tk' that will ensure
that _tkinter.so is linked to the system version of Tcl/Tk
(/System/Library/Frameworks/...) instead of some other framework.

Causes a build error when Tkinter is linked against a non-compatible
version (not a framework, or a framework version not present in
/System/Library/Frameworks).

Also remove duplicate definitions of a number of methods (!) and
remove a block of code that was disabled with 'if 0'.

Closes issue #92

  • Participants
  • Parent commits a005e84

Comments (0)

Files changed (2)

File doc/changelog.rst

 
 py2app 0.8 is a feature release
 
+- Issue #92: Add option '--force-system-tk' which ensures that the _tkinter
+  extension (used by Tkinter) is linked against the Apple build of Tcl/Tk,
+  even when it is linked to another framework in Python's std. library.
+
+  This will cause a build error when tkinter is linked with a major version of
+  Tcl/Tk that is not present in /System/Library/Frameworks.
+
 - Issue #80: Add support for copying system plugins into the application
   bundle.
- 
+
   Py2app now supports a new option *include_plugins*. The value of this
   is a list of paths to plugins that should be copied into the application
-  bundle. 
+  bundle.
 
   Items in the list are either paths, or a tuple with the plugin type
   and the path::
         ("SystemConfiguration", "MyPlugins/MyConfig.plugin"),
       ]
 
-  Py2app currently knows about the following plugin suffixes: 
-  ``.qlgenerator``, ``.mdimporter``, ``.xpc``, ``.service``, 
+  Py2app currently knows about the following plugin suffixes:
+  ``.qlgenerator``, ``.mdimporter``, ``.xpc``, ``.service``,
   ``.prefPane``, ``.iaplugin`` and ``.action``. These plugins
   can be added without specifying the plugin type.
 
 - Issue #83: Setup.py now refuses to install when the current
-  platform is not Mac OS X. 
-  
-  This makes it clear that the package is only supported on OSX and 
+  platform is not Mac OS X.
+
+  This makes it clear that the package is only supported on OSX and
   avoids confusing errors later on.
 
 - Issue #39: It is now possible to have subpackages on
 
 - Disabled the 'email' recipe for python 3.x as it isn't needed there.
 
-- Issue #91: Added a recipe for `lxml <http://lxml.de/>`, needed because 
+- Issue #91: Added a recipe for `lxml <http://lxml.de/>`, needed because
   lxml performs a number of imports from an extension and those cannot
   be detected automaticly by modulegraph.
 
   caused problems with Python 3.
 
 - Issue #81: Py2app now fails with an error when trying to build a bundle
-  for a unix-style shared library build of Python (``--enable-shared``) unless 
-  you are using a recent enough patchlevel of python (2.7.4, 3.2.3, 3.3.1, 
+  for a unix-style shared library build of Python (``--enable-shared``) unless
+  you are using a recent enough patchlevel of python (2.7.4, 3.2.3, 3.3.1,
   3.4.0, all of them are not released yet).
 
   The build failure was added to avoid a very confusing error when trying
-  to start the generated application due to a bug in the way python reads 
+  to start the generated application due to a bug in the way python reads
   the environment (for shared library builds on Mac OS X).
 
 - Py2app will also give an error message when the python binary does not
   symbolic name to the other).
 
 - Issue #88: Ensure that the fix for #65 won't try to create a symlink that
-  points to itself. This could for example occur with homebrew, where the 
+  points to itself. This could for example occur with homebrew, where the
   exposed lib directory contains symlinks to a cellar, while tye install_name
   does mention the "public" lib directory::
 
 py2app 0.7.2 is a bugfix release
 
 - Issue #75: Don't remove ``--dist-dir``, but only remove the old version
-  of the objects we're trying to build (if that exists). 
+  of the objects we're trying to build (if that exists).
 
   This once again makes it possible to have a number of setup.py files that
   build plugins into the same target folder (such as the plugins folder
   and prints an error message instead of building an application that doesn't
   work.
 
-  Issue: #39 
+  Issue: #39
 
 
 py2app 0.7.1
   'includes' list.
 
 - rewritten the recipe for matplotlib. The recipe no longer includes
-  the entire package, but just the "mpl-data" directory. 
+  the entire package, but just the "mpl-data" directory.
 
   WARNING: This recipe has had limited testing.
 
 - fix mixed indentation (tabs and spaces) in argv_emulation.py,
   which caused installation failures on python 3.x (issue #40)
-  
+
 - Issue #43: py2app now creates a symlink named "Current" in the
   'Versions' directory of the embedded Python framework to comply
   with a requirement for the Mac App-store.
 - Added option '--arch=VALUE' which can be used to select the set of
   architectures for the main executable. This defaults to the set of
   architectures supported by the python interpreter and can be used to
-  drop support for some architectures (for example when you're using a 
+  drop support for some architectures (for example when you're using a
   python binary that supports both 32-bit and 64-bit code and use a
   GUI library that does not yet work in 64-bit mode).
 
   (replace ``<PID>`` by the process ID of the current process).
 
 - When using the system python we now explicitly add Apple's additional packages
-  (like PyObjC and Twisted) to ``sys.path``. 
-  
+  (like PyObjC and Twisted) to ``sys.path``.
+
   This fixes and issue reported by Sean Robinson: py2app used to create a non-working
   bundle when you used these packages because the packages didn't get included
   (as intented), but were not available on ``sys.path`` either.
 
   As before the SIP recipe is rather crude, it will include *all* SIP-based
   packages into your application bundle when it detects a module that uses
-  SIP. 
+  SIP.
 
 - The 'Resources' folder is no longer on the python search path,
   it contains the scripts while Python modules and packages are located
 - Issue #23: py2app failed to work when an .egg directory was implictly added
   to ``sys.path`` by setuptools and the "-O" option was used (for example
   ``python setup.py py2app -O2``)
-  
+
 - Issue #26: py2app copied the wrong executable into the application bundle
   when using virtualenv with a framework build of Python.
 
 
   Report and fix by Erik van Zijst.
 
-- Ensure that the 'examples' directory is included in the source 
+- Ensure that the 'examples' directory is included in the source
   archive
 
 py2app 0.6.1
   workaround (the issue is fixed when the filename ends with '.zip').
 
 - The code that recreates the stub executables when they are
-  older than the source code now uses ``xcode-select`` to 
+  older than the source code now uses ``xcode-select`` to
   find the root of SDKs.
 
   This makes it possible to recreate these executables on machines
   stub executables, in particular not those that have support
   for the PPC architecture.
 
-- Don't rebuild the stub executables automaticly, that's 
+- Don't rebuild the stub executables automaticly, that's
   unsafe with Xcode 4 and could trigger accidently when
   files are installed in a different order than expected.
 
 Features:
 
 - it is now possible to specify which python distributions must
-  be availble when building the bundle by using the 
+  be availble when building the bundle by using the
   "install_requires" argument of the ``setup()`` function::
 
      setup(
   supported with python3 as well (patch by Virgil Dupras)
 
 - argv emulation doesn't work in python 3, this release
-  will tell you abou this instead of silently failing to 
+  will tell you abou this instead of silently failing to
   build a working bundle.
 
 - add support for custom URLs to the argv emulation code
-  (patch by Brendan Simon). 
-  
-  You will have to add a "CFBundleURLTypes" key to your Info.plist to 
+  (patch by Brendan Simon).
+
+  You will have to add a "CFBundleURLTypes" key to your Info.plist to
   use this, the argv emulation code will ensure that the URL
   to open will end up in ``sys.argv``.
 
 - Avoid copying the __pycache__ directory in python versions
   that implement PEP 3147 (Python 3.2 and later)
 
-- App bundles with Python 3 now work when the application is 
+- App bundles with Python 3 now work when the application is
   stored in a directory with non-ASCII characters in the full
   name.
 
   command subclasses)
 
 - The source distribution didn't include all files that needed to be
-  it ever since switching to mercurial, I've added a MANIFEST.in 
+  it ever since switching to mercurial, I've added a MANIFEST.in
   file rather than relying on setuptool's autoguessing of files to include.
 
 - Bundle template works again with semi-standalone builds (such as
   when using a system python), this rewrites the fix for issue #10
   mentioned earlier.
 
-- Ensure py2app works correctly when the sources are located in a 
+- Ensure py2app works correctly when the sources are located in a
   directory with non-ascii characters in its name.
 
 
 
 - Add support for various build flavours of Python (32bit, 3-way, ...)
 
-- py2app now actually works for me (ronaldoussoren@mac.com) with a 
+- py2app now actually works for me (ronaldoussoren@mac.com) with a
   python interpreter in a virtualenv environment.
 
 - Experimental support for python 3
 
 - Use modern API's in the alias-build bootstrap code, without
   this 'py2app -A' will result in broken bundles on a 64-bit build
-  of Python. 
+  of Python.
   (Patch contributed by James R Eagan)
 
 - Try both 'import Image' and 'from PIL import Image' in the PIL
 
 Features:
 
-- When the '--strip' option is specified we now also remove '.dSYM' 
+- When the '--strip' option is specified we now also remove '.dSYM'
   directories from the bundle.
 
 - Remove dependency on a 'version.plist' file in the python framework
 
 - A new recipe for `PyQt`_ 4.x. This recipe was donated by Kevin Walzer.
 
-- A new recipe for `virtualenv`_, this allows you to use py2app from 
+- A new recipe for `virtualenv`_, this allows you to use py2app from
   a virtual environment.
 
 .. _`virtualenv`: http://pypi.python.org/pypi/virtualenv
 - Adds support for converting ``.xib`` files (NIB files for
   Interface Builder 3)
 
-- Introduces an experimental plugin API for data converters. 
+- Introduces an experimental plugin API for data converters.
 
   A conversion plugin should be defined as an entry-point in the
   ``py2app.converter`` group::
 
 Buf fixes:
 
-- This fixes an issue with copying a different version of Python over 
+- This fixes an issue with copying a different version of Python over
   to an app/plugin bundle than the one used to run py2app with.
 
 
 - Support for CoreData mapping models (introduced in Mac OS X 10.5)
 
 - Support for python packages that are stored in zipfiles (such as ``zip_safe``
-  python eggs). 
+  python eggs).
 
 Bug fixes:
 
   etc.
 
 - An embedded Python interpreter is now included in the executable
-  bundle (``sys.executable`` points to it), this currently only 
+  bundle (``sys.executable`` points to it), this currently only
   works for framework builds of Python
 
 - New ``macho_standalone`` tool
 py2app 0.1.6
 ------------
 
-Since I have been slacking and the last announcement was for 0.1.4, here are the 
+Since I have been slacking and the last announcement was for 0.1.4, here are the
 changes for the soft-launched releases 0.1.5 and 0.1.6:
 
 `py2app`_ 0.1.6 was a major feature enhancements release:
 
 `py2app`_ 0.1.5 is a major feature enhancements release:
 
-- Added a ``bdist_mpkg`` distutils extension, for creating Installer 
+- Added a ``bdist_mpkg`` distutils extension, for creating Installer
   an metapackage from any distutils script.
 
   - Includes PackageInstaller tool
 - Should now correctly handle paths (and application names) with unicode characters
   in them.
 
-- New ``--strip`` option for ``py2app`` build command, strips all Mach-O files 
+- New ``--strip`` option for ``py2app`` build command, strips all Mach-O files
   in output application bundle.
 
 - New ``--bdist-base=`` option for ``py2app`` build command, allows an alternate
 
 `py2app`_ 0.1.4 is a minor bugfix release:
 
-- The ``altgraph`` from 0.1.3 had a pretty nasty bug in it that prevented 
+- The ``altgraph`` from 0.1.3 had a pretty nasty bug in it that prevented
   filtering from working properly, so I fixed it and bumped to 0.1.4.
 
 py2app 0.1.3
 - Fixed a bug that may have been in 0.1.2 where explicitly included packages
   would not be scanned by ``macholib``
 
-- ``py2app.apptemplate`` now contains a stripped down ``site`` module as 
+- ``py2app.apptemplate`` now contains a stripped down ``site`` module as
   opposed to a ``sitecustomize``
 
-- Alias builds are now the only ones that contain the system and user 
+- Alias builds are now the only ones that contain the system and user
   ``site-packages`` directory in ``sys.path``
 
 - The ``pydoc`` recipe has been beefed up to also exclude ``BaseHTTPServer``,
 - The ``Command`` instance is now passed to recipes instead of the
   ``Distribution`` instance (though no recipes currently use either)
 
-- The post-filtering of modules and extensions is now generalized into a 
+- The post-filtering of modules and extensions is now generalized into a
   stack and can be modified by recipes
 
-- A `wxPython`_ example demonstrating how to package `wxGlade`_ has been 
+- A `wxPython`_ example demonstrating how to package `wxGlade`_ has been
   added (this is a good example of how to write your own recipe, and how to
   deal with complex applications that mix code and data files)
 
 - ``PyRuntimeLocations`` is now set to (only) the location of the current
-  interpreter's ``Python.framework`` for alias and semi-standalone build 
+  interpreter's ``Python.framework`` for alias and semi-standalone build
   modes (enhances compatibility with extensions built with an unpatched
   Makefile with Mac OS X 10.3's Python 2.3.0)
 
 
 `py2app`_ 0.1.1 is primarily a bugfix release:
 
-- Several problems related to Mac OS X 10.2 compatibility and standalone 
+- Several problems related to Mac OS X 10.2 compatibility and standalone
    building have been resolved
 
 - Scripts that are not in the same directory as setup.py now work
 
 - A recipe has been added for `py2app`_ itself
 
-- a `wxPython`_ example (superdoodle) has been added.  
-  Demonstrates not only how easy it is (finally!) to bundle 
-  `wxPython`_ applications, but also how one setup.py can 
+- a `wxPython`_ example (superdoodle) has been added.
+  Demonstrates not only how easy it is (finally!) to bundle
+  `wxPython`_ applications, but also how one setup.py can
   deal with both `py2exe`_ and `py2app`_.
 
-- A new experimental tool, py2applet, has been added.  
+- A new experimental tool, py2applet, has been added.
   Once you've built it (``python setup.py py2app``, of course), you should
   be able to build simple applications simply by dragging your main script
   and optionally any packages, data files, Info.plist and icon it needs.
 Known issues:
 
 - Includes *all* files from packages, it should be smart enough to strip
-  unused .py/.pyc/.pyo files (to save space, depending on which 
+  unused .py/.pyc/.pyo files (to save space, depending on which
   optimization flag is used).
 
 - The default ``PyRuntimeLocations`` can cause problems on machines that
   have a /Library/Frameworks/Python.framework installed.  Workaround is
-  to set a plist that has the following key: 
+  to set a plist that has the following key:
   ``PyRuntimeLocations=['/System/Library/Frameworks/Python.framework/Versions/2.3/Python']``
   (this will be resolved soon)
 

File py2app/build_app.py

 
 import macholib.dyld
 import macholib.MachOStandalone
+import macholib.MachO
+from macholib.util import flipwritable
 
 from py2app.create_appbundle import create_appbundle
 from py2app.create_pluginbundle import create_pluginbundle
 except NameError:
     basestring = str
 
+def rewrite_tkinter_load_commands(tkinter_path):
+    print("rewrite_tk", tkinter_path)
+    m = macholib.MachO.MachO(tkinter_path)
+    tcl_path = None
+    tk_path = None
+
+    rewrite_map = {}
+
+    for header in m.headers:
+        for idx, name, other in header.walkRelocatables():
+            if other.endswith('/Tk'):
+                if tk_path is not None and other != tk_path:
+                    raise DistutilsPlatformError('_tkinter is linked to different Tk paths')
+                tk_path = other
+            elif other.endswith('/Tcl'):
+                if tcl_path is not None and other != tcl_path:
+                    raise DistutilsPlatformError('_tkinter is linked to different Tcl paths')
+                tcl_path = other
+
+    if tcl_path is None or 'Tcl.framework' not in tcl_path:
+        raise DistutilsPlatformError('_tkinter is not linked a Tcl.framework')
+
+    if tk_path is None or 'Tk.framework' not in tk_path:
+        raise DistutilsPlatformError('_tkinter is not linked a Tk.framework')
+
+    system_tcl_versions = [nm for nm in os.listdir('/System/Library/Frameworks/Tcl.framework/Versions') if nm != 'Current']
+    system_tk_versions = [nm for nm in os.listdir('/System/Library/Frameworks/Tk.framework/Versions') if nm != 'Current']
+
+    if not tcl_path.startswith('/System/Library/Frameworks'):
+        # ../Versions/8.5/Tcl
+        ver = os.path.basename(os.path.dirname(tcl_path))
+        if ver not in system_tcl_versions:
+            raise DistutilsPlatformError('_tkinter is linked to a version of Tcl not in /System')
+
+        rewrite_map[tcl_path] = '/System/Library/Frameworks/Tcl.framework/Versions/%s/Tcl'%(ver,)
+
+    if not tk_path.startswith('/System/Library/Frameworks'):
+        # ../Versions/8.5/Tk
+        ver = os.path.basename(os.path.dirname(tk_path))
+        if ver not in system_tk_versions:
+            raise DistutilsPlatformError('_tkinter is linked to a version of Tk not in /System')
+
+        rewrite_map[tk_path] = '/System/Library/Frameworks/Tk.framework/Versions/%s/Tk'%(ver,)
+
+    if rewrite_map:
+        print("Relinking _tkinter.so to system Tcl/Tk")
+        rewroteAny = False
+        for header in m.headers:
+            for idx, name, other in header.walkRelocatables():
+                data = rewrite_map.get(other)
+                if data:
+                    if header.rewriteDataForCommand(idx, data.encode(sys.getfilesystemencoding())):
+                        rewroteAny = True
+
+        if rewroteAny:
+            old_mode = flipwritable(m.filename)
+            try:
+                with open(m.filename, 'rb+') as f:
+                    for header in m.headers:
+                        f.seek(0)
+                        header.write(f)
+                        f.seek(0, 2)
+                        f.flush()
+
+            finally:
+                flipwritable(m.filename, old_mode)
+
+    else:
+        print("_tkinter already linked against system Tcl/Tk")
+
 
 def get_zipfile(dist, semi_standalone=False):
     if sys.version_info[0] == 3:
 
             # Ensure that the orginal name also exists, avoids problems when
             # the filename is used from Python (see issue #65)
-            # 
-            # NOTE: The if statement checks that the target link won't 
+            #
+            # NOTE: The if statement checks that the target link won't
             #       point to itself, needed for systems like homebrew that
             #       store symlinks in "public" locations that point to
             #       files of the same name in a per-package install location.
         ("matplotlib-backends=", None, "set of matplotlib backends to include (default: include entire package)"),
         ("extra-scripts=", None, "set of scripts to include in the application bundle, next to the main application script"),
         ("include-plugins=", None, "List of plugins to include"),
+        ("force-system-tk", None, "Ensure that Tkinter is linked against Apple's build of Tcl/Tk"),
         ]
 
     boolean_options = [
         "graph",
         "prefer-ppc",
         "emulate-shell-environment",
+        "force-system-tk",
     ]
 
     def initialize_options (self):
         self.matplotlib_backends = None
         self.extra_scripts = None
         self.include_plugins = None
+        self.force_system_tk = False
 
     def finalize_options (self):
         if not self.strip:
                 raise DistutilsPlatformError("This python does not have a shared library or framework")
 
             else:
-                # Issue .. in py2app's tracker, and issue .. in python's tracker: a unix-style shared 
+                # Issue .. in py2app's tracker, and issue .. in python's tracker: a unix-style shared
                 # library build did not read the application environment correctly. The collection of
                 # if statements below gives a clean error message when py2app is started, instead of
                 # building a bundle that will give a confusing error message when started.
 
     def build_xref(self, mf, flatpackages):
         for target in self.targets:
-            base = target.get_dest_base()
-            appdir = os.path.join(self.dist_dir, os.path.dirname(base))
+            appdir = target.appdir
             appname = self.get_appname()
             dgraph = os.path.join(appdir, appname + '.html')
             print("*** creating dependency html: %s ***"
 
                 else:
                     self.copy_file(sys.executable, execdst)
+
             if not self.debug_skip_macholib:
+                if self.force_system_tk:
+                    print("force system tk")
+                    resdir = os.path.join(dst, 'Contents', 'Resources')
+                    pydir = os.path.join(resdir, 'lib', 'python%s.%s'%(sys.version_info[:2]))
+                    ext_dir = os.path.join(pydir, os.path.basename(self.ext_dir))
+                    tkinter_path = os.path.join(ext_dir, '_tkinter.so')
+                    if os.path.exists(tkinter_path):
+                        rewrite_tkinter_load_commands(tkinter_path)
+                    else:
+                        print("tkinter not found at", tkinter_path)
+
+
                 mm = PythonStandalone(self, dst, executable_path=exp)
                 dylib, runtime = self.get_runtime()
                 if self.semi_standalone:
         target.appdir = appdir
         return appdir
 
-
-    def build_executable(self, target, arcname, pkgexts, copyexts, script, extra_scripts):
-        # Build an executable for the target
-        appdir, resdir, plist = self.create_bundle(target, script)
-        self.appdir = appdir
-        self.resdir = resdir
-        self.plist = plist
-
-        for fn in extra_scripts:
-            if fn.endswith('.py'):
-                fn = fn[:-3]
-            elif fn.endswith('.pyw'):
-                fn = fn[:-4]
-
-            src_fn = script_executable(arch=self.arch)
-            tgt_fn = os.path.join(self.appdir, 'Contents', 'MacOS', os.path.basename(fn))
-            mergecopy(src_fn, tgt_fn)
-            make_exec(tgt_fn)
-
-
-        site_path = os.path.join(resdir, 'site.py')
-        byte_compile([
-            SourceModule('site', site_path),
-            ],
-            target_dir=resdir,
-            optimize=self.optimize,
-            force=self.force,
-            verbose=self.verbose,
-            dry_run=self.dry_run)
-        if not self.dry_run:
-            os.unlink(site_path)
-
-
-        includedir = None
-        configdir = None
-        if sysconfig is not None:
-            includedir = sysconfig.get_config_var('CONFINCLUDEPY')
-            configdir = sysconfig.get_config_var('LIBPL')
-
-
-        if includedir is None:
-            includedir = 'python%d.%d'%(sys.version_info[:2])
-        else:
-            includedir = os.path.basename(includedir)
-
-        if configdir is None:
-            configdir = 'config'
-        else:
-            configdir = os.path.basename(configdir)
-
-        self.compile_datamodels(resdir)
-        self.compile_mappingmodels(resdir)
-
-        bootfn = '__boot__'
-        bootfile = open(os.path.join(resdir, bootfn + '.py'), 'w')
-        for fn in target.prescripts:
-            bootfile.write(self.get_bootstrap_data(fn))
-            bootfile.write('\n\n')
-
-        bootfile.write("DEFAULT_SCRIPT=%r\n"%(os.path.basename(script),))
-        bootfile.write('try:\n')
-        bootfile.write('    _run()\n' % os.path.realpath(script))
-        bootfile.write('except KeyboardInterrupt:\n')
-        bootfile.write('    pass\n')
-        bootfile.close()
-
-        target.appdir = appdir
-        return appdir
-
-    def build_executable(self, target, arcname, pkgexts, copyexts, script, extra_scripts):
-        # Build an executable for the target
-        appdir, resdir, plist = self.create_bundle(target, script)
-        self.appdir = appdir
-        self.resdir = resdir
-        self.plist = plist
-
-        for fn in extra_scripts:
-            if fn.endswith('.py'):
-                fn = fn[:-3]
-            elif fn.endswith('.pyw'):
-                fn = fn[:-4]
-
-            src_fn = script_executable(arch=self.arch)
-            tgt_fn = os.path.join(self.appdir, 'Contents', 'MacOS', os.path.basename(fn))
-            mergecopy(src_fn, tgt_fn)
-            make_exec(tgt_fn)
-
-
-        site_path = os.path.join(resdir, 'site.py')
-        byte_compile([
-            SourceModule('site', site_path),
-            ],
-            target_dir=resdir,
-            optimize=self.optimize,
-            force=self.force,
-            verbose=self.verbose,
-            dry_run=self.dry_run)
-        if not self.dry_run:
-            os.unlink(site_path)
-
-
-        includedir = None
-        configdir = None
-        if sysconfig is not None:
-            includedir = sysconfig.get_config_var('CONFINCLUDEPY')
-            configdir = sysconfig.get_config_var('LIBPL')
-
-
-        if includedir is None:
-            includedir = 'python%d.%d'%(sys.version_info[:2])
-        else:
-            includedir = os.path.basename(includedir)
-
-        if configdir is None:
-            configdir = 'config'
-        else:
-            configdir = os.path.basename(configdir)
-
-        self.compile_datamodels(resdir)
-        self.compile_mappingmodels(resdir)
-
-        bootfn = '__boot__'
-        bootfile = open(os.path.join(resdir, bootfn + '.py'), 'w')
-        for fn in target.prescripts:
-            bootfile.write(self.get_bootstrap_data(fn))
-            bootfile.write('\n\n')
-
-        bootfile.write("DEFAULT_SCRIPT=%r\n"%(os.path.basename(script),))
-        bootfile.write('try:\n')
-        bootfile.write('    _run()\n' % os.path.realpath(script))
-        bootfile.write('except KeyboardInterrupt:\n')
-        bootfile.write('    pass\n')
-        bootfile.close()
-
-        target.appdir = appdir
-        return appdir
-
     def build_executable(self, target, arcname, pkgexts, copyexts, script, extra_scripts):
         # Build an executable for the target
         appdir, resdir, plist = self.create_bundle(target, script)
         realhome = os.path.join(sys.prefix, 'lib', 'python' + sys.version[:3])
         self.mkpath(pydir)
 
-        # The site.py file needs to be a two locations 
+        # The site.py file needs to be a two locations
         # 1) in lib/pythonX.Y, to be found during normal startup and
         #    by the 'python' executable
-        # 2) in the resources directory next to the script for 
+        # 2) in the resources directory next to the script for
         #    semistandalone builds (the lib/pythonX.Y directory is too
         #    late on sys.path to be found in that case).
         #
             self.mkpath(os.path.dirname(fn))
             copy_file(copyext.filename, fn, dry_run=self.dry_run)
 
-        if 0 and sys.version_info[:2] >= (3, 2) and not self.alias:
-            import encodings
-            import encodings.cp437
-            import encodings.utf_8
-            import encodings.latin_1
-            import codecs
-
-            encodings_dir = os.path.join(pydir, 'encodings')
-            self.mkpath(encodings_dir)
-
-            byte_compile([
-                    SourceModule('encodings.__init__', encodings.__file__),
-                    SourceModule('encodings.cp437', encodings.cp437.__file__),
-                    SourceModule('encodings.utf_8', encodings.utf_8.__file__),
-                    SourceModule('encodings.latin_1', encodings.latin_1.__file__),
-                    SourceModule('codecs', codecs.__file__),
-                ],
-                target_dir=pydir,
-                optimize=self.optimize,
-                force=self.force,
-                verbose=self.verbose,
-                dry_run=self.dry_run)
-
-            if not self.dry_run:
-                fp = open(os.path.join(encodings_dir, 'aliases.py'), 'w')
-                fp.write('aliases = {}\n')
-                fp.close()
-
         for src, dest in self.iter_data_files():
             dest = os.path.join(resdir, dest)
             if src == dest: