开发者

Tracing interconnected Python executables on OS X

I have a rather long setup, then three questions at the end. On OS X, the System Python framework contains three executables (let me give them short names):

> F=/System/Library/Frameworks/Python.framework/Versions/2.6
> A=$F/bin/python2.6
> B=$F/Resources/Python.app/Contents/MacOS/Python
> C=$F/Python

$A and $B are clearly too small to be Python itself.

> ls -s $A; ls -s $B; ls -s $C
16 /System/Library/Frameworks/Python.framework/Versions/2.6/bin/python2.6
16 /System/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python
3152 /System/Library/Frameworks/Python.framework/Versions/2.6/Python

> $A
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) 
> $B
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) 
> $C
-bash: /System/Library/Frameworks/Python.framework/Versions/2.6/Python: cannot execute binary file

Despite equal size and apparently, effect, the first two are different, e.g.:

> cmp -lc $A $B

Also, in /usr/bin, python2.6 is a symlink to $C, but there is also:

> D=/usr/bin/python
> ls -s $D
48 /usr/bin/python

I want to sort out how these are connected; the command which doesn't help.

> export DYLD_PRINT_LIBRARIES=1
> $A
..
dyld: loaded: /System/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python
dyld: loaded: /System/Library/Frameworks/Python.framework/Versions/2.6/Python

Summary: $A loads $B followed by $C; $B loads $C; $D loads $B followed by $C

So my question开发者_Python百科s are:

  1. Is this documented anywhere?
  2. What roles do these play?
  3. Most important, what tools would be useful in tracing connections like this?


The Apple-supplied Pythons in OS X 10.6 are built and installed using the standard Python framework build option, with a few customization tweaks. It is not in Apple's documentation because the specific layout is not an Apple invention; it has evolved over the years by the Python project using other OS X framework layouts as a starting point. If you install a version of Python on OS X using one of the python.org installers, say from here, you will see the same pattern, with the framework rooted at /Library/Frameworks/ rather than /System/Library/Frameworks. So, if you are really curious, you can download the source and look at the configure script and Makefile templates. It can be heavy reading, though. Apple also makes available here the source used to build open source components, including Python, in each OS X release along with the customization patches so, in theory, you can see exactly how Apple built what it released.

That said, to address your questions, in Python 2.6:

$A is the pythonw wrapper that ensures Python is recognized as a GUI application by OS X (see the source of pythonw.c here). Note, the Apple version of pythonw has been customized to add the preferred execution modes (see Apple's man 1 python). A somewhat different approach to this is provided in the upstream source of newer versions of Python (2.7 and 3.2).

$B is the actual executable of the Python interpreter. It is what is execed by the pythonw executable, $A. You should be able to easily verify that by actually running Python and looking at the value of sys.executable but there is a bug with the Apple-supplied Python 2.6 (probably due to the added feature mentioned above) that causes the wrong value to be assigned to it. The python.org Python 2.6.6 shows the correct value:

$ cd /Library/Frameworks/Python.framework/Versions/2.6
$ ./bin/python2.6 -c 'import sys;print(sys.executable)'
/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python`

$C is the shared library containing all of the interpreter's loadable modules. You can see that by using otool on $B:

$ cd /System/Library/Frameworks/Python.framework/Versions/2.6
$ cd Resources/Python.app/Contents/MacOS/
$ otool -L ./Python
Python:
   /System/Library/Frameworks/Python.framework/Versions/2.6/Python (compatibility version 2.6.0, current version 2.6.1)
   /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)


The tools to use are ls and file.

ls -l will give what the symbolic link goes to. The size of a symbolic link is the number of chafracters in the path it points to.

file x will give the type of the file

e.g.

file /System/Library/Frameworks/Python.framework/Versions/2.6/Python  
/System/Library/Frameworks/Python.framework/Versions/2.6/Python: Mach-O universal binary with 3 architectures  
/System/Library/Frameworks/Python.framework/Versions/2.6/Python (for architecture x86_64):      Mach-O 64-bit dynamically linked shared library x86_64  
/System/Library/Frameworks/Python.framework/Versions/2.6/Python (for architecture i386):        Mach-O dynamically linked shared library i386  
/System/Library/Frameworks/Python.framework/Versions/2.6/Python (for architecture ppc7400):     Mach-O dynamically linked shared library ppc  

OSX Frameworks are described in Apple developer docs

/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python and /System/Library/Frameworks/Python.framework/Versions/2.6/bin/python2.6 are the actual python interpreter, I think they are hard links to the same binary.

/usr/bin/python is the python on the path - I think it is hard linked to /usr/bin/pythonw. These are wrappers that call exec to the real python interpreter in /System/Library/Frameworks/Python.framework/Versions/2.6/bin/python2.6 see python bug tracker

/System/Library/Frameworks/Python.framework/Versions/Current is a symlink to System/Library/Frameworks/Python.framework/Versions/2.6 using the standard OSX Framework versioning

/System/Library/Frameworks/Python.framework/Versions/2.6/Python is the shared library that does all the work - set up as a library so that you can write programs in other languages that can embed a python interpreter.

For other details look at Python docs but I suspect you would have to search the apple python mailing list

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜