Re: [Pyobjc-dev] execing /usr/bin/python
Brought to you by:
ronaldoussoren
From: Jack J. <Jac...@or...> - 2002-11-01 12:05:17
|
> - The python sources are copied to the Resources directory of > the application > > Do we have any control over this? I'd like to be able to convert the > sources to bytecode (slightly faster startup, and this makes it harder > to change the code). Please have a look at BuildApplication (and the underlying freeze modules), so you don't go reinventing the wheel. BuildApplication first recursively collects all modules used by a script, then byte-compiles these and then stuffs them into OS9 resources. The last step needs to be modified for OSX, but the first step (which is basically shared with freeze) can definitely be used. This is on my todo list, but it's fairly far down, so feel free to beat me to it. On vrijdag, nov 1, 2002, at 03:53 Europe/Amsterdam, bb...@ma... wrote: > On Thursday, October 31, 2002, at 04:42 PM, Ronald Oussoren wrote: >> On Thursday, Oct 31, 2002, at 14:20 Europe/Amsterdam, bb...@ma... >> wrote: >>>> 2. If not, how could this be implemented? >>> >>> It is is implemented by: >> - The python sources are copied to the Resources directory of >> the application >> >> Do we have any control over this? I'd like to be able to convert the >> sources to bytecode (slightly faster startup, and this makes it >> harder to change the code). > > Sure. > > - Add a new shell script build phase to your project > > - check off the 'Run only when installing' checkbox > > - set the script to the command necessary to compile the python code > [see the PBX docs for what variables are available, etc...] > > The alternative is to do a new target of type legacy makefile, then > create another target named packaging and add both the app target and > the legacy target to packaging. The legacy target could be used to > compile all py files upon installation. This is how the Web Services > Tool project works -- if you 'pbxbuild install -target Packaging', it > uses a legacy makefile target to copy the readme and license to the > destination directory. With the addition of a script written by Mike > Trent and I, the whole thing can be automatically shoved onto a Disk > Image automatically. > >>> - using a series of copy file phases to copy the PyObjC module >>> into the 'pyobjc' subdirectory of the Resources directory of the >>> application when the 'install' target is used ('pbxbuild install' >>> from the command line). >>> >>> - the main.m uses execve() to transfer control to >>> /usr/bin/python and exec Main.py in a fashion where OS X thinks that >>> /usr/bin/python is the executable within the app wrapper (otherwise, >>> mainBundle breaks). Unfortunately, this is what breaks gdb. >>> Fortunately, this will go away when Apple ships a new build of >>> Python that includes a library for embedding. >> In a conversation about an 'addon-for-Apple-python' version of >> MacPython I mentioned this technique to Jack Jansen (the MacPython >> maintainer). He intends to use a slightly different technique: The >> wrapper does not use execve() /usr/bin/python, but a python binary(*) >> in the Contents/MacOS directory of the .app with and argv[0] that >> actually points to this python binary. The reason for this variation >> is that this would make 'sys.executable' point to a python >> interpreter and appearantly some existing code expects this >> (including the Python testsuite). We didn't know if the APIs that >> require a full path to the application in argv[0] would mind that >> argv[0] is not the name of the binary mentioned in the Info.plist. > > That'll work though the current use of execve() has a distinct > advantage (and, in reality, calling execve to transfer control to the > python interpreter adds very little overhead). > > The advantage to the current method is that the binary contained in > the app wrapper can be linked against all the frameworks that should > be loaded into the python interpreter environment; including any > frameworks specifically built for the project. The main that is in > Web Services Tool and-- now-- the Project Template passes the set of > frameworks linked into the app wrapper's executable into the execution > of the python binary as an argument. This argument is picked up by > Main.py and it automatically dynamically loads all of the frameworks > and executes an Init.py in each, if present. > > In other words, the app wrapper automatically bootstraps the python > environment with all of the frameworks that would normally be linked > directly into the application -- the developer doesn't have to do > anything to cause these frameworks to be loaded. I think there's a misunderstanding somewhere in the me->ronald->bill conversation, as I don't see why Bill's method would be different from mine. In other words, please explain if there is... Here's my scheme, with an example: /Applications/foo.app/Contents/MacOS/foo looks for __main__.py in Resources, and does execve("/Applications/foo.app/Contents/MacOS/python", ["/Applications/foo.app/Contents/MacOS/python", "/Applications/foo.app/Contents/Resources/__main__.py", rest of original argv]) and Contents/MacOS/python is a symlink to /usr/bin/python. I would think this works the same as Bills scheme, with the only exception that sys.executable points to a python interpreter, so something like system(sys.executable + " myscript.py") will work. -- - Jack Jansen <Jac...@or...> http://www.cwi.nl/~jack - - If I can't dance I don't want to be part of your revolution -- Emma Goldman - |