How to install Python 2.7.x independently of /Syst

2019-04-16 01:26发布

问题:

Is there a way to build and install Python 2.7.x so that it has no direct dependency whatsoever on anything under /System/Library/Frameworks? (IOW, such Python should remain functional even after sudo chmod 000 /System/Library/Frameworks.)

I thought it would be enough to omit the --enable-framework flag at the time of running ./configure, but I was wrong: if I do this the resulting Python still has plenty of dependencies to frameworks under /System/Library/Frameworks, including, of course, /System/Library/Frameworks/Python.framework. (IOW, one has to wonder if there's any difference between installing with and without selecting --enable-framework.)

回答1:

Yes, --enable-framework makes a difference when building and installing Python. Without --enable-framework, Python is built as a conventional "unix-style" build by default installed to /usr/local/ but that can be changed with the --prefix= option to ./configure. --enable-framework builds a Python that, by default, is installed into /Library/Frameworks, although that can be changed by specifying another path to --enable-framework. But any Python build will be dependent on other libraries and frameworks provided by the operating system. This is normal. Why are you concerned about it?

Update: It's easy to avoid using the Apple-supplied system Pythons, e.g. those which are in /usr/bin and whose shared components are in /System/Library/Frameworks/Python.frameworks, just by installing another Python 2.7 and not using /usr/bin/python2.7. But that doesn't mean you should or can avoid using other system frameworks.

That said, there is one known problematic Apple-supplied framework in OS X 10.6 through 10.8 that is used by Python: that is Tk 8.5, used by Python Tkinter applications including IDLE. Fortunately, it is pretty easy to work around that. Like Python, you can install a newer, third-party version of the Tcl 8.5 and Tk 8.5 frameworks into /Library/Frameworks and some Python distributions, like the binary installers from python.org, will use them. We recommend the ActiveTcl distribution if you are able to use it. See http://www.python.org/download/mac/tcltk/ for more information.

Also, be aware that you need to install separate versions of Distribute (or setuptools), pip (if you use it), and/or virtualenv for each instance of Python you have. Don't fall into the trap of using the Apple-supplied easy_install commands in /usr/bin/ which are for the system Pythons.

Further update: With the further refinement

avoid all the stuff under /S/L/F/Python.framework". I already tried something like what you describe, but the resulting installation still depends on stuff under /S/L/F/Python.framework

all I can do is reiterate that building your own Python, be it a "unix" build, a "shared" build, or a "framework" build, the resultant Python should be totally independent of anything in /System/Library/Frameworks/Python.framework. If not, something went wrong in the build or in how you are executing Python. More details would be needed to determine what is going wrong, at a minimum something like:

/path/to/your/python -c "import sys, pprint; print(sys.version); print(sys.executable); pprint.pprint(sys.path)"

If you built the Python, we'd need to see the complete configure and make commands. But that would be getting into localized debugging not really appropriate for StackOverflow.

Last (!) update: In a framework build, the --enable-framework=/path/to option to configure uses that "prefix" as the install "prefix" location for the framework and two auxiliary directories if you stick to using paths that end in Library/Frameworks. So, if you used:

./configure --enable-framework=/baz/quux/Library/Frameworks && make && make install

it should result in:

/baz
    quux
        Applications
            Python 2.7
                Build Applet.app
                IDLE.app
                ...
        Library
            Frameworks
                Python
                    Version
                        2.7
                            Headers/
                            Python
                            ...
                            Resources/
                            bin
                                ...
                                2to3
                                idle2.7
                                ...
                                python
                                python2
                                python2.7
                                ...
                            include/
                            lib/
                            share/
        bin
            2to3 -> ...bin/2to3
            ...
            idle2.7 -> ...bin/idle2.7
            ...
            python -> ...bin/python
            ...

The top-level bin directory is somewhat vestigial and really just confuses matters. It contains symlinks to the executables in the framework bin directory. It's what gets installed in /usr/local/bin by a default framework build. One problem with using it is that Distutils-installed scripts will, by default, get installed to the framework bin directory and there won't be an alias for them in the top-level directory. That's why it is recommended that you put the framework bin directory at the head of your shell PATH and just ignore the top-level bin.

If --prefix=/foo/bar is added to the previous configure, it will use the prefix path as the root for the vestigial top-level bin directory. In the above example, that top-level bin directory would be installed instead at:

/foo
    bar
        bin
            2to3 -> ...bin/2to3
            ...
            idle2.7 -> ...bin/idle2.7
            ...
            python -> ...bin/python
            ...

Otherwise, it should have no effect.