Thread: [Pyobjc-dev] buildapplication strawman
Brought to you by:
ronaldoussoren
From: Just v. R. <ju...@le...> - 2002-11-17 20:44:57
Attachments:
buildapp.py
|
I've attached a small and very quickly hacked up script that will build an applet for the TableModel demo (the original, not #2). Drop it in that folder and run it from the command line. What it does is create a bunch of folders, copies a bunch of files, and poof, there's an app. It basically does the same thing as Ronalds setup-app.py script, except it doesn't depend in (MacPython's) buildtools.py, which in turn depends on some Mac-specific modules not available in the Apple-shipped Python 2.2. I'd like to turn it into a module, refactored in a nicely extensible way. The next step would be to plug in freeze's module finder and (optionally) copy all modules the main program depends on to Contents/Resources as well. An interesting middle way might be to _only_ copy those modules that are not shipped by Apple (ie. only everything in site-packages and sys.path entries not enclosed in sys.prefix + "/lib/python<version>/"). It could in theory be a distutils extension, but I'm not sure that buys us much: it only needs to copy files and compile .py files into .pyc (it doesn't do the latter yet, though). On the other hand: py2exe is a distutils extension, and that works wonderfully (it builds standalone Windows executables). Comments? Just |
From: Jack J. <Jac...@or...> - 2002-11-17 21:53:07
|
On zondag, nov 17, 2002, at 21:44 Europe/Amsterdam, Just van Rossum wrote: > I'd like to turn it into a module, refactored in a nicely extensible > way. Your code appears to be a modified version of Mac/script/buildappbundle.py, or is the similarity a coincidence? Anyway, my plan was to put the buildappbundle functionality into Mac/Lib/buildtools.py when I find the time for it. Putting your buildapp functionality in there as well should be a minor task. And then the code should be factored into an OS9-only bit (which would have all the MacPython-specific stuff dealing with opening resource forks and such) that wouldn't be imported if we're on OSX. > The > next step would be to plug in freeze's module finder and (optionally) > copy all > modules the main program depends on to Contents/Resources as well. An > interesting middle way might be to _only_ copy those modules that are > not > shipped by Apple (ie. only everything in site-packages and sys.path > entries not > enclosed in sys.prefix + "/lib/python<version>/"). Great minds think alike:-) I was just thinking the same thing when cycling home today: freeze's module finder should get an optional argument that would make it skip any modules in the standard python distribution. This is fairly simple: any sys.path entry that starts with sys.prefix or sys.exec_prefix except for site-packages could be considered the standard distribution. -- - 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 - |
From: Just v. R. <ju...@le...> - 2002-11-17 22:28:15
|
Jack Jansen wrote: > Your code appears to be a modified version of > Mac/script/buildappbundle.py, or is the similarity a coincidence? Heh, I hadn't seen that one! D'oh. I only saw the bundle support in buildtools.py which I didn't like all that much. I'll have a closer look at yours later, and think about how to develop it further. I definitely think it should be a module, not just a script. Any thoughts about whether to use distutils or not? (I remember we both once wrote a CFM module without knowing it of each other, and at some point I couldn't tell anymore who wrote which one...) Just |
From: Just v. R. <ju...@le...> - 2002-11-17 23:47:19
|
Jack Jansen wrote: > Mac/script/buildappbundle.py Ok, I've had a closer look at it: great! Mind if I take a hack at it? I would like to move it to Mac/Lib/ though. It it used much? Would people likely get upset if I change the (function) interface? A few comments. - I would not let people specify a nib by path, but by name, defaulting to "MainMenu". The .lproj or individual nibs should then be listed as a resource. - I don't care much for the command line interface: I think people should just write a setup.py-like script. I wouldn't rip main() out, but I wouldn't want to spend much time on it. - I think it's good if it (by default) would build the app in a build/ subdir, like distutils and PB. Further things I'd like to do: - Change it to use the os.execve() trick. - I would like to add a debug or "developer" option: instead of copying the files/folders it would put symlinks inside the bundle. That way it's easy to keep on hacking on any file without having to rebuild the app all the time. - Add modulefinder support, like we discussed by telepathy... The full version would also copy the Python executable to Contents/Resources/. Not sure what to do about a Framework python, though. Not sure I even care about that anymore: it only seems to make thing harder here. What do you think? - A strip binaries option. Hm, evil? Could save a huge amount of disk space, though. Question: is it possible to completely override sys.path for a statically built Unix Python? $PYTHONPATH merely prepends sys.path. Would be nice to completely control it for a standalone app bundle. Speaking of sys.path: why does the objc module muck with it? Can't we solve this some other way? I really dislike imports with such side effects. (It has already confused me to no end: modules that I knew were in the current directory couldn't be found after "import objc"...) An option would be for the os.execve() wrapper to add Contents/Resources/ to the path through $PYTHONPATH. Just |
From: <bb...@ma...> - 2002-11-18 18:40:13
|
I ran into the single biggest reason not to use a pure python main this morning. Project Builder's indexing relies on the use of header files to determine what to index. As such, if I link Cocoa, AppKit, and Foundation into my application as I build main.m, all three framework's documentation and headers will be fully indexed by PBX such that I can easily and very quickly access it through cmd or opt double-clicking. Very, very handy. Now, of course, this doesn't mean we couldn't use a python based main and provide a different NSExecutableFile key/value in the information bundle while continuing to build a binary with all the frameworks for indexing purposes, but why bother when we already have a bin-python-main.m that works quite well, if fully Cocoa compliant, and has some additional features already implemented that are extremely convenient as the size of a project grows? b.bum |
From: Just v. R. <ju...@le...> - 2002-11-18 19:19:20
|
bb...@ma... wrote: > I ran into the single biggest reason not to use a pure python main this > morning. Project Builder's indexing relies on the use of header files > to determine what to index. As such, if I link Cocoa, AppKit, and > Foundation into my application as I build main.m, all three framework's > documentation and headers will be fully indexed by PBX such that I can > easily and very quickly access it through cmd or opt double-clicking. > > Very, very handy. Hm, basing a coding decision on one specific feature of one specific IDE? Bleh... > Now, of course, this doesn't mean we couldn't use a python based main > and provide a different NSExecutableFile key/value in the information > bundle while continuing to build a binary with all the frameworks for > indexing purposes, but why bother when we already have a > bin-python-main.m that works quite well, if fully Cocoa compliant, and > has some additional features already implemented that are extremely > convenient as the size of a project grows? - the current main.m doesn't work if the python executable isn't /usr/bin/python - it's 50 lines of dense Obj-C code instead of 5 sparse lines of Python - the executable can't easily be created from a template - it depends on dev-tools being available, can't be built from pure Python - why would one _ever_ want to use Obj-C if the same can be done in Python and speed is not an issue? Questions: - what's not Cocoa-compliant about the current Python solution? - what are the additional features of main.m? Just |
From: <bb...@ma...> - 2002-11-18 19:38:57
|
On Monday, November 18, 2002, at 02:18 PM, Just van Rossum wrote: > Hm, basing a coding decision on one specific feature of one specific > IDE? > Bleh... Normally, I would agree... however, seeing that PBX is the standard and free IDE included with the platform and, therefore, is accessible to every single developer on the platform and that installation of the Dev Tools also installs all the documentation that the developer needs for effective development using PyObjC, it would seem that basic decisions on the PBX IDE is in line with the desired direction for the module. > - the current main.m doesn't work if the python executable isn't > /usr/bin/python Not true; set PythonBinPath default to whatever you want. > - it's 50 lines of dense Obj-C code instead of 5 sparse lines of Python 50 lines that no developer ever has to look at; plus, that 50 lines packs quite a few more features into than the 5 lines of python. > - the executable can't easily be created from a template Why would it need to be created from a template? Once the executable exists-- it could/should be shipped as a part of the PyObjC module-- it can be copied into any application and it will "just work". It can be renamed, if so desired. > - it depends on dev-tools being available, can't be built from pure > Python Why would it need to be compiled? It "just works" as is. Just copy it. > - why would one _ever_ want to use Obj-C if the same can be done in > Python and > speed is not an issue? I was kind of expecting to see a :-) on that statement. Python is a wonderful language, but there is a lot of value in other languages... In any case, the ObjC version offers features that cannot be implemented in Python. Notably, the automatic handling and loading of frameworks cannot be done without some manual effort on the part of the developer. The current bin-python-main.m allows the developer to link the frameworks into the project as they would in any normal PBX based project and the __main__.py and bin-python-main.m will take care of ensuring that they are also dynamically loaded once control is turned over to the python interpreter. Of course, all of this is just a workaround until Apple ships an embeddable interpreter [though, even once they do, it may be sometime before everyone in the market has upgraded to a version of the OS with the appropriate dylib in place]. The point of the PyObjC bridge is to provide a transparent bridge between Python and Objective-C such that a developer can freely mix and match the two at will. The compiled executable based approach preserves the full OS X development experience for those that choose it while taking away nothing from those that choose to go the pure-Python, non Apple Dev Tools, approach. The same cannot be said for the pure python main. There isn't a reason-- beyond yet-another-moving-part-to-maintain-- that we can't ship both. b.bum |
From: Just v. R. <ju...@le...> - 2002-11-18 20:23:26
|
bb...@ma... wrote: > On Monday, November 18, 2002, at 02:18 PM, Just van Rossum wrote: > > Hm, basing a coding decision on one specific feature of one > > specific IDE? Bleh... > > Normally, I would agree... however, seeing that PBX is the standard and > free IDE included with the platform and, therefore, is accessible to > every single developer on the platform and that installation of the Dev > Tools also installs all the documentation that the developer needs for > effective development using PyObjC, it would seem that basic decisions > on the PBX IDE is in line with the desired direction for the module. Ok. However, the tool I have in mind is not specific to pyobjc. (I personally don't use PB yet, and I'm not sure I will anytime soon.) > > - the current main.m doesn't work if the python executable isn't > > /usr/bin/python > > Not true; set PythonBinPath default to whatever you want. Ok, I see the [NSUserDefaults standardUserDefaults] line. User defaults? How does this work? Is it an entry in the Info.plist? If so, how come that's called a user default? It it really _is_ a user default: it should be an app setting. > > - it's 50 lines of dense Obj-C code instead of 5 sparse lines of Python > > 50 lines that no developer ever has to look at; plus, that 50 lines > packs quite a few more features into than the 5 lines of python. I had to look at it the first time I tried to use it with a different Python than the 10.2-shipped. > > - the executable can't easily be created from a template > > Why would it need to be created from a template? Once the executable > exists-- it could/should be shipped as a part of the PyObjC module-- it > can be copied into any application and it will "just work". It can be > renamed, if so desired. Ok. However, the idea to just make a custom execve wrapper which (eg.) hardcodes the real executable and/or the main Python program appleals to me. It's just so simple. > > - it depends on dev-tools being available, can't be built from pure > > Python > > Why would it need to be compiled? It "just works" as is. Just copy it. True. But what if you'd want to muck with argv before passing it along to the child process? > > - why would one _ever_ want to use Obj-C if the same can be done in > > Python and speed is not an issue? > > I was kind of expecting to see a :-) on that statement. Ok, just to make that 100% clear: I'm not even kidding ;-) > Python is a wonderful language, but there is a lot of value in other > languages... Sure. Obj-C may kick some major butt compared to C (or even C++), but compared to Python it's a big fat pain in the butt. Hey, a language war! ;-) > In any case, the ObjC version offers features that cannot be > implemented in Python. Notably, the automatic handling and loading of > frameworks cannot be done without some manual effort on the part of the > developer. I don't follow this. Why would you load Frameworks in main.m if you're execve-ing another _process_? > The current bin-python-main.m allows the developer to link > the frameworks into the project as they would in any normal PBX based > project and the __main__.py and bin-python-main.m will take care of > ensuring that they are also dynamically loaded once control is turned > over to the python interpreter. Ok, I guess I'll have to learn more about this. Isn't "import AppKit" all that's needed? > Of course, all of this is just a workaround until Apple ships an > embeddable interpreter [though, even once they do, it may be sometime > before everyone in the market has upgraded to a version of the OS with > the appropriate dylib in place]. I actually _like_ the flexibility of doing an execve. Bootstrapping code in Python, what more could one want? ;-) > The point of the PyObjC bridge is to provide a transparent bridge > between Python and Objective-C such that a developer can freely mix and > match the two at will. The compiled executable based approach > preserves the full OS X development experience for those that choose it > while taking away nothing from those that choose to go the pure-Python, > non Apple Dev Tools, approach. The same cannot be said for the pure > python main. But it remains purely an IDE problem, no? > There isn't a reason-- beyond yet-another-moving-part-to-maintain-- > that we can't ship both. Not sure if I follow you. I think both the main.m and the Python execve wrapper can exist next to each other. I'll write the one, you the other ;-) Peace... Just |
From: <bb...@ma...> - 2002-11-18 20:51:17
|
On Monday, November 18, 2002, at 03:23 PM, Just van Rossum wrote: > Not sure if I follow you. I think both the main.m and the Python > execve wrapper > can exist next to each other. I'll write the one, you the other ;-) > Peace... I'll try to find time to respond to some of the other points in detail (as it is both very interesting, quite pertinent, and is making me think really hard about why I have the opinions that I do), but the above makes it all somewhat moot. This sounds good to me-- I'm going to continue to use the compiled main in the context of the Project Builder project templates and I'll leave it to you/Jack/etc to come up with whatever works best for the standalone method of building apps (and I'll use it quite enthusiastically, when appropriate). b.bum |
From: Jack J. <Jac...@cw...> - 2002-11-19 12:05:27
|
On Monday, Nov 18, 2002, at 20:38 Europe/Amsterdam, bb...@ma... wrote: > In any case, the ObjC version offers features that cannot be > implemented in Python. Notably, the automatic handling and loading of > frameworks cannot be done without some manual effort on the part of > the developer. The current bin-python-main.m allows the developer to > link the frameworks into the project as they would in any normal PBX > based project and the __main__.py and bin-python-main.m will take care > of ensuring that they are also dynamically loaded once control is > turned over to the python interpreter. Bill, you've said this a couple of times earlier, but I absolutely fail to see what you mean by it. What's the use linking an executable to a couple of frameworks if that executable is going to blow itself away with an execve() a couple of microseconds later? How will the frameworks that bin-python-main has been linked with influence the python interpreter that is started later? -- - 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 - |
From: <bb...@ma...> - 2002-11-19 16:18:01
|
On Tuesday, November 19, 2002, at 07:05 AM, Jack Jansen wrote: > Bill, you've said this a couple of times earlier, but I absolutely > fail to see what you mean by it. What's the use linking an executable > to a couple of frameworks if that executable is going to blow itself > away with an execve() a couple of microseconds later? How will the > frameworks that bin-python-main has been linked with influence the > python interpreter that is started later? Let me use a production application suite that I'm developing as an example. It is a Cocoa and Foundation based suite of applications that provides a user interface to CodeFab's product Intent. See www.codefab.com for more information. Intent provides a full featured XML-RPC inteface; anything you can do via the web interface can also be done via XML-RPC (excluding administrative tasks). About a month ago, I moved the project to using Python as the XML-RPC client because it was both a boatload easier and significantly more robust than using Apple's WebServices framework found in the Core (which can be crashed by malformed XML -- "malformed" isn't well defined given the state of the XML-RPC "specification"). The use of python also allows me to build a single client that can be used basically anywhere, has a clean command line interface and can act as the communication bridge within the Cocoa applications. The application suite is currently comprised of two applications; a user tool and an administrative tool. A command line tool and a third application are already planned. As there are multiple applications, there are two frameworks used across the apps -- the Core framework provides non-UI client services while an Application support level framework provides UI services. The Core only depends on the Foundation. The Application level framework depends on both Foundation and AppKit. Enter Python; the Core contains the Python XML-RPC client code and, as such, uses the PyObjC bridge quite heavily. The rest of the app is pure Obj-C. Not so much because it is intended to be pure ObjC, but because it was pure ObjC before Python and the PyObjC bridge were introduced [and before PyObjC was stable enough to be used in this context]. In other words, I have a large and relatively complex set of interlocking projects that mix Python and Objective-C. To these ends, each application ships with the two frameworks installed in the application wrapper, one of which contains Python code using PyObjC. At launch, I need to dynamically load both frameworks. The most straightforward approach would be to walk through the Contents/Frameworks or Contents/SharedFrameworks directory and dynamically load each framework in turn. However, this won't work within the development environment as the frameworks are not-- and should not be-- copied into this directories when I'm building and running the app(s) within Project Builder (i.e. using pbxbuild to build the apps). This also won't work in situations where the developer or administrator is using the DYLD functionality provided by the system to either share one copy of the frameworks or to run a different version of a particular framework within the app. To make everything work correctly, I build the python-bin-main based executable-- the main executable within each app wrapper-- such that it links against AppKit, Foundation, and my two private frameworks. Upon execution, the python-bin-main uses NSBundle's +allFrameworks directory to determine all of the frameworks linked into the application, creates a command line argument to be passed to the python interpreter, sets a couple of the DYLD linker configuration environment variables appropriately, and passes control to the python interpreter (typically /usr/bin/python but can be any python interpreter -- pyobjc may or may not be packaged in the App wrapper, as well) by executing Main.py (now __main__.py, but will move to the list Jack uses very soon) entry point python file. Main.py modifies sys.path to include Contents/Resources/pyobjc (in case pyobjc is shipped in the wrapper). It then loads the objc module. Once the objc module is loaded, Main.py walks the list of frameworks that were passed in from python-bin-main executable and dynamically loads each one. Furthermore, it will execute the file Init.py in each framework if the framework's NSBundle finds said file via pathForResource_ofType_('Init', 'py'), providing the framework with a chance to initialize its python based features, if any. All of this guarantees that the dynamically loaded frameworks under the Python environment behave as much like their directly linked counterparts in a "normal" application. In particular, it guarantees that the frameworks will be loaded from exactly where they would normally be loaded-- there is no way to tell where a framework is going to be loaded from without both reverse engineering and recreating a good chunk of the dynamic loading code found via the dyld* APIs. This style of initialization also allows the developer to create a command line tool-- an executable without a resources directory-- that can still use a mix of Python and Objective-C by using a framework and will also find that framework in the exact same fashion as a "normal" command line tool that uses a framework (namely, will find the framework in the development environment without having to install the framework). For Cocoa apps written in pure python as non-PBX based or 'standalone' projects, python-bin-main doesn't offer much and sticking with a pure python based main is the way to go. For developers using PBX to develop any kind of a Cocoa-ObjC app that used compiled ObjC classes, the compiled python-bin-main is a requirement if the developer wants the development experience to remain consistent with non-python based projects (a desirable feature, IMO). If the developer wants the documentation indexing to work in PBX, something must be compiled as a part of the project -- doesn't have to be the main, but it might as well be. BTW: The Cocoa application and Python client are both open source -- we will be shipping the source under a BSD style (or MIT) license. A rather long winded response, but hopefully it'll provide some indication as to the thinking that has gone into some of my opinions... b.bum |
From: Jack J. <Jac...@cw...> - 2002-11-19 13:26:04
|
On Monday, Nov 18, 2002, at 00:46 Europe/Amsterdam, Just van Rossum wrote: > Jack Jansen wrote: > >> Mac/script/buildappbundle.py > > Ok, I've had a closer look at it: great! Mind if I take a hack at it? > I would > like to move it to Mac/Lib/ though. It it used much? Would people > likely get > upset if I change the (function) interface? It's only been there for a week or two, so I doubt anyone gets upset. But: do keep the commandline interface working (or, if you move the functionality to Lib, keep the driver main program in the scripts folder), as I use it when building MacPython-OSX 2.2 (the MacPython that will sit on /usr/bin/python). And note that the tool has nothing python-specific, really. I use it with my OpenGL C and C++ applications too. I build these with Makefiles (they run on both Linux and OSX), and for OSX the last build step is buildappbundle, which stuffs the executable into a .app bundle (on Linux this step is skipped). > - I would not let people specify a nib by path, but by name, > defaulting to > "MainMenu". The .lproj or individual nibs should then be listed as a > resource. Why? If there is a good reason to disallow full pathnames: fine with me, but I don't immediately see why this would be so. > - I don't care much for the command line interface: I think people > should just > write a setup.py-like script. I wouldn't rip main() out, but I > wouldn't want > to spend much time on it. As said above: I need it for building Python.app for 2.2 MacPython-OSX. > - I think it's good if it (by default) would build the app in a build/ > subdir, > like distutils and PB. I've been working to the analogy of BuildApplet, but I'm not particularly married to that. > > Further things I'd like to do: > > - Change it to use the os.execve() trick. Definitely, but as an option. The only thing I'm not sure about is whether the execve code should be in-line in a string (as in your version) or external on sys.path (as buildtools.py currently does). > - I would like to add a debug or "developer" option: instead of > copying the > files/folders it would put symlinks inside the bundle. That way it's > easy > to keep on hacking on any file without having to rebuild the app all > the time. Yes, good idea. > - Add modulefinder support, like we discussed by telepathy... The full > version > would also copy the Python executable to Contents/Resources/. Not > sure what > to do about a Framework python, though. Not sure I even care about > that > anymore: it only seems to make thing harder here. What do you think? I think the framework python is still my preferred option, and I hope we can get Apple to adopt it at some point in the future. but for the time being I want to keep both working. As to modulefinder support: I think we need to think architecture first. We now have a number of modules and scripts that do things that are vaguely similar conceptually, but very different in implementation: - buildtools can build MacPython-OS9 applets. - buildtools can build MacPython-OSX applets. - buildtools can help with building MacPython-OS9 applications. - BuildApplication uses buildtools and selected bits of freeze to build applications for MacPython-OS9. - buildappbundle can build general .app bundles. - your tool can build .app bundles specific for Python applets. How about structuring this whole lot as a package? We could then make sure that the OS9-specific code (which would depend on MacPython functionality for resource-file mangling, for instance) would be in a separate module so it wouldn't be seen when building a PyObjC applet with /usr/bin/python. Also, there's heaps of data that the modules above rely on, and currently some of it is hardcoded in strings (your execve code, the plist data in your script), some of it is in modules on sys.path (__rawmain__ aka appletrawmain, appletrunner), some of it is somewhere completely different (Applet-Info.plist). If we have a package we also have a neat place to store all this data, in separate files. > > - A strip binaries option. Hm, evil? Could save a huge amount of disk > space, > though. Good idea. But: is "strip" available if you don't have the dev tools installed? > > Question: is it possible to completely override sys.path for a > statically built > Unix Python? $PYTHONPATH merely prepends sys.path. Would be nice to > completely > control it for a standalone app bundle. You could create lib/python2.2 and lib/python2.2/lib-dynload under Resources, and then set PYTHONHOME to Resources. Hmm, this could be an interesting way to distinguish applets and fully self-contained applications: if there is a lib/python2.2 and lib/python2.2/lib-dynload then we set PYTHONHOME. We could then copy /usr/bin/python to the MacOS directory too, and use that to run the standalone application. For static python this is good enough. For framework python more magic is needed. -- - 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 - |
From: Just v. R. <ju...@le...> - 2002-11-19 14:16:03
|
Oooh, lots of stuff... Jack Jansen wrote: [ Mac/script/buildappbundle.py ] > It's only been there for a week or two, so I doubt anyone gets upset. > But: do keep the commandline interface working (or, if you move the > functionality to Lib, keep the driver main program in the scripts > folder), as I use it when building MacPython-OSX 2.2 (the MacPython > that will sit on /usr/bin/python). > > And note that the tool has nothing python-specific, really. I use it > with my OpenGL C and C++ applications too. I build these with > Makefiles (they run on both Linux and OSX), and for OSX the last > build step is buildappbundle, which stuffs the executable into a .app > bundle (on Linux this step is skipped). Ah, I see. This means I'll have to rework my working version as it's fairly Python-specific now :-( > > - I would not let people specify a nib by path, but by name, > > defaulting to "MainMenu". The .lproj or individual nibs should then > > be listed as a resource. > > Why? If there is a good reason to disallow full pathnames: fine with > me, but I don't immediately see why this would be so. But you don't do anything with the pathname but get the base name, strip the extension and use it as the NSMainNibFile Info.plist key, right? Why not just write "MainMenu" and be done with it? > > - I think it's good if it (by default) would build the app in a > > build/ subdir, like distutils and PB. > > I've been working to the analogy of BuildApplet, but I'm not > particularly married to that. BuildApplet is great for very simple things, and worked fine on OS9 where everything you needed could live in <scriptname>.rsrc. But I don't think this approach is all that useful for .app bundles but for the simplest of scripts. Then again: BuildApplet-like functionality could easily be built on top of this. > > - Change it to use the os.execve() trick. > > Definitely, but as an option. Ok, I'll have to work on that. > The only thing I'm not sure about is > whether the execve code should be in-line in a string (as in your > version) or external on sys.path (as buildtools.py currently does). My working code currently needs to munge the wrapper even more: I need to specify the Python executable in case it's copied to Contents/Resources/. It's a tiny amount of code and works for me just fine as a triple-quoted string. [Reading this back: I need to do even more if we need to set PYTHONHOME conditionally.] > > - Add modulefinder support, like we discussed by telepathy... The > > full version would also copy the Python executable to > > Contents/Resources/. Not sure what to do about a Framework python, > > though. Not sure I even care about that anymore: it only seems to > > make thing harder here. What do you think? > > I think the framework python is still my preferred option, and I hope > we can get Apple to adopt it at some point in the future. but for the > time being I want to keep both working. Ok, but I'll need your help then... The code will have to become a _lot_ more complicated if I need to support Framework Python: instead of just throwing the python executable and all needed modules (.py[c] & .so) into Contents/Resources/ I'll have to copy a _subset_ of Python.framework to the bundle. And somehow we need to tell the main executable to look for the Framework in the bundle (or has this become more transparent now?). Things are so fantastically simple with a unix install that I'm not really all that sure what Python.framework was supposed to buy us in the first place :-(. > As to modulefinder support: I think we need to think architecture > first. We now have a number of modules and scripts that do things that > are vaguely similar conceptually, but very different in implementation: > - buildtools can build MacPython-OS9 applets. > - buildtools can build MacPython-OSX applets. > - buildtools can help with building MacPython-OS9 applications. > - BuildApplication uses buildtools and selected bits of freeze to build > applications for MacPython-OS9. > - buildappbundle can build general .app bundles. > - your tool can build .app bundles specific for Python applets. Hm, I would _love_ to just leave that old cruft alone, and start from scratch with something maintainable. The old stuff works, I would rather not let the old stuff be a burden to get the new stuff going. The stuff I would _especially_ like to avoid is the Mac-specific main, with __main__/__rawmain__ magic. I want to use the vanilla unix main, or rather the vanilla unix _executable_. Trivial with the execve template. [ ... ] > > - A strip binaries option. Hm, evil? Could save a huge amount of > > disk space, though. > > Good idea. But: is "strip" available if you don't have the dev tools > installed? Dunno, but we can skip that option then... > > Question: is it possible to completely override sys.path for a > > statically built Unix Python? $PYTHONPATH merely prepends sys.path. > > Would be nice to completely control it for a standalone app bundle. > > You could create lib/python2.2 and lib/python2.2/lib-dynload under > Resources, and then set PYTHONHOME to Resources. Ah, PYTHONHOME of course. > Hmm, this could be an interesting way to distinguish applets and > fully self-contained applications: if there is a lib/python2.2 and > lib/python2.2/lib-dynload then we set PYTHONHOME. We could then copy > /usr/bin/python to the MacOS directory too, and use that to run the > standalone application. Not sure if I follow you... > For static python this is good enough. For framework python more > magic is needed. Operative words: "more magic". Do we _really_ want to go there? Just |
From: Jack J. <Jac...@cw...> - 2002-11-19 15:39:17
|
On Tuesday, Nov 19, 2002, at 15:15 Europe/Amsterdam, Just van Rossum wrote: >>> - I would not let people specify a nib by path, but by name, >>> defaulting to "MainMenu". The .lproj or individual nibs should then >>> be listed as a resource. >> >> Why? If there is a good reason to disallow full pathnames: fine with >> me, but I don't immediately see why this would be so. > > But you don't do anything with the pathname but get the base name, > strip the > extension and use it as the NSMainNibFile Info.plist key, right? Why > not just > write "MainMenu" and be done with it? Yes, it's added to the resources. Ah, I now see your "The .lproj or individual nibs should then be listed as a resource" sentence. So you want the user to pass the main nib twice, once as a file and once as a name. Hmm, yes, with nibs in .lprojs I can see the point. Ok, fine with me, but you should probably add a check that the main nib actually exists. >>> - I think it's good if it (by default) would build the app in a >>> build/ subdir, like distutils and PB. >> >> I've been working to the analogy of BuildApplet, but I'm not >> particularly married to that. > > BuildApplet is great for very simple things, and worked fine on OS9 > where > everything you needed could live in <scriptname>.rsrc. But I don't > think this > approach is all that useful for .app bundles but for the simplest of > scripts. > Then again: BuildApplet-like functionality could easily be built on > top of this. But don't forget that there are many "very simple things". About 100% of the scripts ported over from unix, for instance. But as I said: if you're writing the code you decide how to do it. >> The only thing I'm not sure about is >> whether the execve code should be in-line in a string (as in your >> version) or external on sys.path (as buildtools.py currently does). > > My working code currently needs to munge the wrapper even more: I need > to > specify the Python executable in case it's copied to > Contents/Resources/. > It's a tiny amount of code and works for me just fine as a > triple-quoted string. > [Reading this back: I need to do even more if we need to set PYTHONHOME > conditionally.] Could be done dynamically: bindir = os.path.split(argv[0])[0] if os.path.exists(os.path.join(bindir, "python")): We are a self-contained application, set PYTHONHOME and use this python else: We are an applet. Set PYTHONPATH and use /usr/bin/python >> I think the framework python is still my preferred option, and I hope >> we can get Apple to adopt it at some point in the future. but for the >> time being I want to keep both working. > > Ok, but I'll need your help then... The code will have to become a > _lot_ more > complicated if I need to support Framework Python: instead of just > throwing the > python executable and all needed modules (.py[c] & .so) into > Contents/Resources/ > I'll have to copy a _subset_ of Python.framework to the bundle. And > somehow we > need to tell the main executable to look for the Framework in the > bundle (or has > this become more transparent now?). Things are so fantastically simple > with a > unix install that I'm not really all that sure what Python.framework > was > supposed to buy us in the first place :-(. Don't worry about this for the moment. BuildApplication doesn't work for framework python right now, so there's nothing you can break. I have some ideas on how to do this, but there's lots of time before 2.3b1. >> As to modulefinder support: I think we need to think architecture >> first. We now have a number of modules and scripts that do things that >> are vaguely similar conceptually, but very different in >> implementation: >> - buildtools can build MacPython-OS9 applets. >> - buildtools can build MacPython-OSX applets. >> - buildtools can help with building MacPython-OS9 applications. >> - BuildApplication uses buildtools and selected bits of freeze to >> build >> applications for MacPython-OS9. >> - buildappbundle can build general .app bundles. >> - your tool can build .app bundles specific for Python applets. > > Hm, I would _love_ to just leave that old cruft alone, and start from > scratch > with something maintainable. The old stuff works, I would rather not > let the old > stuff be a burden to get the new stuff going. There's definitely something to be said for this. [think.... think...] Ok, make it so. > > The stuff I would _especially_ like to avoid is the Mac-specific main, > with > __main__/__rawmain__ magic. I want to use the vanilla unix main, or > rather the > vanilla unix _executable_. Trivial with the execve template. But unfortunately the __rawmain__ trick is needed for one of the most useful applications of an applet: taking a standard unix Python script and turning it into a droplet. This is the one use of applets I can see end-users (as opposed to developers) making. -- - 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 - |
From: Just v. R. <ju...@le...> - 2002-11-19 17:07:05
|
Jack Jansen wrote: > > But you don't do anything with the pathname but get the base name, > > strip the extension and use it as the NSMainNibFile Info.plist key, > > right? Why not just write "MainMenu" and be done with it? > > Yes, it's added to the resources. Ah, I now see your "The .lproj or > individual nibs should then be listed as a resource" sentence. So you > want the user to pass the main nib twice, once as a file and once as > a name. Hmm, yes, with nibs in ..lprojs I can see the point. Ok, fine > with me, but you should probably add a check that the main nib > actually exists. I read your code, and it just picks an arbitrary nib if there are more than one, I don't quite understand how you can defend that... [I don't quite get Bill's comment regarding this, we're assembling an app, not _using_ nibs, so I don't see the relevance of the system API's here.] > > BuildApplet is great for very simple things, and worked fine on OS9 > > where everything you needed could live in <scriptname>.rsrc. But I > > don't think this approach is all that useful for .app bundles but > > for the simplest of scripts. Then again: BuildApplet-like > > functionality could easily be built on top of this. > > But don't forget that there are many "very simple things". About 100% > of the scripts ported over from unix, for instance. But as I said: if > you're writing the code you decide how to do it. I find it very limiting in reality: as soon as a unix script has options the argv emulation is hardly useful. > > My working code currently needs to munge the wrapper even more: I > > need to specify the Python executable in case it's copied to > > Contents/Resources/. It's a tiny amount of code and works for me > > just fine as a triple-quoted string. [Reading this back: I need to > > do even more if we need to set PYTHONHOME conditionally.] > > Could be done dynamically: > bindir = os.path.split(argv[0])[0] > if os.path.exists(os.path.join(bindir, "python")): > We are a self-contained application, set PYTHONHOME and use > this python > else: > We are an applet. Set PYTHONPATH and use /usr/bin/python Ok, that's an option. But I don't really like runtime checks for things that are known at build time, and I really don't see any problem with using a tiny triple-quoted string as template. > > The stuff I would _especially_ like to avoid is the Mac-specific > > main, with __main__/__rawmain__ magic. I want to use the vanilla > > unix main, or rather the vanilla unix _executable_. Trivial with > > the execve template. > > But unfortunately the __rawmain__ trick is needed for one of the most > useful applications of an applet: taking a standard unix Python > script and turning it into a droplet. Don't you want to move the argv emulation to Python as well? It's hairy stuff and I think we could win a great deal to have it in Python. I really think we should strive to use a vanilla main, and the execve wrapper makes it all possible. Just |
From: <bb...@ma...> - 2002-11-19 17:56:29
|
On Tuesday, November 19, 2002, at 12:06 PM, Just van Rossum wrote: > [I don't quite get Bill's comment regarding this, we're assembling an > app, not > _using_ nibs, so I don't see the relevance of the system API's here.] Clarification: Yes, I realized now it was about assembling an app. In any case, the NSMainNibFile (or whatever it is called) key in the Info.plist should be set appropriately as opposed to using a hard coded path. It, in turn, uses the localization APIs to load the appropriate NIB file. At least, it does in Cocoa, I have *no idea* what happens with NIB based Carbon apps. b.bum |
From: Jack J. <Jac...@cw...> - 2002-11-20 13:45:30
|
On Tuesday, Nov 19, 2002, at 18:06 Europe/Amsterdam, Just van Rossum wrote: >> Yes, it's added to the resources. Ah, I now see your "The .lproj or >> individual nibs should then be listed as a resource" sentence. So you >> want the user to pass the main nib twice, once as a file and once as >> a name. Hmm, yes, with nibs in ..lprojs I can see the point. Ok, fine >> with me, but you should probably add a check that the main nib >> actually exists. > > I read your code, and it just picks an arbitrary nib if there are more > than one, > I don't quite understand how you can defend that... No, not an arbitrary one, it picks the first one you specified. But never mind: let's do this your way (i.e. specify the nib by name, separate from the .plist files). >> But unfortunately the __rawmain__ trick is needed for one of the most >> useful applications of an applet: taking a standard unix Python >> script and turning it into a droplet. > > Don't you want to move the argv emulation to Python as well? It's > hairy stuff > and I think we could win a great deal to have it in Python. I really > think we > should strive to use a vanilla main, and the execve wrapper makes it > all > possible. Let me borrow Guido's time machine .... [POOF] Done! PythonW uses the normal unix main program (as of 2.3a0, not in 2.2.X). And the __rawmain__ is all about doing the OSA stuff for argument emulation. Look at Mac/Lib/appletrawmain.py (which is copied to __rawmain__ in an applets that wants argv emulation) and argvemulator.py (which does the actual 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 - |
From: Just v. R. <ju...@le...> - 2002-11-20 15:18:45
|
Jack Jansen wrote: > > I read your code, and it just picks an arbitrary nib if there are > > more than one, I don't quite understand how you can defend that... > > No, not an arbitrary one, it picks the first one you specified. But > never mind: let's do this your way (i.e. specify the nib by name, > separate from the ..plist files). Ah, whoops, sorry for the misunderstanding! > >> But unfortunately the __rawmain__ trick is needed for one of the most > >> useful applications of an applet: taking a standard unix Python > >> script and turning it into a droplet. > > > > Don't you want to move the argv emulation to Python as well? It's > > hairy stuff and I think we could win a great deal to have it in > > Python. I really think we should strive to use a vanilla main, and > > the execve wrapper makes it all possible. > > Let me borrow Guido's time machine .... [POOF] Done! > > PythonW uses the normal unix main program (as of 2.3a0, not in > 2.2.X). And the __rawmain__ is all about doing the OSA stuff for > argument emulation. > > Look at Mac/Lib/appletrawmain.py (which is copied to __rawmain__ in > an applets that wants argv emulation) and argvemulator.py (which does > the actual work). Ah, perfect, I hadn't realized that! Very cool. But then I don't understand what you meant with your comment about the "__rawmain__ trick" being needed: the question was whether it is needed in the _actual_ compiled main program, but I don't see how that could be the case with the execve wrapper. Just |
From: <bb...@ma...> - 2002-11-20 16:32:51
|
On Wednesday, November 20, 2002, at 08:45 AM, Jack Jansen wrote: > No, not an arbitrary one, it picks the first one you specified. But > never mind: > let's do this your way (i.e. specify the nib by name, separate from > the .plist > files). I'm confused; will this work with the localization features built into the system? |
From: <bb...@ma...> - 2002-11-19 16:20:10
|
(Cursory comments-- a lot of this is about stuff that I know little about [framework build, Carbon stuff, MacPython], so take it with a grain of salt) On Tuesday, November 19, 2002, at 08:26 AM, Jack Jansen wrote: >> - I would not let people specify a nib by path, but by name, >> defaulting to >> "MainMenu". The .lproj or individual nibs should then be listed as a >> resource. > > Why? If there is a good reason to disallow full pathnames: fine with > me, but I don't > immediately see why this would be so. If one uses the CFBundle/NSBundle APIs to obtain the path to the NIB file, then localization "just works". Full pathnames defeat this feature of the OS. Similarly, using the NSMainNIB key (whatever it is called) also exercises the localization features. >> Further things I'd like to do: >> >> - Change it to use the os.execve() trick. > > Definitely, but as an option. The only thing I'm not sure about is > whether the execve code > should be in-line in a string (as in your version) or external on > sys.path (as buildtools.py > currently does). If it is to work with the Apple distribution of Python, then the assumption must be that it won't necessarily be available in the python installation? Even in a development environment, there is no need for the user to install pyobjc into the python distribution -- non-administrators can and should be able to use PyObjC and the related development tools without an administrative-only installation phase. >> - I would like to add a debug or "developer" option: instead of >> copying the >> files/folders it would put symlinks inside the bundle. That way >> it's easy >> to keep on hacking on any file without having to rebuild the app >> all the time. > > Yes, good idea. WebObjects has a feature called 'rapid turnaround mode'. It works in a similar fashion, but doesn't use symlinks. I have been looking into how to do the same with PyObjC based applications. But, in reality, symlinks work just fine . >> - Add modulefinder support, like we discussed by telepathy... The >> full version >> would also copy the Python executable to Contents/Resources/. Not >> sure what >> to do about a Framework python, though. Not sure I even care about >> that >> anymore: it only seems to make thing harder here. What do you think? > > I think the framework python is still my preferred option, and I hope > we can get Apple to adopt it at some point in the future. but for the > time being I want to keep both working. I don't understand the benefits of the framework build. It requires additional maintenance within the Python source trees and doesn't seem to add any capabilities that couldn't be done with a 'regular' build of Python? I would think there is a tremendous amount of value in eliminating the number of differences between the build of Python on one platform vs. others. Certainly, the Mac platform warrants the slew of Mac specific modules that are in their, but modules build relatively cleanly without requiring changes to and ongoing maintenance of configure.in.... I admit a lot of ignorance on this front-- emphasis on ? .... >> - A strip binaries option. Hm, evil? Could save a huge amount of disk >> space, >> though. > > Good idea. But: is "strip" available if you don't have the dev tools > installed? It is in /usr/bin/strip and, I believe, is a part of the BSD layer, not the dev tools. Should definitely check the BOMs in /Library/Receipts/.... b.bum |
From: Just v. R. <ju...@le...> - 2002-11-19 23:27:21
|
bb...@ma... wrote: > I don't understand the benefits of the framework build. It requires > additional maintenance within the Python source trees and doesn't seem > to add any capabilities that couldn't be done with a 'regular' build of > Python? I would think there is a tremendous amount of value in > eliminating the number of differences between the build of Python on > one platform vs. others. Certainly, the Mac platform warrants the slew > of Mac specific modules that are in their, but modules build relatively > cleanly without requiring changes to and ongoing maintenance of > configure.in.... Hear, hear and hear. I'd suggest to install all Mac stuff in <prefix>/lib/python<version>/plat-darwin (or /plat-mac if the install procedure allows that). Just |
From: tmk <li...@ne...> - 2002-11-20 11:21:46
|
On Wednesday, Nov 20, 2002, at 00:27 Europe/Brussels, Just van Rossum wrote: > bb...@ma... wrote: > >> I don't understand the benefits of the framework build. It requires >> additional maintenance within the Python source trees and doesn't seem >> to add any capabilities that couldn't be done with a 'regular' build >> of >> Python? I would think there is a tremendous amount of value in >> eliminating the number of differences between the build of Python on >> one platform vs. others. Certainly, the Mac platform warrants the >> slew >> of Mac specific modules that are in their, but modules build >> relatively >> cleanly without requiring changes to and ongoing maintenance of >> configure.in.... > > Hear, hear and hear. > > I'd suggest to install all Mac stuff in > <prefix>/lib/python<version>/plat-darwin > (or /plat-mac if the install procedure allows that). Same here. I was originally a supporter of the framework install. But after bbum's excellent arguments in favor of a standard I can't see any advantages in having the official (Apple or not) python install being a framework install. Plus, it seems that even Apple is moving away from framework install for OSS type software (Perl, tcl used to be packaged (at least partially) as frameworks in Rhapsody and later on). And last, the many scars I got from trying to build (MachoPython) python from source on Mac OS X "non-standard" unix (starting way back on Rhapsody and Mac OS X Developper and Preview Releases have made me a strong supporter of standards when available ;-). That and the time it took to have Python build from source on Mac OS X without one having to hack on it. That said, I trust the fact that Jack may have very good reasons to favor the framework install option instead. When you can spare the time Jack inquiring minds want to know :-) Just my .02 euros = tmk = > > Just > > > ------------------------------------------------------- > This sf.net email is sponsored by: To learn the basics of securing > your web site with SSL, click here to get a FREE TRIAL of a Thawte > Server Certificate: http://www.gothawte.com/rd524.html > _______________________________________________ > Pyobjc-dev mailing list > Pyo...@li... > https://lists.sourceforge.net/lists/listinfo/pyobjc-dev > |
From: Jack J. <Jac...@cw...> - 2002-11-20 13:32:11
|
On Wednesday, Nov 20, 2002, at 12:21 Europe/Amsterdam, tmk wrote: > That said, I trust the fact that Jack may have very good reasons to > favor the framework install option instead. When you can spare the > time Jack inquiring minds want to know :-) As I explained on the pythonmac-sig last month I'm not so sure anymore, I would like to keep both options open for python 2.3, and then we'll see which build catches on. But when people thought I suggested doing away with framework builds completely (which I didn't) there was quite a bit of protest. MacCVS needs it, for using Python as its scripting language, and the Python OSA component needs it. Note that a non-framework Python with a shared library seems like a solution for this it's really only a poor substitute. With a shared library approach your python installation cannot be moved around anymore (Python itself can handle this, by using its own argv[0] to locate the Lib folder, but embedding applications will always use the fixed fallback path). Especially if we want binary installers things shouldn't depend on a compile-time builtin pathname. -- - 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 - |
From: Just v. R. <ju...@le...> - 2002-11-20 15:36:09
|
Jack Jansen wrote: > [ ... ] With a shared library approach your python installation > cannot be moved around anymore (Python itself can handle this, by > using its own argv[0] to locate the Lib folder, but embedding > applications will always use the fixed fallback path). [ ... ] I think that Python embedders should think twice about embedding based on an install not included with the system: the above is definitely not the only reason things may break. If you embed, ship Python as well and be done with it. Just |
From: Jack J. <Jac...@cw...> - 2002-11-20 16:37:29
|
On Wednesday, Nov 20, 2002, at 16:35 Europe/Amsterdam, Just van Rossum wrote: > Jack Jansen wrote: > >> [ ... ] With a shared library approach your python installation >> cannot be moved around anymore (Python itself can handle this, by >> using its own argv[0] to locate the Lib folder, but embedding >> applications will always use the fixed fallback path). [ ... ] > > I think that Python embedders should think twice about embedding based > on an > install not included with the system: the above is definitely not the > only > reason things may break. If you embed, ship Python as well and be done > with it. I fail to see this... In the case of MacCVS it's simple: if there's no framework Python installation you get no scripting capabilities. In the case of the Python OSA component I'm not sure what happens, but it doesn't really matter: the Python OSA component should be considered an integral part of the Python distribution (and we also don't really care what the IDE does if Python isn't installed). -- - 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 - |