From gward@python.net Thu Jun 1 01:03:37 2000 From: gward@python.net (Greg Ward) Date: Wed, 31 May 2000 20:03:37 -0400 Subject: [Distutils] Suggested directory convention Message-ID: <20000531200337.A489@beelzebub> Lots of distribution formats need a place to put files that aren't really temporary, can often be generated by the Distutils, but may be tweaked by the developer (and put under source control). I'm thinking of RPM's spec files, Debian's directory of package meta-data, Wise scripts, and similar stuff. Seems like a good idea to me to put this all in a directory "dist": the first time you use the Distutils to generate a .spec file, or a Wise script, or what-have-you, it would create "dist" and would always put those sort of files in there. Naturally, this would be a configurable option to the bdist_* commands, but "dist" strikes me as a sensible default. This is distinct from the "build" directory for two reasons: 1) it's for distribution, not building -- hence the domain of the module developer rather than the installer/packager; 2) it's not temporary -- it's always safe to blow away the "build" directory, but could be foolish to ditch "dist". (Eg. if someone has started with Distutils-generated files and customized them to suit.) In addition to the bdist_* commands, the sdist command could possibly use the dist tree for creating source archives. (Currently, it creates - (eg. "Distutils-0.8.3") in the distribution root, fill it up with copies or hardlinks to all the files in MANIFEST, and creates an archive rooted at -. If we move that source distribution tree down a level, we'd have to chdir to create the source archive.) Opinions? Sound like a good idea or just more complexity? Greg -- Greg Ward - nerd gward@python.net http://starship.python.net/~gward/ When the ship lifts, all bills are paid. No regrets. From mwa@gate.net Thu Jun 1 02:44:04 2000 From: mwa@gate.net (Mark W. Alexander) Date: Wed, 31 May 2000 21:44:04 -0400 (EDT) Subject: [Distutils] Suggested directory convention In-Reply-To: <20000531200337.A489@beelzebub> Message-ID: I like it alot! It could also hold package install scripts that aren't really part of the distribution but are necessary for packaging binary distributions. I use this convention for my Solaris/HP (non-python) packages by having a "pkgfiles" directory that installed either under the package directory, or if the package was installed in /usr or /usr/local, it went to /var/pkgfiles/pkg-name. This makes the binary package re- creatable on any system that it's installed on (unlike RPM, these package managers don't require the source). In some cases, I would like to do the same with Python packages, e.g. have the "dist" directory installed under the package installation directory. It's frequently usefull to have access to pre/post install scripts at other times, and they're generally not big enough to be a space concern. Mark Alexander mwa@gate.net From gward@python.net Thu Jun 1 02:58:27 2000 From: gward@python.net (Greg Ward) Date: Wed, 31 May 2000 21:58:27 -0400 Subject: [Distutils] Suggested directory convention In-Reply-To: ; from Mark W. Alexander on Wed, May 31, 2000 at 09:44:04PM -0400 References: <20000531200337.A489@beelzebub> Message-ID: <20000531215827.A677@beelzebub> On 31 May 2000, Mark W. Alexander said: > I like it alot! Oh good, 'cause I've already started sorta-kinda moving "bdist_rpm" in that direction. (If run with --spec-only, it now drops the spec file in "dist" rather than "redhat". The directory name is still hard-coded, though.) Greg -- Greg Ward - programmer-at-large gward@python.net http://starship.python.net/~gward/ Well, I didn't expect a sort of Spanish Inquisition! From gward@python.net Thu Jun 1 03:05:48 2000 From: gward@python.net (Greg Ward) Date: Wed, 31 May 2000 22:05:48 -0400 Subject: [Distutils] Pondering multi-package packages In-Reply-To: <3934C961.8DE617BE@lemburg.com>; from M.-A. Lemburg on Wed, May 31, 2000 at 10:12:17AM +0200 References: <20000524223002.C612@beelzebub> <392CFBA3.E4B5131E@lemburg.com> <20000525083500.O29443@inet.net> <392D4262.CF25D949@lemburg.com> <20000525220121.C996@beelzebub> <392E3AB2.D53CF1A0@lemburg.com> <20000526222832.B318@beelzebub> <392F936D.E2E3D42E@lemburg.com> <20000528152317.A698@beelzebub> <3934C961.8DE617BE@lemburg.com> Message-ID: <20000531220548.B677@beelzebub> On 31 May 2000, M.-A. Lemburg said: > Why not ? The RPMs could use the existing Python installation > which comes with a version of distutils (at least for 1.6) > or use a copy which gets installed together with the > package. The post-install script could then pass control > to distutils and let it apply its magic. True when installing and RPM into a Python 1.6 installation, but it'll be a good while before we can assume that. I want Distutils-generated RPMs to work with any version of Python that the modules-being-installed work with. (Granted, you may have to build extensions multiple times for eg. 1.5 and 1.6. But you shouldn't need to have anything more than Python installed to install Python modules from an RPM; the same goes for other built distribution formats.) Also, even when we *can* assume that, we won't be including the setup script in the (binary) RPM (or whatever). So while we could still use the many useful utility functions provided by distutils.*_util, we can't make use of whatever goodies the developer has put in his setup script, like the name of the distribution or the modules it installs. > Hmm, I still don't see why you can't add attribute access methods > which check and possibly control the forementioned problems. > A few .set_this() and .get_that() methods would make the interface > more transparent, add documentation (by virtue of __doc__ strings ;-) > and could add check assertions. [...] > Why not let the .set_this() method take care of getting the > state right ? (or raise an exception if that's impossible) [...] > In my experience, it's always better to define object access > via methods rather than attributes. This is especially true > when the projects evolves with time: you simply forget about > the details, side-effects, assertions you made months ago > (and possibly forgot to document) about the specific > attributes. I'm moving in the direction of more bureaucracy for command options. We're a long way from "out-of-control", but the system has grown considerably in the last couple of months. There are dependencies and interactions between commands that are only documented in code, default values, type/syntax expectations -- all sorts of things that might be better off under a more bondage 'n discipline regime. One aspect of that regime would be automatic accessor and modifier methods provided by the Command class. However, this is not a high priority for Distutils 1.0. For now, I'm more interested in solving the problem of building, installing, and distributing Python module distributions; I'm inclined to worry about imposing more bureaucracy on the Distutils inner workings in the future. Greg -- Greg Ward - Unix nerd gward@python.net http://starship.python.net/~gward/ Hand me a pair of leather pants and a CASIO keyboard -- I'm living for today! From hgebel@inet.net Thu Jun 1 03:09:50 2000 From: hgebel@inet.net (Harry Henry Gebel) Date: Wed, 31 May 2000 22:09:50 -0400 Subject: [Distutils] Suggested directory convention In-Reply-To: ; from mwa@gate.net on Wed, May 31, 2000 at 09:44:04PM -0400 References: <20000531200337.A489@beelzebub> Message-ID: <20000531220950.A14755@inet.net> On Wed, May 31, 2000 at 09:44:04PM -0400, Mark W. Alexander wrote: > In some cases, I would like to do the same with Python > packages, e.g. have the "dist" directory installed under > the package installation directory. It's frequently > usefull to have access to pre/post install scripts > at other times, and they're generally not big enough to > be a space concern. And binary package making commands like bdist_rpm could look in the directory to find the default scripts, which would make one less thing to put into package_data (in fact, maybe this could almost eliminate package_data if configuration, build, and install scripts were placed here, I think most other parts of package_data could be moved into setup.py as meta-data.) -- Harry Henry Gebel, Senior Developer, Landon House SBS West Dover Hundred, Delaware From gward@python.net Thu Jun 1 03:34:55 2000 From: gward@python.net (Greg Ward) Date: Wed, 31 May 2000 22:34:55 -0400 Subject: [Distutils] Suggested directory convention In-Reply-To: <20000531220950.A14755@inet.net>; from Harry Henry Gebel on Wed, May 31, 2000 at 10:09:50PM -0400 References: <20000531200337.A489@beelzebub> <20000531220950.A14755@inet.net> Message-ID: <20000531223455.C677@beelzebub> On 31 May 2000, Harry Henry Gebel said: > And binary package making commands like bdist_rpm could look in the > directory to find the default scripts, which would make one less thing to > put into package_data (in fact, maybe this could almost eliminate > package_data if configuration, build, and install scripts were placed here, > I think most other parts of package_data could be moved into setup.py as > meta-data.) Actually, tonight I started work on making package_data entirely obsolete by putting that information in the config file, setup.cfg. Here's what it would look like: [bdist_rpm] release = 3 packager = Harry Henry Gebel doc = CHANGES.txt README.txt USAGE.txt doc/ examples/ changelog = * Wed May 31 2000 Greg Ward 0.8.3pre-1 - Hacked up bdist_rpm.py, moved meta-data into setup.cfg * Thu May 10 2000 Harry Henry Gebel 0.8.2-3 - Added new options to package_data * Tue May 09 2000 Harry Henry Gebel 0.8.2-2 - Include RPM_OPT_FLAGS in distutils * Wed Apr 26 2000 Harry Henry Gebel 0.8.2-1 - First test of bdist_rpm Look familiar? There are some whitespace issues with the changelog, and I don't see a good way to map your multi-locale "summaries" and "descriptions" dictionaries to options in the config file. Maybe a complicated string like "key: value, key: value", but it would have to be shlex'd to allow quoting keys and values. The code's in upheaval at the moment, so not checked in. But I did check in some other changes to bdist_rpm that you should keep on top of! Oops, that was off-topic as hell. Oh well. Sounds like the "dist" directory is a winner. Now I just have to figure out what goes there and what goes in "build/bdist./"... Greg -- Greg Ward - Linux nerd gward@python.net http://starship.python.net/~gward/ It has just been discovered that research causes cancer in rats. From gward@python.net Fri Jun 2 02:38:49 2000 From: gward@python.net (Greg Ward) Date: Thu, 1 Jun 2000 21:38:49 -0400 Subject: [Distutils] RPM questions Message-ID: <20000601213849.A650@beelzebub> [oops, meant to cc this to the sig] Hi Harry -- [and any other distutils-siggies who know more about RPM than me] I'm beating the hell out of the bdist_rpm command to make it use config files rather than the "package_data" file, and naturally a few questions about RPM arise. Thought I'd ask you and the SIG instead of RTFM'ing. (Hey, I don't have a copy of the RPM book at home... and I have to mooch off someone else's at work.) * are the {pre,post}_{install,uninstall} scripts specified as raw shell code or filenames? * if raw code, d'you think it would be acceptable to specify them as filenames for the Distutils instead of trying to deal with shell (or Python!) code in a config file? * I'm punting on preserving the 'summaries' and 'descriptions' dictionaries: either we craft a mapping syntax in config files, or we expand 'description' and 'long_description' in the setup script so they can be either a string (English description) or a dictionary mapping 2-letter language codes to description in that language. Opinions? * what is "prep" for? is that a pre-build script? is it basically the same as {pre,post}_{install,uninstall}? * what should the default for "packager" be? I initially made it default to "vendor" (which in turn defaults to the "contact" from the setup script, ie. maintainer if present, author otherwise), but then I had a dim recollection that packagers can set their name/address in an RPM config file. True? Should "packager" default to nothing, so RPM fills it in? * should "release" be a string or a number? I've never seen a Red Hat RPM with a non-integer "release", but what're the rules? * what is "serial"? * do you have an example Python module distribution that actually uses most of the RPM options? The Distutils distribution is pretty simple, so I can't fully test "bdist_rpm" with it. * is it really necessary to pass the "--define _topdir ..." to RPM? Recall that this breaks under RPM 2.x, and since I *still* haven't gotten around to upgrading my Red Hat 5.2 system, this bites me. (Who? me? procrastinating?) OK! Enough of that; the good news is, I've rebuild enough of "bdist_rpm" that we're back where we started, ie. it fails-to-work for me just as it failed-to-work before I started ripping it apart. IOW, it creates a reasonable-looking spec file, but dies because of the "rpm --define" option. Well, guess what's next on my agenda. Anyways, using the same ol' Distutils setup script that we're all familiar with, and this setup.cfg: """ [bdist_rpm] release = 3 packager = Harry Henry Gebel doc_files = CHANGES.txt README.txt USAGE.txt doc/ examples/ changelog = * Wed May 31 2000 Greg Ward 0.8.3pre-1 - Hacked up bdist_rpm.py, moved meta-data into setup.cfg * Thu May 10 2000 Harry Henry Gebel 0.8.2-3 - Added new options to package_data * Tue May 09 2000 Harry Henry Gebel 0.8.2-2 - Include RPM_OPT_FLAGS in distutils * Wed Apr 26 2000 Harry Henry Gebel 0.8.2-1 - First test of bdist_rpm """ I can now run "setup.py bdist_rpm --spec-only" and get this spec file: """ %define name Distutils %define version 0.8.3pre %define release 3 Summary: Python Distribution Utilities Name: %{name} Version: %{version} Release: %{release} Source0: %{name}-%{version}.tar.gz Copyright: Python Group: Development/Libraries BuildRoot: %{_tmppath}/%{name}-buildroot Prefix: %{_prefix} BuildArchitectures: noarch Vendor: Greg Ward Packager: Harry Henry Gebel Url: http://www.python.org/sigs/distutils-sig/ %description A collection of modules to aid in the distribution and installation of Python modules, extensions, and (ultimately) applications. A standard part of Python 1.6, but also distributed separately for use with Python 1.5. %prep %setup %build python setup.py build %install python setup.py install --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES %clean rm -rf $RPM_BUILD_ROOT %files -f INSTALLED_FILES %defattr(-,root,root) %doc CHANGES.txt README.txt USAGE.txt doc/ examples/ %changelog * Wed May 31 2000 Greg Ward 0.8.3pre-1 - Hacked up bdist_rpm.py, moved meta-data into setup.cfg * Thu May 10 2000 Harry Henry Gebel 0.8.2-3 - Added new options to package_data * Tue May 09 2000 Harry Henry Gebel 0.8.2-2 - Include RPM_OPT_FLAGS in distutils * Wed Apr 26 2000 Harry Henry Gebel 0.8.2-1 - First test of bdist_rpm """ Cool! Note that the formatting of the changelog is slightly mutilated by ConfigParser. ;-( I dunno how sensitive RPM is about this; guess I'll find out soon enough! Greg -- Greg Ward - Unix bigot gward@python.net http://starship.python.net/~gward/ I'd rather have a bottle in front of me than have to have a frontal lobotomy. From robin@jessikat.demon.co.uk Fri Jun 2 10:14:46 2000 From: robin@jessikat.demon.co.uk (Robin Becker) Date: Fri, 2 Jun 2000 10:14:46 +0100 Subject: [Distutils] Win32+Numpy+distutils 0.8 problem Message-ID: For some reason I'm getting this with the latest 15.3 tgz. This is with distutils 0.8. Seems as though the search for the python include directory has again failed somewhere. C:\Program Files\Microsoft Visual Studio\VC98\BIN\cl.exe /c /nologo /Ox /MD /W3 -I""\include\python1.5 -IInclude -I""\Include /TcSrc/_numpymodule.c /Fobuild\tem p.win32\Release\Src/_numpymodule.obj _numpymodule.c Src/_numpymodule.c(1) : fatal error C1083: Cannot open include file: 'Python.h': No such file or directory error: command '"C:\Program Files\Microsoft Visual Studio\VC98\BIN\cl.exe"' fail ed with exit status 2 -- Robin Becker From robin@jessikat.demon.co.uk Fri Jun 2 13:23:29 2000 From: robin@jessikat.demon.co.uk (Robin Becker) Date: Fri, 2 Jun 2000 13:23:29 +0100 Subject: [Distutils] Win32+Numpy+distutils 0.8 problem In-Reply-To: References: Message-ID: In article , Robin Becker writes >For some reason I'm getting this with the latest 15.3 tgz. This is with >distutils 0.8. Seems as though the search for the python include >directory has again failed somewhere. > >C:\Program Files\Microsoft Visual Studio\VC98\BIN\cl.exe /c /nologo /Ox >/MD /W3 >-I""\include\python1.5 -IInclude -I""\Include /TcSrc/_numpymodule.c >/Fobuild\tem >p.win32\Release\Src/_numpymodule.obj >_numpymodule.c >Src/_numpymodule.c(1) : fatal error C1083: Cannot open include file: >'Python.h': > No such file or directory >error: command '"C:\Program Files\Microsoft Visual >Studio\VC98\BIN\cl.exe"' fail >ed with exit status 2 > OK the latest CVS fixes this. -- Robin Becker From hgebel@inet.net Fri Jun 2 14:12:09 2000 From: hgebel@inet.net (Harry Henry Gebel) Date: Fri, 2 Jun 2000 09:12:09 -0400 Subject: [Distutils] RPM questions In-Reply-To: <20000601213849.A650@beelzebub>; from gward@python.net on Thu, Jun 01, 2000 at 09:38:49PM -0400 References: <20000601213849.A650@beelzebub> Message-ID: <20000602091209.A705@inet.net> On Thu, Jun 01, 2000 at 09:38:49PM -0400, Greg Ward wrote: > (Hey, I don't have a copy of the RPM book at home... and I have to mooch > off someone else's at work.) That's okay, the manual is horribly out of date anyhow (still based on RPM 2). > * are the {pre,post}_{install,uninstall} scripts specified as > raw shell code or filenames? > > * if raw code, d'you think it would be acceptable to specify them as > filenames for the Distutils instead of trying to deal with shell (or > Python!) code in a config file? They are placed into the spec file as raw code, but it would probably be better for the config file to refer to a file on disk, that saves from having to work about multi-line strings (like package_data), etc. Then just copy the contents of the file into the spec. Plus that way multiple distribution formats could all refer to the same install/uninstall scripts if appropriate. > * I'm punting on preserving the 'summaries' and 'descriptions' > dictionaries: either we craft a mapping syntax in config files, or > we expand 'description' and 'long_description' in the setup script > so they can be either a string (English description) or a dictionary > mapping 2-letter language codes to description in that language. > Opinions? I was trying to think of the best way to put it in the config file, but maybe the setup script would be better, certainly I think that Debian support multiple locales and alot of other packaging formats probably do as well, so it is something that has utility outside of just bdist_rpm. > * what is "prep" for? is that a pre-build script? is it basically > the same as {pre,post}_{install,uninstall}? RPM wants source to be in the directory 'BUILD/package-version', the prep script it a script that unpacks the original source file or files and into this directory and applies any patches. For most Distutils modules it will '%setup' which is a macro that just extracts Source0 into BUILD. > * what should the default for "packager" be? I initially made it > default to "vendor" (which in turn defaults to the "contact" from > the setup script, ie. maintainer if present, author otherwise), but > then I had a dim recollection that packagers can set their > name/address in an RPM config file. True? Should "packager" > default to nothing, so RPM fills it in? Packager should be the person who is in charge of maintaining the RPM, it should be left blank if there is no such person. This would be appropriate for the [bdist_rpm] section of the config file since each packing format will likely have somebody else in charge of it (at least if most developers out there are like me and don't run a wide variety of operating systems/distributions). > * should "release" be a string or a number? I've never seen a Red Hat > RPM with a non-integer "release", but what're the rules? Release can be any alphanumeric string, for example Mandrake RPMs start at release '1mdk', then '2mdk', etc. I am using Helix Gnome and the release is the unlikely string '0mdk_helix_1' (a very poor choice on Helix's part IMHO). As long as the alphabetical portion remains the same RPM can still keep the releases in order. > * what is "serial"? This is for packages with version naming scheme that causes RPM to not be able to put packages in the correct order; for example, RPM will classify version 2.0b as being newer than 2.0 , if 2.0b is that package's way of designating a beta release then RPM will complain about trying to install an older release over a newer release when trying to upgrade to the final release. If serial is specified then RPM ignores the version when it figures out what packages are newer and older. Serial isn't used much because once you start using it you have to keep using it forever if you want RPM to keep putting your packages in the right order; most people (like me) who use alot of betas and prereleases just learn to use `rpm --force`. > * do you have an example Python module distribution that actually uses > most of the RPM options? The Distutils distribution is pretty > simple, so I can't fully test "bdist_rpm" with it. Nope, PyNcurses is also pretty simple. There are alot of python modules out there, maybe somebody could point out a good one to experiment with? > * is it really necessary to pass the "--define _topdir ..." to RPM? > Recall that this breaks under RPM 2.x, and since I *still* haven't > gotten around to upgrading my Red Hat 5.2 system, this bites > me. (Who? me? procrastinating?) This is being used to allow bdist_rpm to tell RPM where to find everything; I asked both an this list and the RPM list if anyone knew a reliable way of determining this but no one did so I was forced to specify a specific location. Unfortunately in RPM 2 there was no way of specifying where to put things on the command line, it had to be done in the rc file. And to make matters worse RPM's internals were completely changed between RPM 2 and RPM 3, and the changes resulted in different rc file formats. The only way I can see to get around it for RPM 2 compatibility is to specify on the setup.py command line the directories to use, then you could remove the '--define topdir' option. > OK! Enough of that; the good news is, I've rebuild enough of > "bdist_rpm" that we're back where we started, ie. it fails-to-work for me > just as it failed-to-work before I started ripping it apart. IOW, it > creates a reasonable-looking spec file, but dies because of the "rpm > --define" option. Well, guess what's next on my agenda. I will test tonight to see if works with RPM 3. -- Harry Henry Gebel, Senior Developer, Landon House SBS West Dover Hundred, Delaware From aa8vb@yahoo.com Fri Jun 2 14:42:38 2000 From: aa8vb@yahoo.com (Randall Hopper) Date: Fri, 02 Jun 2000 09:42:38 -0400 Subject: [Distutils] -I paths and ext_modules Message-ID: <20000602094238.A3357531@vislab.epa.gov> Thought I'd try packaging up an OpenDX wrapper using the new Distutils. I need to get a -I path on the cc command line (and a -L/-rpath on the linker line). Is there a way to do this with the current version (portably or UNIX-specific; either one)? I gather from the docs that the Setup Configuration File will eventually take care of this third-party software path configuration. I'm looking for a stopgap until then. If not, is there a "!shell " backdoor that can be used in the meantime? Thanks, Randall -- Randall Hopper (mailto:aa8vb@yahoo.com) EPA Scientific Visualization Center US EPA MD/24 ERC-1A; RTP, NC 27711 From aa8vb@yahoo.com Fri Jun 2 15:02:29 2000 From: aa8vb@yahoo.com (Randall Hopper) Date: Fri, 02 Jun 2000 10:02:29 -0400 Subject: [Distutils] Confusing options error msg Message-ID: <20000602100229.A3343172@vislab.epa.gov> Something else I noticed a bit earlier. If you supply all three of: packages, py_modules, and ext_modules, you get an error that says: > setup.py build running build running build_py error: build_py: supplying both 'packages' and 'modules' options is not allowed It's not clear from the message which *_modules variable/variables are the problem. Based on PyNcurses's and Numerical's setup.py files, it's apparent that py_modules is the culprit. Removing it lets the build continue. That said, I do like how easy it appears it's going to be to build and distribution module dists with the new DistUtils. Copy setup.py, tweak, and build. Very nice. Randall From hgebel@inet.net Fri Jun 2 17:13:47 2000 From: hgebel@inet.net (Harry Henry Gebel) Date: Fri, 2 Jun 2000 12:13:47 -0400 Subject: [Distutils] bdist_rpm patch Message-ID: <20000602121347.C705@inet.net> --17pEHd4RhPHOinZp Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Here is a patch against the current CVS version of Distutils to make it build RPMs with RPM 3. -- Harry Henry Gebel, Senior Developer, Landon House SBS West Dover Hundred, Delaware --17pEHd4RhPHOinZp Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="bdist_rpm.patch" Index: distutils/command/bdist_rpm.py =================================================================== RCS file: /cvsroot/python/distutils/distutils/command/bdist_rpm.py,v retrieving revision 1.8 diff -u -r1.8 bdist_rpm.py --- distutils/command/bdist_rpm.py 2000/06/02 02:01:51 1.8 +++ distutils/command/bdist_rpm.py 2000/06/02 16:12:04 @@ -308,9 +308,8 @@ rpm_args.append('-bb') else: rpm_args.append('-ba') - topdir = os.getcwd() + 'build/rpm' rpm_args.extend(['--define', - '_topdir ' + os.getcwd() + '/build/rpm',]) + '_topdir %s/%s' % (os.getcwd(), rpm_base),]) if self.clean: rpm_args.append('--clean') rpm_args.append(spec_path) --17pEHd4RhPHOinZp-- From gpk@bell-labs.com Fri Jun 2 17:14:06 2000 From: gpk@bell-labs.com (Greg Kochanski) Date: Fri, 02 Jun 2000 12:14:06 -0400 Subject: [Distutils] bug in install_scripts Message-ID: <3937DD4E.E015ACD8@bell-labs.com> If you are installing from .../bin/foo to /usr/local/bin/foo, distutils installs correctly, but then reports an error when it incorrectly tries to chmod the file /usr/local/bin/bin/foo . The problem seems to be in .../distutils/cmd.py, in the function _copy_files(). It looks as if it should not just do os.path.join, but should drop off the directory parts of f, first with os.path.basename(). setup.py: from distutils.core import setup setup(name="promu1python", version="1.0", description = "Stem-ML level 1 tag set", author = "Greg Kochanski", author_email = "gpk@bell-labs.com", url="http://hce.research.bell-labs.com/promu1python", scripts = ["bin/promu1.sh"], packages = ["promu1python"]) From gward@python.net Sat Jun 3 01:53:21 2000 From: gward@python.net (Greg Ward) Date: Fri, 2 Jun 2000 20:53:21 -0400 Subject: [Distutils] -I paths and ext_modules In-Reply-To: <20000602094238.A3357531@vislab.epa.gov>; from Randall Hopper on Fri, Jun 02, 2000 at 09:42:38AM -0400 References: <20000602094238.A3357531@vislab.epa.gov> Message-ID: <20000602205321.B326@beelzebub> On 02 June 2000, Randall Hopper said: > I need to get a -I path on the cc command line (and a -L/-rpath on the > linker line). Is there a way to do this with the current version (portably > or UNIX-specific; either one)? Just put 'include_dirs' and 'library_dirs' elements in dictionaries at the bottom of the 'ext_modules' list-of-tuples-of-dictionaries. Eg. see examples/mxdatetime_setup.py: ext_modules = [('DateTime.mxDateTime.mxDateTime', { 'sources': ['mxDateTime/mxDateTime.c'], 'include_dirs': ['mxDateTime'], } )] 'library_dirs' is similar. Note that this is a lot less hairy in the current CVS code: ext_modules = [Extension('DateTime.mxDateTime.mxDateTime', ['mxDateTime/mxDateTime.c'], include_dirs=['mxDateTime'] ) ] And if this is a setting that users have to override (eg. "specify the include directories for libfoo here"), the config file code in the current CVS will handly this nicely. Right, enough screwing around -- definitely time to write some docs and tests and get 0.9 out the door. Greg -- Greg Ward - just another /P(erl|ython)/ hacker gward@python.net http://starship.python.net/~gward/ Budget's in the red? Let's tax religion! -- Dead Kennedys From gward@python.net Sat Jun 3 01:58:36 2000 From: gward@python.net (Greg Ward) Date: Fri, 2 Jun 2000 20:58:36 -0400 Subject: [Distutils] Confusing options error msg In-Reply-To: <20000602100229.A3343172@vislab.epa.gov>; from Randall Hopper on Fri, Jun 02, 2000 at 10:02:29AM -0400 References: <20000602100229.A3343172@vislab.epa.gov> Message-ID: <20000602205836.C326@beelzebub> On 02 June 2000, Randall Hopper said: > error: build_py: supplying both 'packages' and 'modules' options is not allowed > > It's not clear from the message which *_modules variable/variables are the > problem. Based on PyNcurses's and Numerical's setup.py files, it's > apparent that py_modules is the culprit. Removing it lets the build > continue. Good point -- I've just changed 'self.modules' in build_py.py to 'self.py_modules', both for consistency and so that I can fix the error message without barfing. Thanks! Greg -- Greg Ward - programmer-at-large gward@python.net http://starship.python.net/~gward/ There are no stupid questions -- only stupid people. From gward@python.net Sat Jun 3 02:03:18 2000 From: gward@python.net (Greg Ward) Date: Fri, 2 Jun 2000 21:03:18 -0400 Subject: [Distutils] bdist_rpm patch In-Reply-To: <20000602121347.C705@inet.net>; from Harry Henry Gebel on Fri, Jun 02, 2000 at 12:13:47PM -0400 References: <20000602121347.C705@inet.net> Message-ID: <20000602210318.D326@beelzebub> On 02 June 2000, Harry Henry Gebel said: > Here is a patch against the current CVS version of Distutils to make it > build RPMs with RPM 3. Checked in, thanks. Greg -- Greg Ward - programmer-at-big gward@python.net http://starship.python.net/~gward/ Time flies like an arrow; fruit flies like a banana. From gward@python.net Sat Jun 3 02:24:42 2000 From: gward@python.net (Greg Ward) Date: Fri, 2 Jun 2000 21:24:42 -0400 Subject: [Distutils] bug in install_scripts In-Reply-To: <3937DD4E.E015ACD8@bell-labs.com>; from Greg Kochanski on Fri, Jun 02, 2000 at 12:14:06PM -0400 References: <3937DD4E.E015ACD8@bell-labs.com> Message-ID: <20000602212442.F326@beelzebub> On 02 June 2000, Greg Kochanski said: > If you are installing from .../bin/foo to /usr/local/bin/foo, > distutils installs correctly, but then reports an error when > it incorrectly tries to chmod the file /usr/local/bin/bin/foo . > > The problem seems to be in .../distutils/cmd.py, in the function > _copy_files(). > It looks as if it should not just do os.path.join, but should > drop off the directory parts of f, first with os.path.basename(). I can't reproduce this. If you're referring to the '_copy_files()' method in install_misc, it can't be that, because that class isn't (currently) used anywhere. Can you tell us which Distutils version you're using, which version of Python, and which OS? And show us exactly the command(s) issued and the complete output you got? I can't reach your web site right now; if I could I'd try to go download your tarball and try it myself. If it's no more than 50k, can you mail it directly to me (gward@python.net)? Thanks... Greg -- Greg Ward - geek-at-large gward@python.net http://starship.python.net/~gward/ Just because you're paranoid doesn't mean they *aren't* out to get you. From calvin@cs.uni-sb.de Sat Jun 3 16:20:33 2000 From: calvin@cs.uni-sb.de (Bastian Kleineidam) Date: Sat, 3 Jun 2000 17:20:33 +0200 (CEST) Subject: [Distutils] two bugs In-Reply-To: <3937DD4E.E015ACD8@bell-labs.com> Message-ID: Hello, I discovered a minor glitch in install_data.py, line 59, in get_outputs(self): replace return self.outfiles with return self.outfiles or [] to ensure a list is returned and not the None object. Another bug I found: When I run # python setup.py sdist bdist_rpm I get the following traceback: [snipped] running bdist_rpm writing 'build/bdist.linux2-i686/rpm/SPECS/linkchecker.spec' Traceback (innermost last): File "setup.py", line 100, in ? data_files = [('locale/de/LC_MESSAGES', File "/usr/lib/python1.5/site-packages/distutils/core.py", line 111, in setup dist.run_commands () File "setup.py", line 32, in run_commands self.run_command (cmd) File "/usr/lib/python1.5/site-packages/distutils/dist.py", line 757, in run_command cmd_obj.run () File "/usr/lib/python1.5/site-packages/distutils/command/bdist_rpm.py", line 290, in run source = sdist.get_archive_files()[0] TypeError: unsubscriptable object Here is why: bdist_rpm.py:283: sdist = self.reinitialize_command ('sdist') now sdist is _not_ finalized bdist_rpm.py:288: self.run_command('sdist') now sdist is _still_ not finalized! this is because we have run 'sdist' before and wrote this in the cache: dist.py:751: if self.have_run.get (command): return and therefore sdist.get_archive_files() returns None which is not subscriptable I have no fix for this bug. Probly you should insert in Distribution.reinitialize_command() the line self.have_run[commandname] = 0 before the return. Bastian From hgebel@inet.net Sun Jun 4 08:07:00 2000 From: hgebel@inet.net (Harry Henry Gebel) Date: Sun, 4 Jun 2000 03:07:00 -0400 Subject: [Distutils] Patch to bdist_rpm Message-ID: <20000604030700.B5468@inet.net> --LQksG6bCIzRHxTLp Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Here is a patch to bdist_rpm. It does the following: Fills in question marks in help Reads scripts in from files rather than strings Adds RPM 2 compatibility mode (untested). Use of this mode requires that --bdist-base be specified because bdist_rpm has no way of detecting where RPM wants to find spec files and source files. An unmodified RedHat 5.0 system would require '--bdist-base=/usr/src/RedHat'. (You would also have to be root.) If the rpmrc file has been modified to allow RPMs to be built by normal users then --build-base would need to be changed accordingly. Formats the changelog. -- Harry Henry Gebel, Senior Developer, Landon House SBS West Dover Hundred, Delaware --LQksG6bCIzRHxTLp Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="bdist_rpm.patch" Index: setup.cfg =================================================================== RCS file: /cvsroot/python/distutils/setup.cfg,v retrieving revision 1.1 diff -u -r1.1 setup.cfg --- setup.cfg 2000/06/02 02:07:43 1.1 +++ setup.cfg 2000/06/04 06:54:04 @@ -19,7 +19,7 @@ formats=gztar,zip [bdist_rpm] -release = 3 +release = 1 packager = Harry Henry Gebel doc_files = CHANGES.txt README.txt @@ -28,6 +28,10 @@ examples/ changelog = + * Sun Jun 04 2000 Harry Henry Gebel 0.9pre-1 + - Made sure scripts are file names, filled in some help strings, formatted + changelog correctly + * Wed May 31 2000 Greg Ward 0.8.3pre-1 - Hacked up bdist_rpm.py, moved meta-data into setup.cfg Index: distutils/command/bdist_rpm.py =================================================================== RCS file: /cvsroot/python/distutils/distutils/command/bdist_rpm.py,v retrieving revision 1.9 diff -u -r1.9 bdist_rpm.py --- distutils/command/bdist_rpm.py 2000/06/03 01:03:55 1.9 +++ distutils/command/bdist_rpm.py 2000/06/04 06:54:06 @@ -42,7 +42,7 @@ ('release', None, "RPM release number"), ('serial', None, - "???"), + "RPM serial number"), ('vendor', None, "RPM \"vendor\" (eg. \"Joe Blow \") " "[default: maintainer or author from setup script]"), @@ -52,18 +52,17 @@ ('doc-files', None, "list of documentation files (space or comma-separated)"), ('changelog', None, - "RPM changelog"), + "path to RPM changelog"), ('icon', None, "name of icon file"), - - ('prep-cmd', None, - "?? pre-build command(s) ??"), - ('build-cmd', None, - "?? build command(s) ??"), - ('install-cmd', None, - "?? installation command(s) ??"), - ('clean-cmd', None, - "?? clean command(s) ??"), + ('prep-script', None, + "pre-build script (Bourne shell code)"), + ('build-script', None, + "build script (Bourne shell code)"), + ('install-script', None, + "installation script (Bourne shell code)"), + ('clean-script', None, + "clean script (Bourne shell code)"), ('pre-install', None, "pre-install script (Bourne shell code)"), ('post-install', None, @@ -72,17 +71,16 @@ "pre-uninstall script (Bourne shell code)"), ('post-uninstall', None, "post-uninstall script (Bourne shell code)"), - ('provides', None, - "???"), + "capabilities provided by this package"), ('requires', None, - "???"), + "capabilities required by this package"), ('conflicts', None, - "???"), + "capabilities which conflict with this package"), ('build-requires', None, - "???"), + "capabilities required to build this package"), ('obsoletes', None, - "???"), + "capabilities made obsolete by this package"), # Actions to take when building RPM ('clean', None, @@ -93,10 +91,15 @@ "compile with RPM_OPT_FLAGS when building from source RPM"), ('no-rpm-opt-flags', None, "do not pass any RPM CFLAGS to compiler"), + ('rpm3-mode', None, + "RPM 3 compatibility mode (default)"), + ('rpm2-mode', None, + "RPM 2 compatibility mode"), ] negative_opt = {'no-clean': 'clean', - 'no-rpm-opt-flags': 'use-rpm-opt-flags'} + 'no-rpm-opt-flags': 'use-rpm-opt-flags', + 'rpm2-mode': 'rpm3-mode'} def initialize_options (self): @@ -116,10 +119,10 @@ self.changelog = None self.icon = None - self.prep_cmd = None - self.build_cmd = None - self.install_cmd = None - self.clean_cmd = None + self.prep_script = None + self.build_script = None + self.install_script = None + self.clean_script = None self.pre_install = None self.post_install = None self.pre_uninstall = None @@ -133,6 +136,7 @@ self.clean = 1 self.use_rpm_opt_flags = 1 + self.rpm3_mode = 1 # initialize_options() @@ -160,31 +164,28 @@ self.ensure_string('vendor', "%s <%s>" % (self.distribution.get_contact(), self.distribution.get_contact_email())) - self.ensure_string('packager', self.vendor) # or nothing? + self.ensure_string('packager') self.ensure_string_list('doc_files') if type(self.doc_files) is ListType: for readme in ('README', 'README.txt'): if os.path.exists(readme) and readme not in self.doc_files: self.doc.append(readme) - self.ensure_string('release', "1") # should it be an int? + self.ensure_string('release', "1") self.ensure_string('serial') # should it be an int? - self.ensure_string('icon') self.ensure_string('distribution_name') - self.ensure_string('prep_cmd', "%setup") # string or filename? + self.ensure_string('changelog') + # Format changelog correctly + self.changelog = self._format_changelog(self.changelog) - if self.use_rpm_opt_flags: - def_build = 'env CFLAGS="$RPM_OPT_FLAGS" python setup.py build' - else: - def_build = 'python setup.py build' - self.ensure_string('build_cmd', def_build) - self.ensure_string('install_cmd', - "python setup.py install --root=$RPM_BUILD_ROOT " - "--record=INSTALLED_FILES") - self.ensure_string('clean_cmd', - "rm -rf $RPM_BUILD_ROOT") + self.ensure_filename('icon') + + self.ensure_filename('prep_script') + self.ensure_filename('build_script') + self.ensure_filename('install_script') + self.ensure_filename('clean_script') self.ensure_filename('pre_install') self.ensure_filename('post_install') self.ensure_filename('pre_uninstall') @@ -259,7 +260,11 @@ spec_dir = "dist" self.mkpath(spec_dir) # XXX should be configurable else: - rpm_base = os.path.join(self.bdist_base, "rpm") + if self.rpm3_mode: + rpm_base = os.path.join(self.bdist_base, "rpm") + else: + # complete path must be specified in RPM 2 mode + rpm_base = self.bdist_base rpm_dir = {} for d in ('SOURCES', 'SPECS', 'BUILD', 'RPMS', 'SRPMS'): rpm_dir[d] = os.path.join(rpm_base, d) @@ -308,8 +313,9 @@ rpm_args.append('-bb') else: rpm_args.append('-ba') - rpm_args.extend(['--define', - '_topdir %s/%s' % (os.getcwd(), rpm_base),]) + if self.rpm3_mode: + rpm_args.extend(['--define', + '_topdir %s/%s' % (os.getcwd(), rpm_base),]) if self.clean: rpm_args.append('--clean') rpm_args.append(spec_path) @@ -405,27 +411,43 @@ # ]) # rpm scripts - for (rpm_opt, attr) in (('prep', 'prep_cmd'), - ('build', 'build_cmd'), - ('install', 'install_cmd'), - ('clean', 'clean_cmd'), - ('pre', 'pre_install'), - ('post', 'post_install'), - ('preun', 'pre_uninstall'), - ('postun', 'post_uninstall')): - # XXX oops, this doesn't distinguish between "raw code" - # options and "script filename" options -- well, we probably - # should settle on one or the other, and not make the - # distinction! + # figure out default build script + if self.use_rpm_opt_flags: + def_build = 'env CFLAGS="$RPM_OPT_FLAGS" python setup.py build' + else: + def_build = 'python setup.py build' + # insert contents of files + for (rpm_opt, attr, default) in (('prep', 'prep_script', + "%setup"), + ('build', 'build_script', + def_build), + ('install', 'install_script', + "python setup.py install " + "--root=$RPM_BUILD_ROOT " + "--record=INSTALLED_FILES"), + ('clean', 'clean_script', + "rm -rf $RPM_BUILD_ROOT"), + ('pre', 'pre_install', + None), + ('post', 'post_install', + None), + ('preun', 'pre_uninstall', + None), + ('postun', 'post_uninstall', + None)): + # Insert contents of file refered to, if no file is refered to + # use 'default' as contents of script val = getattr(self, attr) - if val: + if val or default: spec_file.extend([ '', - '%' + rpm_opt, - val - ]) + '%' + rpm_opt,]) + if val: + spec_file.extend(string.split(open(val, 'r').read(), '\n')) + else: + spec_file.append(default) - + # files section spec_file.extend([ '', @@ -439,12 +461,32 @@ if self.changelog: spec_file.extend([ '', - '%changelog', - self.changelog - ]) + '%changelog',]) + spec_file.extend(self.changelog) return spec_file # _make_spec_file () + + def _format_changelog(self, changelog): + """Format the changelog correctly and convert it to a list of strings + """ + new_changelog = [] + for line in string.split(string.strip(changelog), '\n'): + line = string.strip(line) + if line[0] == '*': + new_changelog.extend(['', line]) + elif line[0] == '-': + new_changelog.append(line) + else: + new_changelog.append(' ' + line) + + # strip trailing newline inserted by first changelog entry + if not new_changelog[0]: + del new_changelog[0] + + return new_changelog + + # _format_changelog() # class bdist_rpm --LQksG6bCIzRHxTLp-- From gward@python.net Sun Jun 4 15:38:59 2000 From: gward@python.net (Greg Ward) Date: Sun, 4 Jun 2000 10:38:59 -0400 Subject: [Distutils] Patch to bdist_rpm In-Reply-To: <20000604030700.B5468@inet.net>; from Harry Henry Gebel on Sun, Jun 04, 2000 at 03:07:00AM -0400 References: <20000604030700.B5468@inet.net> Message-ID: <20000604103859.A1211@beelzebub> On 04 June 2000, Harry Henry Gebel said: > Here is a patch to bdist_rpm. It does the following: Cool, thanks. A few comments... > Reads scripts in from files rather than strings Then why do the help strings say --prep-script pre-build script (Bourne shell code) --build-script build script (Bourne shell code) --install-script installation script (Bourne shell code) --clean-script clean script (Bourne shell code) --pre-install pre-install script (Bourne shell code) --post-install post-install script (Bourne shell code) --pre-uninstall pre-uninstall script (Bourne shell code) --post-uninstall post-uninstall script (Bourne shell code) ? My automatic response to those help messages would be setup.py bdist_rpm \ --post-install="echo 'thanks for installing me" \ --pre-uninstall="echo 'you bastard! how dare you uninstall me?'" ie., put unadorned shell code into the appropriate "bdist_rpm" options. Now I'm totally confused about the right way to proceed. Considerations: * you might prefer to write your {pre,post}-{install,uninstall} scripts in Python rather than shell, especially if you'll use the same scripts on non-Unix platforms * you might have the same scripts for all platforms, or you might have distinct Unix/Windows/Mac OS scripts, or you might even have distinct Debian Linux/Red Hat Linux/Free BSD/NetBSD/Solaris/IRIX/... scripts * very similar to the above: you might have the same scripts for every type of built distribution, or you might have different ones for RPM, Debian packages, BSD packages, Thomas' homebrew Windows installer, Wise installers, etc. * you might have very simple, one-command scripts (especially if they are shell code), or complex scripts that need to go in a file * very rarely would you specify all this on the "bdist_rpm" command line -- this is the sort of stuff that the per-distribution config file (setup.cfg) is just made for I don't have a ready answer, I just thought I'd bring up these points for anyone who thinks they might. ;-( I'll leave the bdist_rpm code alone for now, since there's no point in overgeneralizing yet. > Adds RPM 2 compatibility mode (untested). Use of this mode requires that > --bdist-base be specified because bdist_rpm has no way of detecting where > RPM wants to find spec files and source files. An unmodified RedHat 5.0 > system would require '--bdist-base=/usr/src/RedHat'. (You would also have > to be root.) If the rpmrc file has been modified to allow RPMs to be built > by normal users then --build-base would need to be changed accordingly. Seems reasonable -- probably something you'd set in the site-wide Distutils config file. I'll be sure to give it a workout. I'll check your patch in shortly... Greg -- Greg Ward - programmer-at-large gward@python.net http://starship.python.net/~gward/ I just forgot my whole philosophy of life!!! From gward@python.net Sun Jun 4 15:56:10 2000 From: gward@python.net (Greg Ward) Date: Sun, 4 Jun 2000 10:56:10 -0400 Subject: [Distutils] Patch to bdist_rpm In-Reply-To: <20000604103859.A1211@beelzebub>; from Greg Ward on Sun, Jun 04, 2000 at 10:38:59AM -0400 References: <20000604030700.B5468@inet.net> <20000604103859.A1211@beelzebub> Message-ID: <20000604105610.C1211@beelzebub> On 04 June 2000, I said: > Considerations: > > * you might prefer to write your {pre,post}-{install,uninstall} > scripts in Python rather than shell, especially if you'll use > the same scripts on non-Unix platforms > > * you might have the same scripts for all platforms, or you might have > distinct Unix/Windows/Mac OS scripts, or you might even have > distinct Debian Linux/Red Hat Linux/Free BSD/NetBSD/Solaris/IRIX/... > scripts > > * very similar to the above: you might have the same scripts for every > type of built distribution, or you might have different ones for > RPM, Debian packages, BSD packages, Thomas' homebrew Windows > installer, Wise installers, etc. > > * you might have very simple, one-command scripts (especially if > they are shell code), or complex scripts that need to go in a file > > * very rarely would you specify all this on the "bdist_rpm" command > line -- this is the sort of stuff that the per-distribution config > file (setup.cfg) is just made for OK, I think I have an answer: for "bdist_rpm", just supply little snippets of shell code. If those snippets are "python /tmp/foo_postinst.py", that's fine. (I'm just guessing that post-installation scripts would go to /tmp, and I have no idea how pre-installation scripts would be handled.) IOW, I'm inclined to push the complexity onto module developers, packagers, and their config files. I simply don't understand the situation sufficiently to construct an all-singing, all-dancing, pre/post install/uninstall bureaucracy for the Distutils. Greg -- Greg Ward - just another /P(erl|ython)/ hacker gward@python.net http://starship.python.net/~gward/ "I know a lot about art, but I don't know what I like!" From gward@python.net Sun Jun 4 15:40:50 2000 From: gward@python.net (Greg Ward) Date: Sun, 4 Jun 2000 10:40:50 -0400 Subject: [Distutils] Patch to bdist_rpm In-Reply-To: <20000604030700.B5468@inet.net>; from Harry Henry Gebel on Sun, Jun 04, 2000 at 03:07:00AM -0400 References: <20000604030700.B5468@inet.net> Message-ID: <20000604104050.B1211@beelzebub> Another thought just occurred to me: should we default the "requires" list to "python-1.5.2" (or whatever the current Python version is)? Developers can of course override this, but it seems like it might be a useful default. Greg -- Greg Ward - geek-on-the-loose gward@python.net http://starship.python.net/~gward/ And now for something completely different. From gward@python.net Sun Jun 4 16:37:33 2000 From: gward@python.net (Greg Ward) Date: Sun, 4 Jun 2000 11:37:33 -0400 Subject: [Distutils] bdist_rpm and RPM 2 Message-ID: <20000604113733.D1211@beelzebub> OK, I've tried out "bdist_rpm" with RPM 2 on my Red Hat 5.2 system. I had to make "rpm_base" an option to "bdist_rpm", so now I run this: ./setup.py bdist_rpm --rpm2-mode --rpm-base=/scratch/rpmtest because my /etc/rpmrc is this: topdir: /scratch/rpmtest pgp_path: /home/greg/.pgp signature: pgp pgp_name: Greg Ward With this change, bdist_rpm successfully launches RPM, which unpacks and builds. Things start to awry with the pseudo-installation, though: it appears that RPM 2 doesn't know about the %_tmpdir macro. I'll attach the complete output of running "bdist_rpm" on the Distutils, compressed because it's quite big (40k). (Both the Distutils and RPM are very verbose: this is a feature, dammit!) Greg -- Greg Ward - programmer-at-big gward@python.net http://starship.python.net/~gward/ I feel like I am sharing a ``CORN-DOG'' with NIKITA KHRUSCHEV ... From hgebel@inet.net Mon Jun 5 04:09:08 2000 From: hgebel@inet.net (Harry Henry Gebel) Date: Sun, 4 Jun 2000 23:09:08 -0400 Subject: [Distutils] Patch to bdist_rpm In-Reply-To: <20000604104050.B1211@beelzebub>; from gward@python.net on Sun, Jun 04, 2000 at 10:40:50AM -0400 References: <20000604030700.B5468@inet.net> <20000604104050.B1211@beelzebub> Message-ID: <20000604230908.G20611@inet.net> On Sun, Jun 04, 2000 at 10:40:50AM -0400, Greg Ward wrote: > should we default the "requires" list to "python-1.5.2" (or whatever the > current Python version is)? Developers can of course override this, but > it seems like it might be a useful default. Good question, maybe it would be best to just require python and if the package requires a specific version let the packager override this. On the other hand 1.5.2 has been out for long enough that alot of modules do require it, so maybe "python >= 1.5.2" should be the default. -- Harry Henry Gebel, Senior Developer, Landon House SBS ICQ# 76308382 West Dover Hundred, Delaware From hgebel@inet.net Mon Jun 5 04:09:49 2000 From: hgebel@inet.net (Harry Henry Gebel) Date: Sun, 4 Jun 2000 23:09:49 -0400 Subject: [Distutils] Patch to bdist_rpm References: <20000604030700.B5468@inet.net> <20000604103859.A1211@beelzebub> Message-ID: <20000604230949.M20611@inet.net> On Sun, Jun 04, 2000 at 10:38:59AM -0400, Greg Ward wrote: > On 04 June 2000, Harry Henry Gebel said: > > Reads scripts in from files rather than strings > Then why do the help strings say > --prep-script pre-build script (Bourne shell code) > --build-script build script (Bourne shell code) > --install-script installation script (Bourne shell code) > --clean-script clean script (Bourne shell code) > --pre-install pre-install script (Bourne shell code) > --post-install post-install script (Bourne shell code) > --pre-uninstall pre-uninstall script (Bourne shell code) > --post-uninstall post-uninstall script (Bourne shell code) > ? My automatic response to those help messages would be > setup.py bdist_rpm \ > --post-install="echo 'thanks for installing me" \ > --pre-uninstall="echo 'you bastard! how dare you uninstall me?'" Good point; the help strings do not do a good job at indicating that a path is wanted. Unfortunately I'm not good at thinking up help strings. > * you might prefer to write your {pre,post}-{install,uninstall} > scripts in Python rather than shell, especially if you'll use > the same scripts on non-Unix platforms I will have to ask on the RPM list how people have handled using non-shell scripts; maybe insert the python script into the shell script with `python -c `? (Or `echo | python -`?) Both of these would generate a pretty sloppy looking spec file with lots of escapes (unless the author refrained from quoting with '"' and using the '$' and '\' characters), but maybe they are best; sometimes utility wins out over aesthetics. Anyhow I will see how this problem has been handled in the past as I'm sure other people have run into it. -- Harry Henry Gebel, Senior Developer, Landon House SBS ICQ# 76308382 West Dover Hundred, Delaware From aa8vb@yahoo.com Mon Jun 5 18:32:56 2000 From: aa8vb@yahoo.com (Randall Hopper) Date: Mon, 05 Jun 2000 13:32:56 -0400 Subject: [Distutils] Re: -I paths and ext_modules In-Reply-To: <20000602205321.B326@beelzebub>; from gward@python.net on Fri, Jun 02, 2000 at 08:53:21PM -0400 References: <20000602094238.A3357531@vislab.epa.gov> <20000602205321.B326@beelzebub> Message-ID: <20000605133256.A11019@vislab.epa.gov> Greg Ward: |On 02 June 2000, Randall Hopper said: |> I need to get a -I path on the cc command line (and a -L/-rpath on the |> linker line). Is there a way to do this with the current version (portably |> or UNIX-specific; either one)? | |Just put 'include_dirs' and 'library_dirs' elements in dictionaries at |the bottom of the 'ext_modules' list-of-tuples-of-dictionaries. Eg. see |examples/mxdatetime_setup.py: | | ext_modules = [('DateTime.mxDateTime.mxDateTime', | { 'sources': ['mxDateTime/mxDateTime.c'], | 'include_dirs': ['mxDateTime'], | } | )] | |'library_dirs' is similar. Thanks. I've got it packaged and ready to ship with Distutils 15.3. I'll try it on a few folks tonight and see how they do. -- Randall Hopper aa8vb@yahoo.com From aa8vb@yahoo.com Mon Jun 5 18:56:36 2000 From: aa8vb@yahoo.com (Randall Hopper) Date: Mon, 05 Jun 2000 13:56:36 -0400 Subject: [Distutils] cleaning up packages Message-ID: <20000605135636.A11091@vislab.epa.gov> As I install my new module distribution, sprinking .so's and .py's around the Python distribution tree, it occurs to me that I haven't yet read... With DistUtils, what's the command to clean up all the kibbles and bits in the Python tree associated with a package of a given name. Did I miss it? Or is it that not implemented yet? For those familiar with the FreeBSD or Redhat package tools, I'm talking about pkg_delete or rpm -e, respectively (in fact, FreeBSD registers Python packages with the FreeBSD package manager; but not all platforms have this capability). Some related distutils subtasks I also don't know about: 1) Listing what packages are currently installed (pyncurses-0.3, Numeric-15.3, etc.) 2) List what files in the python tree make up a package (/usr/local/python/PLATFORM/plat-irix646-n32/.../site-packages/my.so, etc.) 3) Delete the files for the specified package, and remove the package from the installed list. Is this supported? Slated for the future? Like most folks, I've hit package breakage due to stray files and libs lying around way too many times. And asking users to cd into system-specific paths 10 or more levels deep and rm specific files is a support nightmare. Sure hope we have (or will have) a "delete package" capability. Thanks, Randall -- Randall Hopper aa8vb@yahoo.com From hgebel@inet.net Tue Jun 6 00:58:05 2000 From: hgebel@inet.net (Harry Henry Gebel) Date: Mon, 5 Jun 2000 19:58:05 -0400 Subject: [Distutils] cleaning up packages In-Reply-To: <20000605135636.A11091@vislab.epa.gov>; from aa8vb@yahoo.com on Mon, Jun 05, 2000 at 01:56:36PM -0400 References: <20000605135636.A11091@vislab.epa.gov> Message-ID: <20000605195805.D25602@inet.net> On Mon, Jun 05, 2000 at 01:56:36PM -0400, Randall Hopper wrote: > As I install my new module distribution, sprinking .so's and .py's > around the Python distribution tree, it occurs to me that I haven't yet > read... > > With DistUtils, what's the command to clean up all the kibbles and > bits in the Python tree associated with a package of a given name. Did I > miss it? Or is it that not implemented yet? > > For those familiar with the FreeBSD or Redhat package tools, I'm > talking about pkg_delete or rpm -e, respectively (in fact, FreeBSD > registers Python packages with the FreeBSD package manager; but not all > platforms have this capability). > > Some related distutils subtasks I also don't know about: > > 1) Listing what packages are currently installed > (pyncurses-0.3, Numeric-15.3, etc.) > > 2) List what files in the python tree make up a package > > (/usr/local/python/PLATFORM/plat-irix646-n32/.../site-packages/my.so, > etc.) > > 3) Delete the files for the specified package, and remove the package > from the installed list. > What you are basically talking about is package management for systems that do not have a package manager (or whose package manager is not yet supported by Distutils). I was (and am) planning on working on this but have not had a chance to start; and may not for awhile. I do not know what Greg's plans are for this; I was thinking a sort of mini-RPM-like database but have not heard what other ideas people might have. -- Harry Henry Gebel, Senior Developer, Landon House SBS ICQ# 76308382 West Dover Hundred, Delaware From gward@python.net Tue Jun 6 02:55:28 2000 From: gward@python.net (Greg Ward) Date: Mon, 5 Jun 2000 21:55:28 -0400 Subject: [Distutils] Re: -I paths and ext_modules In-Reply-To: <20000605133256.A11019@vislab.epa.gov>; from Randall Hopper on Mon, Jun 05, 2000 at 01:32:56PM -0400 References: <20000602094238.A3357531@vislab.epa.gov> <20000602205321.B326@beelzebub> <20000605133256.A11019@vislab.epa.gov> Message-ID: <20000605215528.A1204@beelzebub> On 05 June 2000, Randall Hopper said: > Thanks. I've got it packaged and ready to ship with Distutils 15.3. Wow, great! I think this is the first recorded *forward*-looking time machine in the Python community; I'm glad to hear the Distutils makes it as far as version 15.3. How many years into the future did you have to travel? Greg PS. the current Distutils release is 0.8.2; 0.9 will be the next release. ;-) -- Greg Ward - programmer-at-big gward@python.net http://starship.python.net/~gward/ I just got my PRINCE bumper sticker ... But now I can't remember WHO he is ... From gward@python.net Tue Jun 6 03:23:21 2000 From: gward@python.net (Greg Ward) Date: Mon, 5 Jun 2000 22:23:21 -0400 Subject: [Distutils] two bugs In-Reply-To: ; from Bastian Kleineidam on Sat, Jun 03, 2000 at 05:20:33PM +0200 References: <3937DD4E.E015ACD8@bell-labs.com> Message-ID: <20000605222321.B1204@beelzebub> On 03 June 2000, Bastian Kleineidam said: > I discovered a minor glitch in install_data.py, line 59, in > get_outputs(self): > replace > return self.outfiles > with > return self.outfiles or [] > to ensure a list is returned and not the None object. Yup, fixed. Thanks. > Another bug I found: > Here is why: > bdist_rpm.py:283: sdist = self.reinitialize_command ('sdist') > now sdist is _not_ finalized > bdist_rpm.py:288: self.run_command('sdist') > now sdist is _still_ not finalized! this is because we have run > 'sdist' before and wrote this in the cache: > dist.py:751: if self.have_run.get (command): > return > and therefore sdist.get_archive_files() returns None which is not > subscriptable > > I have no fix for this bug. Probly you should insert > in Distribution.reinitialize_command() the line > self.have_run[commandname] = 0 > before the return. Coincidentally, I fixed that bug last night, before I carefully read your bug report. Your fix is correct, which becomes obvious when you realize that command objects have a fairly strict life-cycle; the 'reinitialize_command()' method is (so far) the only way to go backwards in that life-cycle, and the state was not being properly set to reflect that backwards transition. So this should be working in the current CVS. Incidentally, I fixed it so that the "bdist" command can take multiple formats, eg. "bdist --formats=zip,gztar", and run the same "bdist_*" command ("bdist_dumb") in this case multiple times. Be aware that in the "setup.py sdist bdist_rpm" case, "sdist" will run twice: once at your behest, and once at the behest of "bdist_rpm". This looks wasteful, but it's the only safe way to operate, as "bdist_rpm" might set options on "sdist" that cause it to behave differently. (Well, OK, we could have a "have run with this particular state" cache, but that seems excessive.) BTW, you should be aware that I am 99% decided to change the base installation directory from "/share" to just plain "". Now that you can put data files wherever you please, prefix seems like the logical place to put them; if you wish to conform to the GNU standards, all you have to do is change (eg.) "locale/de" to "share/locale/de" in the setup script. But if you have "data" files that belong in "lib" or "etc", you can easily put them there, too. (Unix bias? What do you mean, I have a Unix bias? ;-) Greg -- Greg Ward - Unix geek gward@python.net http://starship.python.net/~gward/ God made machine language; all the rest is the work of man. From gward@python.net Tue Jun 6 03:25:44 2000 From: gward@python.net (Greg Ward) Date: Mon, 5 Jun 2000 22:25:44 -0400 Subject: [Distutils] Patch to bdist_rpm In-Reply-To: <20000604230908.G20611@inet.net>; from Harry Henry Gebel on Sun, Jun 04, 2000 at 11:09:08PM -0400 References: <20000604030700.B5468@inet.net> <20000604104050.B1211@beelzebub> <20000604230908.G20611@inet.net> Message-ID: <20000605222544.C1204@beelzebub> On 04 June 2000, Harry Henry Gebel said: > Good question, maybe it would be best to just require python and if the > package requires a specific version let the packager override this. On the > other hand 1.5.2 has been out for long enough that alot of modules do > require it, so maybe "python >= 1.5.2" should be the default. One good argument for requiring Python 1.5.2: if you wish to build/install from source using the Distutils, you need Python 1.5.2. Yes yes, I know the right place to enforce this is when installing the Distutils themselves. It was just a thought. Greg -- Greg Ward - just another Python hacker gward@python.net http://starship.python.net/~gward/ I have the power to HALT PRODUCTION on all TEENAGE SEX COMEDIES!! From gward@python.net Tue Jun 6 03:49:26 2000 From: gward@python.net (Greg Ward) Date: Mon, 5 Jun 2000 22:49:26 -0400 Subject: [Distutils] cleaning up packages In-Reply-To: <20000605135636.A11091@vislab.epa.gov>; from Randall Hopper on Mon, Jun 05, 2000 at 01:56:36PM -0400 References: <20000605135636.A11091@vislab.epa.gov> Message-ID: <20000605224926.D1204@beelzebub> On 05 June 2000, Randall Hopper said: > Some related distutils subtasks I also don't know about: > > 1) Listing what packages are currently installed > (pyncurses-0.3, Numeric-15.3, etc.) > > 2) List what files in the python tree make up a package > > (/usr/local/python/PLATFORM/plat-irix646-n32/.../site-packages/my.so, > etc.) > > 3) Delete the files for the specified package, and remove the package > from the installed list. > > > Is this supported? Slated for the future? Punted on for now: the immediate concern is building, distributing, and installing Python modules and applications, and -- even more important -- generating "smart" installers that do all of the above work (uninstall, list-what's-installed, etc.) for us. Eg. if everyone in the world used and RPM- or Debian-based Linux, we could just make RPMs or Debian packages for people to install, and let those package managers worry about these issues (not to mention dependencies, requirements, conflicts, and all that other fun stuff). I have no huge desire to reinvent the RPM wheel. The guys at Red Hat did a great job, and from what I've heard the Debian and Free BSD folks have done a little better still. However, the sad truth is that most commercial Unices are saddled with abysmally awful package management systems, and hardly any free software developers bother to support, eg., Sun's pkgtool (or whatever it's called). Is it worth expending effort to support what is obviously a dying breed? In the Unix world, Linux and *BSD are clearly the way of the future; all of the commercial Unices save Solaris are gasping for breath, and -- as any of my co-workers will tell you -- I would gladly stand in the firing squad that ends Sun's time in the limelight. (Hmmm, I hope statements like this don't get me tagged as "another free software gun nut". I'm not, really! I'm actually a raving anti-capitalist nut... ;-) It's certainly an interesting problem, and it wouldn't be too hard to do a 75% solution in Python, namely handle your wishlist. (Handling dependencies smells like a whole other kettle of fish.) Be aware, though, that there has been one crack at this already: Michael Muller submitted a patch back in January which I finally looked over in April, but did not integrate into the Distutils CVS. Anyone interested in this problem should go dig up all versions of Michael's patch (I think there were three of them posted) from the archive, as well as the ensuing discussions. As I recall, the first two versions wrote the meta-data as Python code to be parsed; there was some objection to that, so Michael invented a little format and wrote a parser for it. That still strikes me as the right way to do it, but for something about Michael's implementation put me off, and I haven't looked at it since April. I think what worries me is the potential for profileration of mini-languages for Distutils data. There are already two: the MANIFEST.in file and the config files. MANIFEST.in will probably remain a special (very simple) case, but I would like to see some unification between the config files (data read by the Distutils) and generated meta-data files (written by the Distutils, but would also be read by the generic uninstall script, which would probably start "from distutils.configparser import ..."). Requirements for such a generic format (and the interface that implements it): * basic syntax close to ConfigParser's, but without the baggage of "%(name)s" substitution -- there's already a "$name" substitution mechanism in the Distutils, it just needs to be more widely used to allow substitution of configuration variables at logical points * better support for ConfigParser of multi-line data, specifically stripping leading whitespace on continuation lines should work * support for structured data: eg. "foo, bar, baz" for a sequence, "foo: 37, bar: 12" for a mapping (both of these should optionally allow shlex-style quoting) * maybe: support for typed data (eg. distinguish between string, int, and boolean values) * compatibility, possibly unification, with the FancyGetopt class -- ie. setting command options from both the command line and config files should be no clunkier, and preferably less so, than it currently is * ability to track down where option value originated, ie. filename and line number * lightweight! I don't want to see an Option class, where every command option is now a full-blown object instead of just a string or a list as it should be Proposals are welcome! Greg -- Greg Ward - Unix bigot gward@python.net http://starship.python.net/~gward/ I once decorated my apartment entirely in ten foot salad forks!! From R.Liebscher@gmx.de Tue Jun 6 12:45:35 2000 From: R.Liebscher@gmx.de (Rene Liebscher) Date: Tue, 06 Jun 2000 13:45:35 +0200 Subject: [Distutils] distutils & Cygwin compiler on Win32 References: <20000529221156.C6898@beelzebub> <20000602204146.D352@beelzebub> Message-ID: <393CE45F.95D3614@gmx.de> This is a multi-part message in MIME format. --------------D883EB9E16BD4C83A8F2C8C5 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Greg Ward wrote: > > Second, the patch which provides the help-compiler > > option (and help-format, help-formats whatever > > you need.) This is against the cvs from last monday. > > Oh good. I used the current cvs to create an up-to-date patch. It only introduces this help-option option, nothing else. ( Did you have a problem with bdist, I found the current cvs wasn't working, in the run method you wrote self.format which I had to change to format. ) file: help-option.patch > > Finally, while I was working on this help patch, I > > found that everyone who creates a new compiler has > > to change ccompiler.py, which contains the base class > > for all other compilers. Wouldn't it be better, if > > we had a separate file for the compiler mapping, so > > no-one ever has to touch our base file? > > I'm not convinced. If we actually had to change the CCompiler class, > you'd have a point -- that would be a sign of inadequate design. But we > just have to change the tables that drive the factory function, and > those tables and the factory really belong in the same module as the > base class. What's the big deal with tweaking that file occasionally? You could introduce some other things like building the mapping table at runtime, so you only can choose compilers which are really available on your machine. I think such things don't belong in ccompiler.py, it would be to platform-specific. Look at this piece of code to understand what I mean. ----------------------------------- +# Map a platform ('posix', 'nt') to the default compiler type for +# that platform. +default_compiler = { 'posix': 'unix', + 'nt': 'msvc', + } + +# Map compiler types to (module_name, class_name) pairs -- ie. where to +# find the code that implements an interface to this compiler. (The module +# is assumed to be in the 'distutils' package.) +compiler_class = { + # standard for all platforms + 'unix': ('unixccompiler', 'UnixCCompiler',"standard UNIX-style compiler"), + } + +# on NT we have some compilers more +if os.name=='nt': + compiler_class.update({ + 'msvc': ('msvccompiler', 'MSVCCompiler',"Microsoft Visual C++"), + 'cygwin': ('cygwinccompiler', 'CygwinCCompiler',"Cygwin-Gnu-Win32-C-Compiler"), + 'mingw32': ('cygwinccompiler', 'Mingw32CCompiler',"MinGW32-C-Compiler (or cygwin in this mode)"), + }) + +# One could also check if the compiler is really available +# for example: (doesn't really work, because msvc's find_exe return always a name) +# import msvccompiler +# if msvccompiler.find_exe(...): +# compiler_class.update( ... msvc ... ) + ----------------------------------------- (Perhaps, we could divide it in ccompiler.py which contains only the class CCompiler and a file compiler_util.py or compiler_factory.py? for the rest.?) And now some words to your second email. > * constructing a fake Makefile fragment to set sysconfig globals is > excessively baroque: why not do it like this: (I took it directly from a older version of cygwinccompiler.py) > g['CC'] = "cc" # not gcc? I used 'cc' because it is the standard name for a C compiler. I overwrite UnixCCompilers self.cc to change it to 'gcc'. I think as a default assignment it should be set to the standard name 'cc'. (There are more free compilers for Windows out there, what they call their compiler? cc?) >>>>>>>>>>>>>>>>>>>>>>>>>>>>> * I'd rather do nothing about guessing the user's home directory on Windows -- my innocent question started a surprisingly lively thread on the topic in python-dev, and it seems possible that some sort of "userdir" module will wind up in Python 1.6. I'd rather use whatever code comes out of that discussion. However, it does sound reasonable to respect os.environ['HOME'], in which case Mac OS will be the odd man out in 'find_config_files()' instead of Unix. That way, people who really care about having a personal directory on Windows can communicate it to Distutils unambigiously through HOME -- at least until someone figures out the "right way" to find a home directory on Windows. <<<<<<<<<<<<<<<<<<<<<<<<<<<<< Ok, they could set HOME in their login scripts. >>>>>>>>>>>>>>>>>>>>>>>>>>>>> Can you redo your modification of dist.py to unify the "posix" and "nt" branches of 'find_config_files()', and drop the HOME-setting code in util.py? Thanks. <<<<<<<<<<<<<<<<<<<<<<<<<<<<< Ok. file: dist_home.patch (It contains only this patch.) >Finally, what's your thought on simplifying the CCompiler API and >relying more on instance attributes? I'd rather do this now so you and >Lyle Johnson (who's doing the Borland C++ port) have to adapt your code >before I check it in. >evil smirk< Any feelings? It sounds good, but if you subclass a compiler class, as I do, only to (ex)change some parameters for the call of its base class method, then you probably had to save instance variables, call the base class method and then restore the instance variables. (Ok, for my class this isn't a big problem, because I could set most changes in __init__(). But it is worth to think about, which parameters are really constant for all cases.) If you have a new version of UnixCCompiler, send me an email and I will change my classes, too. (I will send you then the complete file, not an patch.) I also found some problems with building extensions using my classes. I tried to build a more complex extension (pygtk-0.6.5). This works without problems if you use msvc, but the resulting dll crashs if I use cygwin or mingw32, it is probably a problem with initialization of the dll's. If someone else has more experience with cygwin/mingw32, he could find out if there is a problem with my link parameters in the compiler classes. > I've just gone over your patch, and I think I'd like it better if you'd > "cvs update" and regenerate it. There's at least one bug that we both > fixed, so there may be other conflicts -- and those are easier to deal > with using "cvs" than using "patch". ;-) Most of it is either already checked in or attached to this mail. The rest concerns only my cygwinccompiler.py file, and I will send it as file not as patch. (later this week) I found some problems with sdist. If you add a new package in setup.py (I mean one more entry in the packages list), then it is not included in the resulting source distribution. I think this happens because sdist doesn't check the date of MANIFEST against the date of setup.py (or however this file is called, __file__ would give you the name.) I will see if I can change this. Another problem: If I have an empty package (which contains only an empty __init__.py file, file length=0), then it is included in the zip-file, but you can't find it in the tar.gz-file. Is this a problem of tar and it is worth to be treated specially? (makes it ever sense to have such a module) Kind regards Rene Liebscher --------------D883EB9E16BD4C83A8F2C8C5 Content-Type: text/plain; charset=us-ascii; name="dist_home.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dist_home.patch" diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/dist.py distutils.patched/distutils/dist.py --- distutils.orig/distutils/dist.py Tue Jun 6 11:17:02 2000 +++ distutils.patched/distutils/dist.py Tue Jun 6 12:47:42 2000 @@ -263,24 +263,25 @@ and setup.cfg in the current directory. """ files = [] - if os.name == "posix": - check_environ() + check_environ() - sys_dir = os.path.dirname(sys.modules['distutils'].__file__) - sys_file = os.path.join(sys_dir, "pydistutils.cfg") - if os.path.isfile(sys_file): - files.append(sys_file) + if os.name=='posix': + sys_dir = os.path.dirname(sys.modules['distutils'].__file__) + user_filename = ".pydistutils.cfg" + else: + sys_dir = sysconfig.PREFIX + user_filename = "pydistutils.cfg" + + sys_file = os.path.join(sys_dir, "pydistutils.cfg") + if os.path.isfile(sys_file): + files.append(sys_file) - user_file = os.path.join(os.environ.get('HOME'), - ".pydistutils.cfg") + if os.environ.has_key('HOME'): + user_file = os.path.join(os.environ.get('HOME'), + user_filename) if os.path.isfile(user_file): files.append(user_file) - else: - sys_file = os.path.join (sysconfig.PREFIX, "pydistutils.cfg") - if os.path.isfile(sys_file): - files.append(sys_file) - # All platforms support local setup.cfg local_file = "setup.cfg" if os.path.isfile(local_file): --------------D883EB9E16BD4C83A8F2C8C5 Content-Type: text/plain; charset=us-ascii; name="help_option.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="help_option.patch" diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/archive_util.py distutils.patched/distutils/archive_util.py --- distutils.orig/distutils/archive_util.py Tue Jun 6 11:17:01 2000 +++ distutils.patched/distutils/archive_util.py Tue Jun 6 11:20:24 2000 @@ -110,11 +110,11 @@ ARCHIVE_FORMATS = { - 'gztar': (make_tarball, [('compress', 'gzip')]), - 'bztar': (make_tarball, [('compress', 'bzip2')]), - 'ztar': (make_tarball, [('compress', 'compress')]), - 'tar': (make_tarball, [('compress', None)]), - 'zip': (make_zipfile, []) + 'gztar': (make_tarball, [('compress', 'gzip')],"gzipped tar-file"), + 'bztar': (make_tarball, [('compress', 'bzip2')],"bzip2-ed tar-file"), + 'ztar': (make_tarball, [('compress', 'compress')],"compressed tar-file"), + 'tar': (make_tarball, [('compress', None)],"uncompressed tar-file"), + 'zip': (make_zipfile, [],"zip-file") } def check_archive_formats (formats): diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/ccompiler.py distutils.patched/distutils/ccompiler.py --- distutils.orig/distutils/ccompiler.py Tue Jun 6 11:17:02 2000 +++ distutils.patched/distutils/ccompiler.py Tue Jun 6 11:22:15 2000 @@ -726,10 +726,22 @@ # Map compiler types to (module_name, class_name) pairs -- ie. where to # find the code that implements an interface to this compiler. (The module # is assumed to be in the 'distutils' package.) -compiler_class = { 'unix': ('unixccompiler', 'UnixCCompiler'), - 'msvc': ('msvccompiler', 'MSVCCompiler'), +compiler_class = { 'unix': ('unixccompiler', 'UnixCCompiler',"standard UNIX-style compiler"), + 'msvc': ('msvccompiler', 'MSVCCompiler',"Microsoft Visual C++"), + 'cygwin': ('cygwinccompiler', 'CygwinCCompiler',"Cygwin-Gnu-Win32-C-Compiler"), + 'mingw32': ('cygwinccompiler', 'Mingw32CCompiler',"MinGW32-C-Compiler (or cygwin in this mode)"), } +# prints all possible arguments to --compiler +def show_compilers(): + from distutils.fancy_getopt import FancyGetopt + list_of_compilers=[] + for compiler in compiler_class.keys(): + list_of_compilers.append(("compiler="+compiler,None,compiler_class[compiler][2])) + list_of_compilers.sort() + pretty_printer=FancyGetopt(list_of_compilers) + pretty_printer.print_help("List of available compilers:") + def new_compiler (plat=None, compiler=None, @@ -755,7 +767,7 @@ if compiler is None: compiler = default_compiler[plat] - (module_name, class_name) = compiler_class[compiler] + (module_name, class_name,long_description) = compiler_class[compiler] except KeyError: msg = "don't know how to compile C/C++ code on platform '%s'" % plat if compiler is not None: diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/bdist.py distutils.patched/distutils/command/bdist.py --- distutils.orig/distutils/command/bdist.py Tue Jun 6 11:17:03 2000 +++ distutils.patched/distutils/command/bdist.py Tue Jun 6 11:35:12 2000 @@ -21,8 +21,7 @@ user_options = [('bdist-base=', 'b', "temporary directory for creating built distributions"), ('formats=', None, - "formats for distribution " + - "(gztar, bztar, zip, rpm, ... )"), + "formats for distribution"), ] # The following commands do not take a format option from bdist @@ -33,12 +32,28 @@ default_format = { 'posix': 'gztar', 'nt': 'zip', } - format_command = { 'gztar': 'bdist_dumb', - 'bztar': 'bdist_dumb', - 'ztar': 'bdist_dumb', - 'tar': 'bdist_dumb', - 'rpm': 'bdist_rpm', - 'zip': 'bdist_dumb', } + format_command = { 'gztar': ('bdist_dumb',"gzipped tar-file"), + 'bztar': ('bdist_dumb',"bzip2-ed tar-file"), + 'ztar': ('bdist_dumb',"compressed tar-file"), + 'tar': ('bdist_dumb',"tar-file"), + 'rpm': ('bdist_rpm',"rpm distribution"), + 'zip': ('bdist_dumb',"zip-file"), + } + + # prints all possible arguments to --format + def show_formats(): + from distutils.fancy_getopt import FancyGetopt + list_of_formats=[] + for format in bdist.format_command.keys(): + list_of_formats.append(("formats="+format,None,bdist.format_command[format][1])) + list_of_formats.sort() + pretty_printer=FancyGetopt(list_of_formats) + pretty_printer.print_help("List of available distribution formats:") + + help_options = [ + ('help-formats', None, + "lists available distribution formats",show_formats), + ] def initialize_options (self): @@ -74,14 +89,14 @@ for format in self.formats: try: - cmd_name = self.format_command[self.format] + cmd_name = self.format_command[format][0] except KeyError: raise DistutilsOptionError, \ - "invalid format '%s'" % self.format + "invalid format '%s'" % format sub_cmd = self.reinitialize_command(cmd_name) if cmd_name not in self.no_format_option: - sub_cmd.format = self.format + sub_cmd.format = format self.run_command (cmd_name) # run() diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/build.py distutils.patched/distutils/command/build.py --- distutils.orig/distutils/command/build.py Mon May 29 10:26:26 2000 +++ distutils.patched/distutils/command/build.py Tue Jun 6 11:20:24 2000 @@ -9,6 +9,7 @@ import sys, os from distutils.core import Command from distutils.util import get_platform +from distutils.ccompiler import show_compilers class build (Command): @@ -35,6 +36,10 @@ ('force', 'f', "forcibly build everything (ignore file timestamps)"), ] + help_options = [ + ('help-compiler', None, + "lists available compilers",show_compilers), + ] def initialize_options (self): self.build_base = 'build' diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/build_clib.py distutils.patched/distutils/command/build_clib.py --- distutils.orig/distutils/command/build_clib.py Thu May 25 03:10:04 2000 +++ distutils.patched/distutils/command/build_clib.py Tue Jun 6 11:20:24 2000 @@ -23,7 +23,7 @@ from types import * from distutils.core import Command from distutils.errors import * -from distutils.ccompiler import new_compiler +from distutils.ccompiler import new_compiler,show_compilers class build_clib (Command): @@ -42,6 +42,10 @@ ('compiler=', 'c', "specify the compiler type"), ] + help_options = [ + ('help-compiler', None, + "lists available compilers",show_compilers), + ] def initialize_options (self): self.build_clib = None diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/build_ext.py distutils.patched/distutils/command/build_ext.py --- distutils.orig/distutils/command/build_ext.py Tue Jun 6 11:17:04 2000 +++ distutils.patched/distutils/command/build_ext.py Tue Jun 6 11:25:34 2000 @@ -14,6 +14,7 @@ from distutils.errors import * from distutils.dep_util import newer_group from distutils.extension import Extension +from distutils.ccompiler import show_compilers # An extension name is just a dot-separated list of Python NAMEs (ie. # the same as a fully-qualified module name). @@ -72,6 +73,10 @@ ('compiler=', 'c', "specify the compiler type"), ] + help_options = [ + ('help-compiler', None, + "lists available compilers",show_compilers), + ] def initialize_options (self): diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/sdist.py distutils.patched/distutils/command/sdist.py --- distutils.orig/distutils/command/sdist.py Tue Jun 6 11:17:06 2000 +++ distutils.patched/distutils/command/sdist.py Tue Jun 6 11:20:24 2000 @@ -13,7 +13,7 @@ from distutils.core import Command from distutils.util import newer, create_tree, remove_tree, convert_path, \ write_file -from distutils.archive_util import check_archive_formats +from distutils.archive_util import check_archive_formats,ARCHIVE_FORMATS from distutils.text_file import TextFile from distutils.errors import DistutilsExecError, DistutilsOptionError @@ -35,11 +35,26 @@ ('force-manifest', 'f', "forcibly regenerate the manifest and carry on as usual"), ('formats=', None, - "formats for source distribution (tar, ztar, gztar, bztar, or zip)"), + "formats for source distribution"), ('keep-tree', 'k', "keep the distribution tree around after creating " + "archive file(s)"), ] + # prints all possible arguments to --formats + def show_formats(): + from distutils.fancy_getopt import FancyGetopt + list_of_formats=[] + for format in ARCHIVE_FORMATS.keys(): + list_of_formats.append(("formats="+format,None,ARCHIVE_FORMATS[format][2])) + list_of_formats.sort() + pretty_printer=FancyGetopt(list_of_formats) + pretty_printer.print_help("List of available distribution formats:") + + help_options = [ + ('help-formats', None, + "lists available distribution formats",show_formats), + ] + negative_opts = {'use-defaults': 'no-defaults'} default_format = { 'posix': 'gztar', diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/dist.py distutils.patched/distutils/dist.py --- distutils.orig/distutils/dist.py Tue Jun 6 11:17:02 2000 +++ distutils.patched/distutils/dist.py Tue Jun 6 11:20:24 2000 @@ -433,16 +433,38 @@ negative_opt = copy (negative_opt) negative_opt.update (cmd_class.negative_opt) + # Check for help_options in command class + # They have a different format (tuple of four) so we need to preprocess them here + help_options = [] + if hasattr(cmd_class,"help_options") and type (cmd_class.help_options) is ListType: + help_options = map(lambda x:(x[0],x[1],x[2]),cmd_class.help_options) + # All commands support the global options too, just by adding # in 'global_options'. parser.set_option_table (self.global_options + - cmd_class.user_options) + cmd_class.user_options + help_options) parser.set_negative_aliases (negative_opt) (args, opts) = parser.getopt (args[1:]) if hasattr(opts, 'help') and opts.help: self._show_help(parser, display_options=0, commands=[cmd_class]) return + if hasattr(cmd_class,"help_options") and type (cmd_class.help_options) is ListType: + help_option_found=0 + for help_option in cmd_class.help_options: + if hasattr(opts, parser.get_attr_name(help_option[0])): + help_option_found=1 + #print "showing help for option %s of command %s" % (help_option[0],cmd_class) + if callable(help_option[3]): + help_option[3]() + else: + raise DistutilsClassError, \ + ("command class %s must provide " + + "a callable object for help_option '%s'") % \ + (cmd_class,help_option[0]) + if help_option_found: + return + # Put the options from the command-line into their official # holding pen, the 'command_options' dictionary. opt_dict = self.get_option_dict(command) @@ -492,7 +514,11 @@ klass = command else: klass = self.get_command_class (command) - parser.set_option_table (klass.user_options) + if hasattr(klass,"help_options") and type (klass.help_options) is ListType: + parser.set_option_table (klass.user_options+ + map(lambda x:(x[0],x[1],x[2]),klass.help_options)) + else: + parser.set_option_table (klass.user_options) parser.print_help ("Options for '%s' command:" % klass.__name__) print @@ -500,7 +526,7 @@ return # _show_help () - + def handle_display_options (self, option_order): """If there were any non-global "display-only" options --------------D883EB9E16BD4C83A8F2C8C5-- From aa8vb@yahoo.com Tue Jun 6 14:00:59 2000 From: aa8vb@yahoo.com (Randall Hopper) Date: Tue, 06 Jun 2000 09:00:59 -0400 Subject: [Distutils] Re: cleaning up packages In-Reply-To: <20000605224926.D1204@beelzebub>; from gward@python.net on Mon, Jun 05, 2000 at 10:49:26PM -0400 References: <20000605135636.A11091@vislab.epa.gov> <20000605224926.D1204@beelzebub> Message-ID: <20000606090059.A112849@vislab.epa.gov> Thanks for the reply. Greg Ward: |Randall Hopper: |> With DistUtils, what's the command to clean up all the kibbles and |> bits in the Python tree associated with a package of a given name? ... |Punted on for now Ok. |the immediate concern is building, distributing, and installing Python |modules and applications, and -- even more important -- generating |"smart" installers that do all of the above work (uninstall, |list-what's-installed, etc.) for us. I'm a little confused here. Your latter points (uninstall, list what's installed) is what I'm referring to, and if I interpret correctly, you list this in the "immediate concerns" category. |I have no huge desire to reinvent the RPM wheel. The guys at Red Hat |did a great job, and from what I've heard the Debian and Free BSD folks |have done a little better still. However, the sad truth is that most |commercial Unices are saddled with abysmally awful package management |systems, and hardly any free software developers bother to support, eg., |Sun's pkgtool (or whatever it's called). Right. SGI has it's own as well. |Is it worth expending effort to support what is obviously a dying breed? |In the Unix world, Linux and *BSD are clearly the way of the future; all |of the commercial Unices save Solaris are gasping for breath, ... Here's why I think it is worth the effort. Clearly folks "must" deinstall old versions of module distributions before installing new ones. Neglecting this task risks picking up old, incompatible bits from prior versions that may render the module distribution unusable. Case in point: Numeric changing it's include and lib directory names every other version (numeric/multiarray.so vs. Numeric/multiarray.so), or a .so or .py module that gets moved between submodules in a package. Some deinstaller is needed, whether OS-supported or Python-supported. (Either that, or we adopt the MSWin strategy of users completely reinstalling Python when the blue-screen frequency goes high. :-) And here is why I think the OS-supported package managers won't work for the Python world. We have two important classes of Python users that install module distributions: 1) Those with administration privilege (sysadmins, home users) 2) Those without (commercial/government users) For those with admin privilege, the FreeBSD, Redhat, Debian, Sun, SGI, MSWin, <> package managers for the respective OS may be just fine. We've got the headache of supporting N different ways for folks to deinstall packages from their Python tree based on the OS (assuming someone will support building dists for all N) which'll doubtless become an FAQ, but it works. For folks to build these OS-specific packages, we've also got to figure out N different times how each version of each module dist sprinkles files throughout the Python tree (when Distutils could tell us that). And for those users on OSs without package managers, they'll have to cobble together their own ad-hoc solution to keep track of how to clean up module dists. But the real problem is for users wiithout admin privilege (frequent in the commercial and government worlds). For them, the system-provided package manager isn't a realistic option. Assuming these users can find a pre-built package for their OS (SGI, Sun, etc.), and that the local admin compiled/installed Python to live in the same absolute path as the module distribution wants to live in, these users have to get their administrator to install it. This can be a time-consuming task (or neigh impossible in some cases! -- think Dilbert sysadmins and government beaurocracy). More than likely, these developers have their own writable Python tree installed locally off their $HOME so they can do their own install/uninstall and actually get work done. These non-admin users will always be going the "setup.py install" route and building module dists themselves. They will be upgrading, and the system package manager is not going to help them track and clean up old versions. I may be underestimating, but from what's already provided to Distutils in the setup.py files (name, version), it looks like a simple "keep a files-per-module-dist" list doesn't appear that it'd be a whole lot of work: - [TAB] - [TAB] - [TAB] ... and in Python pseudocode, the module deletion is just: while read line: if line[0] == THE_MODULE: os.remove( line[1] ) I share your concern about expanding the number of file formats supported by DistUtils. What about one of these many simple database packages that Python already supports? Just some simple text-file DB is all we need. Just: "give me all the files for this package" | xargs rm -f. If someone wanted to go all-out we could implement empty directory removal and module dist dependencies by adding other columns to the table (text or SQL DB table; doesn't matter), but IMHO this is a relatively low priority. This simple "module dist deletor" doesn't need to be fast either. If there's a need, some budding Python hacker will come along later and improve performance with much praise from the community. -- Randall Hopper aa8vb@yahoo.com From aa8vb@yahoo.com Tue Jun 6 14:37:37 2000 From: aa8vb@yahoo.com (Randall Hopper) Date: Tue, 06 Jun 2000 09:37:37 -0400 Subject: [Distutils] Re: Re: -I paths and ext_modules In-Reply-To: <20000605215528.A1204@beelzebub>; from gward@python.net on Mon, Jun 05, 2000 at 09:55:28PM -0400 References: <20000602094238.A3357531@vislab.epa.gov> <20000602205321.B326@beelzebub> <20000605133256.A11019@vislab.epa.gov> <20000605215528.A1204@beelzebub> Message-ID: <20000606093737.A113670@vislab.epa.gov> Greg Ward: |On 05 June 2000, Randall Hopper said: |> Thanks. I've got it packaged and ready to ship with Distutils 15.3. | |Wow, great! I think this is the first recorded *forward*-looking time |machine in the Python community; I'm glad to hear the Distutils makes it |as far as version 15.3. How many years into the future did you have to |travel? Oops. Oh yeah, I meant to do that ;-) That's Numeric's version number. Distutils 0.8.2 is what I used. -- Randall Hopper aa8vb@yahoo.com From aa8vb@yahoo.com Tue Jun 6 15:06:11 2000 From: aa8vb@yahoo.com (Randall Hopper) Date: Tue, 06 Jun 2000 10:06:11 -0400 Subject: [Distutils] Re: cleaning up packages In-Reply-To: <20000605195805.D25602@inet.net>; from hgebel@inet.net on Mon, Jun 05, 2000 at 07:58:05PM -0400 References: <20000605135636.A11091@vislab.epa.gov> <20000605195805.D25602@inet.net> Message-ID: <20000606100611.B113670@vislab.epa.gov> Harry Henry Gebel: |Randall Hopper: |> |> With DistUtils, what's the command to clean up all the kibbles and |> bits in the Python tree associated with a package of a given name. Did I |> miss it? Or is it that not implemented yet? | |What you are basically talking about is package management for systems |that do not have a package manager (or whose package manager is not yet |supported by Distutils). I was (and am) planning on working on this Glad to hear it! Sounds like you're familiar with Redhat manager. I'm reasonably familiar with the BSD manager. So if you need someone to bounce ideas off of I'd be happy to contribute. |but have not had a chance to start; and may not for awhile. I do not know |what Greg's plans are for this; I was thinking a sort of mini-RPM-like |database but have not heard what other ideas people might have. Here's a thought to spark the discussion. For simple package listing and deletion support, how about: PYTHON_PREFIX/module-dists/-/CONTENTS where each module-dist's CONTENTS contains a list of files to delete (and possibly other cleanup-related commands). I confess I'm borrowing much from the FreeBSD package manager scheme, which stores package info in: /var/db/pkg/_/+CONTENTS ... Here's Distutils's +CONTENTS file, for example: http://www.FreeBSD.org/cgi/cvsweb.cgi/ports/misc/py-distutils/pkg/PLIST?rev=1.2 As you can see, it contains which files to remove when deleting the package. Any associated cleanup commands (remove directories, etc.) are prefixed by an "@" (see bottom for example). http://www.FreeBSD.org/cgi/cvsweb.cgi/ports/misc/py-distutils/ -- Randall Hopper aa8vb@yahoo.com From thomas.heller@ion-tof.com Tue Jun 6 20:21:18 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Tue, 6 Jun 2000 21:21:18 +0200 Subject: [Distutils] Re: cleaning up packages References: <20000605135636.A11091@vislab.epa.gov><20000605224926.D1204@beelzebub> <20000606090059.A112849@vislab.epa.gov> Message-ID: <037c01bfcfec$63dbe490$4500a8c0@thomasnb> > Here's why I think it is worth the effort. > > Clearly folks "must" deinstall old versions of module distributions before > installing new ones. Neglecting this task risks picking up old, > incompatible bits from prior versions that may render the module > distribution unusable. Case in point: Numeric changing it's include and > lib directory names every other version (numeric/multiarray.so vs. > Numeric/multiarray.so), or a .so or .py module that gets moved between > submodules in a package. > > Some deinstaller is needed, whether OS-supported or Python-supported. > (Either that, or we adopt the MSWin strategy of users completely > reinstalling Python when the blue-screen frequency goes high. :-) MSWin users usually reinstall the *operating system* when the blue-screen frequency goes high ;-) Just for information: Windows has NO OS-supported package manager. (This was at least true up to Win98/NT4.0. There is a windows installer service in Win2000, but I have not yet looked at it) The usual way an application is deinstalled is as follows: - At installation time, an uninstaller program is installed, usually in the application directory. - Uninstallation information is written into a data-file (this is a text-file for WISE, a binary file for InstallShield) - Some entries are written into the registry, so that the application shows up in Control Panel->Add/Remove programs, and which will start the uninstaller to deinstall the program. Thomas From mwa@gate.net Tue Jun 6 23:14:18 2000 From: mwa@gate.net (Mark W. Alexander) Date: Tue, 6 Jun 2000 18:14:18 -0400 (EDT) Subject: [Distutils] cleaning up packages In-Reply-To: <20000605224926.D1204@beelzebub> Message-ID: On Mon, 5 Jun 2000, Greg Ward wrote: > > Proposals are welcome! > > Greg > -- Well, I'm real close to getting to work on bdist-pkgtool for the sysv pkgtools used by Solaris (and others). I hope to follow that with HP depot format. Doesn't bdist-dumb to tar.gz or something basic like that? All these formats include some type of file list that can be used for removal. For that matter, if Distutils saved the package's setup.py in the package directory, isn't there enough info there to extrapolate an uninstall list? On a quazi-related note Easy Software has GPL'ed their Easy Package Manager (EPM). It does Debian, RPM, HP-UX, Solaris and IRIX as well as tar.gz and includes installation & removal scripts. I've played with it a little and found it not quite what I needed at the time but it may be good for a source of information if nothing else. Mark mwa@gate.net From mwa@gate.net Tue Jun 6 23:17:07 2000 From: mwa@gate.net (Mark W. Alexander) Date: Tue, 6 Jun 2000 18:17:07 -0400 (EDT) Subject: [Distutils] SWIG support? In-Reply-To: <20000605224926.D1204@beelzebub> Message-ID: Is there any magic in distutils for dealing with SWIG generated modules? A "nice-to-have" feature would be to specify the swig.i file and options and have Distutils take it from there. Mark Alexander mwa@gate.net From hgebel@inet.net Wed Jun 7 12:24:05 2000 From: hgebel@inet.net (Harry Henry Gebel) Date: Wed, 7 Jun 2000 07:24:05 -0400 Subject: [Distutils] SWIG support? References: <20000605224926.D1204@beelzebub> Message-ID: <20000607072405.D3646@inet.net> On Tue, Jun 06, 2000 at 06:17:07PM -0400, Mark W. Alexander wrote: > Is there any magic in distutils for dealing with SWIG > generated modules? A "nice-to-have" feature would be > to specify the swig.i file and options and have > Distutils take it from there. There isn't anything for the SWIG 'i' files, but the 'C' source files are handled just fine. I include both the interface files and the C code with PyNcurses so the users do not need SWIG unless they want to modify the interface file. -- Harry Henry Gebel, Senior Developer, Landon House SBS ICQ# 76308382 West Dover Hundred, Delaware From aa8vb@yahoo.com Wed Jun 7 14:40:11 2000 From: aa8vb@yahoo.com (Randall Hopper) Date: Wed, 07 Jun 2000 09:40:11 -0400 Subject: [Distutils] Re: SWIG support? In-Reply-To: <20000607072405.D3646@inet.net>; from hgebel@inet.net on Wed, Jun 07, 2000 at 07:24:05AM -0400 References: <20000605224926.D1204@beelzebub> <20000607072405.D3646@inet.net> Message-ID: <20000607094011.A218920@vislab.epa.gov> Harry Henry Gebel: |On Tue, Jun 06, 2000 at 06:17:07PM -0400, Mark W. Alexander wrote: |> Is there any magic in distutils for dealing with SWIG |> generated modules? A "nice-to-have" feature would be |> to specify the swig.i file and options and have |> Distutils take it from there. | |There isn't anything for the SWIG 'i' files, but the 'C' source files are |handled just fine. I include both the interface files and the C code with |PyNcurses so the users do not need SWIG unless they want to modify the |interface file. I did the same when packing my SWIG-generated Py-OpenDX wrappers a few days ago. -- Randall Hopper aa8vb@yahoo.com From mmuller@enduden.com Thu Jun 8 01:31:31 2000 From: mmuller@enduden.com (Michael Muller) Date: Wed, 07 Jun 2000 20:31:31 -0400 Subject: [Distutils] cleaning up packages Message-ID: <200006080051.UAA00418@bogus.com> This is a MIME/Multipart message. --192.168.100.3.501.358.960425463.433.1500 Content-type: text/plain Greg Ward wrote: [lots of stuff about file formats for meta-info and for general use deleted] The patch that I submitted uses a format based on that of ConfigParser. It allows for the definition of arbitrary nested syntaxes for defining data. The system currently supports the specification of data elements as simple strings (no embedded newlines or whitespace), lists of simple strings (one per line), lists of words (words being defined as "no embedded whitespace"), and two more specialized types for describing dependencies. Alternate formats can be easily added. I would have liked to have used indentation to define structure, but ConfigParser replaces all indentation in continuation lines with a single blank space. The implementation necessary to parse this syntax is rather complex, but the data formats themselves end up being extremely clean. I have enclosed an example: the package information file generated for Distutils. Note that the "deps" and "compats" fields are not in use at this time. ============================================================================= michaelMuller = mmuller@enduden.com | http://www.cloud9.net/~proteus ----------------------------------------------------------------------------- There is no concept that is more demeaning to the human spirit than the notion that our freedom must be limited in the interests of our own protection. ============================================================================= --192.168.100.3.501.358.960425463.433.1500 Content-type: text/plain; charset="us-ascii" Content-transfer-encoding: base64 Content-disposition: attachment; filename="Distutils" Content-description: Distutils package info file W3BrZ2luZm9dCmNvbXBhdHM6IApkZXBzOiAKbmFtZTogRGlzdHV0aWxzCnZlcnNpb246IDAuMS4z CmZpbGVzOiAvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1wYWNrYWdlcy9kaXN0dXRpbHMv dmVyc2lvbi5weQoJL3Vzci9sb2NhbC9saWIvcHl0aG9uMS41L3NpdGUtcGFja2FnZXMvZGlzdHV0 aWxzL19faW5pdF9fLnB5CgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1wYWNrYWdlcy9k aXN0dXRpbHMvc3lzY29uZmlnLnB5CgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1wYWNr YWdlcy9kaXN0dXRpbHMvY29yZS5weQoJL3Vzci9sb2NhbC9saWIvcHl0aG9uMS41L3NpdGUtcGFj a2FnZXMvZGlzdHV0aWxzL3V0aWwucHkKCS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9zaXRlLXBh Y2thZ2VzL2Rpc3R1dGlscy90ZXh0X2ZpbGUucHkKCS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9z aXRlLXBhY2thZ2VzL2Rpc3R1dGlscy9jY29tcGlsZXIucHkKCS91c3IvbG9jYWwvbGliL3B5dGhv bjEuNS9zaXRlLXBhY2thZ2VzL2Rpc3R1dGlscy9lcnJvcnMucHkKCS91c3IvbG9jYWwvbGliL3B5 dGhvbjEuNS9zaXRlLXBhY2thZ2VzL2Rpc3R1dGlscy9mYW5jeV9nZXRvcHQucHkKCS91c3IvbG9j YWwvbGliL3B5dGhvbjEuNS9zaXRlLXBhY2thZ2VzL2Rpc3R1dGlscy9tc3ZjY29tcGlsZXIucHkK CS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9zaXRlLXBhY2thZ2VzL2Rpc3R1dGlscy91bml4Y2Nv bXBpbGVyLnB5CgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1wYWNrYWdlcy9kaXN0dXRp bHMvc3Bhd24ucHkKCS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9zaXRlLXBhY2thZ2VzL2Rpc3R1 dGlscy9wa2dpbmZvLnB5CgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1wYWNrYWdlcy9k aXN0dXRpbHMvY29tbWFuZC9fX2luaXRfXy5weQoJL3Vzci9sb2NhbC9saWIvcHl0aG9uMS41L3Np dGUtcGFja2FnZXMvZGlzdHV0aWxzL2NvbW1hbmQvYnVpbGQucHkKCS91c3IvbG9jYWwvbGliL3B5 dGhvbjEuNS9zaXRlLXBhY2thZ2VzL2Rpc3R1dGlscy9jb21tYW5kL2J1aWxkX2V4dC5weQoJL3Vz ci9sb2NhbC9saWIvcHl0aG9uMS41L3NpdGUtcGFja2FnZXMvZGlzdHV0aWxzL2NvbW1hbmQvYnVp bGRfcHkucHkKCS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9zaXRlLXBhY2thZ2VzL2Rpc3R1dGls cy9jb21tYW5kL2luc3RhbGxfZXh0LnB5CgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1w YWNrYWdlcy9kaXN0dXRpbHMvY29tbWFuZC9kaXN0LnB5CgkvdXNyL2xvY2FsL2xpYi9weXRob24x LjUvc2l0ZS1wYWNrYWdlcy9kaXN0dXRpbHMvY29tbWFuZC9pbnN0YWxsLnB5CgkvdXNyL2xvY2Fs L2xpYi9weXRob24xLjUvc2l0ZS1wYWNrYWdlcy9kaXN0dXRpbHMvY29tbWFuZC9pbnN0YWxsX3B5 LnB5CgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1wYWNrYWdlcy9kaXN0dXRpbHMvY29t bWFuZC9pbnN0YWxsX2luZm8ucHkKCS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9zaXRlLXBhY2th Z2VzL2Rpc3R1dGlscy92ZXJzaW9uLnB5bwoJL3Vzci9sb2NhbC9saWIvcHl0aG9uMS41L3NpdGUt cGFja2FnZXMvZGlzdHV0aWxzL3ZlcnNpb24ucHljCgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUv c2l0ZS1wYWNrYWdlcy9kaXN0dXRpbHMvX19pbml0X18ucHlvCgkvdXNyL2xvY2FsL2xpYi9weXRo b24xLjUvc2l0ZS1wYWNrYWdlcy9kaXN0dXRpbHMvX19pbml0X18ucHljCgkvdXNyL2xvY2FsL2xp Yi9weXRob24xLjUvc2l0ZS1wYWNrYWdlcy9kaXN0dXRpbHMvc3lzY29uZmlnLnB5bwoJL3Vzci9s b2NhbC9saWIvcHl0aG9uMS41L3NpdGUtcGFja2FnZXMvZGlzdHV0aWxzL3N5c2NvbmZpZy5weWMK CS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9zaXRlLXBhY2thZ2VzL2Rpc3R1dGlscy9jb3JlLnB5 bwoJL3Vzci9sb2NhbC9saWIvcHl0aG9uMS41L3NpdGUtcGFja2FnZXMvZGlzdHV0aWxzL2NvcmUu cHljCgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1wYWNrYWdlcy9kaXN0dXRpbHMvdXRp bC5weW8KCS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9zaXRlLXBhY2thZ2VzL2Rpc3R1dGlscy91 dGlsLnB5YwoJL3Vzci9sb2NhbC9saWIvcHl0aG9uMS41L3NpdGUtcGFja2FnZXMvZGlzdHV0aWxz L3RleHRfZmlsZS5weWMKCS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9zaXRlLXBhY2thZ2VzL2Rp c3R1dGlscy9jY29tcGlsZXIucHljCgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1wYWNr YWdlcy9kaXN0dXRpbHMvZXJyb3JzLnB5bwoJL3Vzci9sb2NhbC9saWIvcHl0aG9uMS41L3NpdGUt cGFja2FnZXMvZGlzdHV0aWxzL2Vycm9ycy5weWMKCS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9z aXRlLXBhY2thZ2VzL2Rpc3R1dGlscy9mYW5jeV9nZXRvcHQucHlvCgkvdXNyL2xvY2FsL2xpYi9w eXRob24xLjUvc2l0ZS1wYWNrYWdlcy9kaXN0dXRpbHMvZmFuY3lfZ2V0b3B0LnB5YwoJL3Vzci9s b2NhbC9saWIvcHl0aG9uMS41L3NpdGUtcGFja2FnZXMvZGlzdHV0aWxzL21zdmNjb21waWxlci5w eWMKCS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9zaXRlLXBhY2thZ2VzL2Rpc3R1dGlscy91bml4 Y2NvbXBpbGVyLnB5YwoJL3Vzci9sb2NhbC9saWIvcHl0aG9uMS41L3NpdGUtcGFja2FnZXMvZGlz dHV0aWxzL3NwYXduLnB5YwoJL3Vzci9sb2NhbC9saWIvcHl0aG9uMS41L3NpdGUtcGFja2FnZXMv ZGlzdHV0aWxzL3BrZ2luZm8ucHljCgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1wYWNr YWdlcy9kaXN0dXRpbHMvY29tbWFuZC9fX2luaXRfXy5weW8KCS91c3IvbG9jYWwvbGliL3B5dGhv bjEuNS9zaXRlLXBhY2thZ2VzL2Rpc3R1dGlscy9jb21tYW5kL19faW5pdF9fLnB5YwoJL3Vzci9s b2NhbC9saWIvcHl0aG9uMS41L3NpdGUtcGFja2FnZXMvZGlzdHV0aWxzL2NvbW1hbmQvYnVpbGQu cHlvCgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1wYWNrYWdlcy9kaXN0dXRpbHMvY29t bWFuZC9idWlsZC5weWMKCS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9zaXRlLXBhY2thZ2VzL2Rp c3R1dGlscy9jb21tYW5kL2J1aWxkX2V4dC5weWMKCS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9z aXRlLXBhY2thZ2VzL2Rpc3R1dGlscy9jb21tYW5kL2J1aWxkX3B5LnB5bwoJL3Vzci9sb2NhbC9s aWIvcHl0aG9uMS41L3NpdGUtcGFja2FnZXMvZGlzdHV0aWxzL2NvbW1hbmQvYnVpbGRfcHkucHlj CgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1wYWNrYWdlcy9kaXN0dXRpbHMvY29tbWFu ZC9pbnN0YWxsX2V4dC5weWMKCS91c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9zaXRlLXBhY2thZ2Vz L2Rpc3R1dGlscy9jb21tYW5kL2Rpc3QucHljCgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0 ZS1wYWNrYWdlcy9kaXN0dXRpbHMvY29tbWFuZC9pbnN0YWxsLnB5bwoJL3Vzci9sb2NhbC9saWIv cHl0aG9uMS41L3NpdGUtcGFja2FnZXMvZGlzdHV0aWxzL2NvbW1hbmQvaW5zdGFsbC5weWMKCS91 c3IvbG9jYWwvbGliL3B5dGhvbjEuNS9zaXRlLXBhY2thZ2VzL2Rpc3R1dGlscy9jb21tYW5kL2lu c3RhbGxfcHkucHlvCgkvdXNyL2xvY2FsL2xpYi9weXRob24xLjUvc2l0ZS1wYWNrYWdlcy9kaXN0 dXRpbHMvY29tbWFuZC9pbnN0YWxsX3B5LnB5YwoJL3Vzci9sb2NhbC9saWIvcHl0aG9uMS41L3Np dGUtcGFja2FnZXMvZGlzdHV0aWxzL2NvbW1hbmQvaW5zdGFsbF9pbmZvLnB5Ywo= --192.168.100.3.501.358.960425463.433.1500-- From gward@python.net Thu Jun 8 03:43:49 2000 From: gward@python.net (Greg Ward) Date: Wed, 7 Jun 2000 22:43:49 -0400 Subject: [Distutils] cleaning up packages In-Reply-To: <200006080051.UAA00418@bogus.com>; from Michael Muller on Wed, Jun 07, 2000 at 08:31:31PM -0400 References: <200006080051.UAA00418@bogus.com> Message-ID: <20000607224349.A1635@beelzebub> On 07 June 2000, Michael Muller said: > The patch that I submitted uses a format based on that of ConfigParser. It > allows for the definition of arbitrary nested syntaxes for defining data. > The system currently supports the specification of data elements as simple > strings (no embedded newlines or whitespace), lists of simple strings (one > per line), lists of words (words being defined as "no embedded whitespace"), > and two more specialized types for describing dependencies. Alternate > formats can be easily added. We should probably resurrect this, then. I know I was put off by the complexity of the implementation, but I'm being totally unfair. I probably would have come up with something at *least* as complex. ;-) (A bad habit of mine.) > I would have liked to have used indentation to define structure, but > ConfigParser replaces all indentation in continuation lines with a single > blank space. I'm leaning towards "Steal ideas, not code" with respect to ConfigParser. (I've been leaning that way with getopt too for quite a while. Sigh.) Anyone interested in Distutils data formats should give my TextFile class (in distutils/text_file.py) a good, close read. This is the class that takes care of stripping comments, joining lines by backslashes, and other common Unix-config-file-type tasks. (TextFile is not a great name, but I couldn't think of anything better.) If possible, it would be nice to add join-lines-by-whitespace a la rfc822.py and ConfigParser. (This would be mutually exclusive with join-lines-by-backslash.) Greg -- Greg Ward - Linux weenie gward@python.net http://starship.python.net/~gward/ All of life is a blur of Republicans and meat! From gward@python.net Thu Jun 8 03:50:23 2000 From: gward@python.net (Greg Ward) Date: Wed, 7 Jun 2000 22:50:23 -0400 Subject: [Distutils] New snapshot (soon) Message-ID: <20000607225023.A1655@beelzebub> Hi all -- I have just thrown together a new Distutils code snapshot. This is the first of several that will lead up to Distutils 0.9, which I hope to release before Python 1.6a3 (whenever that comes). (And assuming that it's not 1.6b1!) It's not available right now, but should be soon: see http://www.python.org/sigs/distutils-sig/download.html#snapshot Greg -- Greg Ward - geek-on-the-loose gward@python.net http://starship.python.net/~gward/ "One world, one web, one program" --Microsoft "Eine volk, eine reich, eine führer" --Hitler From thomas.heller@ion-tof.com Thu Jun 8 08:46:42 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Thu, 8 Jun 2000 09:46:42 +0200 Subject: [Distutils] Fw: CPAN for python? Message-ID: <030a01bfd11d$afeb1860$4500a8c0@thomasnb> [Doesn't this also belong to distutils?] From: "Andrew Kuchling" Newsgroups: comp.lang.python To: Sent: Thursday, June 08, 2000 4:05 AM Subject: Re: CPAN for python? > [...] The distutils work seems to > be freezing down nicely; the discussions have gone from requirements > to design to implementation, and are now doing the i-dotting and > t-crossing fixes, with the occasional slightly larger upheaval. But > the basic principle of running setup.py seems stable. > > So, what would people want on top of distutils? A Debian-style "do > apt-get, upgrade" to update currently installed packages? A > CPAN-style "fetch and install this module for me, please"? Simple > version checking? > > --amk > -- > http://www.python.org/mailman/listinfo/python-list From calvin@cs.uni-sb.de Thu Jun 8 09:25:14 2000 From: calvin@cs.uni-sb.de (Bastian Kleineidam) Date: Thu, 8 Jun 2000 10:25:14 +0200 (CEST) Subject: [Distutils] Traceback in bdist_rpm Message-ID: Hi, I get the following traceback with bdist_rpm command: calvin@treasure:/~/projects/linkchecker> python setup.py bdist_rpm SSL header file ssl.h found, enabling SSL compilation. running bdist_rpm Traceback (innermost last): File "setup.py", line 116, in ? data_files = [('share/locale/de/LC_MESSAGES', File "/usr/lib/python1.5/site-packages/distutils/core.py", line 111, in setup dist.run_commands () File "setup.py", line 47, in run_commands self.run_command (cmd) File "/usr/lib/python1.5/site-packages/distutils/dist.py", line 787, in run_command cmd_obj.ensure_finalized () File "/usr/lib/python1.5/site-packages/distutils/cmd.py", line 95, in ensure_finalized self.finalize_options () File "/usr/lib/python1.5/site-packages/distutils/command/bdist_rpm.py", line 168, in finalize_options self.finalize_package_data() File "/usr/lib/python1.5/site-packages/distutils/command/bdist_rpm.py", line 191, in finalize_package_data self.changelog = self._format_changelog(self.changelog) File "/usr/lib/python1.5/site-packages/distutils/command/bdist_rpm.py", line 440, in _format_changelog for line in string.split(string.strip(changelog), '\n'): TypeError: read-only character buffer, None calvin@treasure:/~/projects/linkchecker> Reason is that the Command.ensure_string() function has default=None and so self.changelog is None and not "". Bastian From hgebel@inet.net Thu Jun 8 09:58:35 2000 From: hgebel@inet.net (Harry Henry Gebel) Date: Thu, 8 Jun 2000 04:58:35 -0400 Subject: [Distutils] Traceback in bdist_rpm In-Reply-To: ; from calvin@cs.uni-sb.de on Thu, Jun 08, 2000 at 10:25:14AM +0200 References: Message-ID: <20000608045835.A6540@inet.net> --tKW2IUtsqtDRztdT Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Jun 08, 2000 at 10:25:14AM +0200, Bastian Kleineidam wrote: > Reason is that the Command.ensure_string() function has default=None and > so self.changelog is None and not "". Okay, None is the correct, so I altered _format_changelog() so that if it gets a false value it echos it back. -- Harry Henry Gebel, Senior Developer, Landon House SBS ICQ# 76308382 West Dover Hundred, Delaware --tKW2IUtsqtDRztdT Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="bdist_rpm.patch" --- bdist_rpm.py.old Thu Jun 8 04:53:24 2000 +++ bdist_rpm.py Thu Jun 8 04:52:18 2000 @@ -471,6 +471,8 @@ def _format_changelog(self, changelog): """Format the changelog correctly and convert it to a list of strings """ + if not changelog: + return changelog new_changelog = [] for line in string.split(string.strip(changelog), '\n'): line = string.strip(line) --tKW2IUtsqtDRztdT-- From calvin@cs.uni-sb.de Thu Jun 8 11:15:07 2000 From: calvin@cs.uni-sb.de (Bastian Kleineidam) Date: Thu, 8 Jun 2000 12:15:07 +0200 (CEST) Subject: [Distutils] remove_tree and PATH_CREATED Message-ID: Hi, in dir_util.py we have a cache which directories are created: PATH_CREATED. This is filled by mkpath. But it is not emptied by remove_tree because we use shutil.rmtree for this. Reproduce: run "python setup.py sdist bdist_rpm" sdist creates a distribution dir, then deletes it. bdist_rpm runs sdist again and the distribution dir is not created a second time because its in the cache PATH_CREATED. Solution 1: find all directories to be removed and remove them out of PATH_CREATED. However if rmtree gives an error we removed probably too much. Solution 2: get rid of the PATH_CREATED cache. Not a good solution. Solution 3: write your own rmtree function. I would prefer this solution. Bastian From gward@python.net Thu Jun 8 15:20:52 2000 From: gward@python.net (Greg Ward) Date: Thu, 8 Jun 2000 10:20:52 -0400 Subject: [Distutils] Traceback in bdist_rpm In-Reply-To: <20000608045835.A6540@inet.net>; from Harry Henry Gebel on Thu, Jun 08, 2000 at 04:58:35AM -0400 References: <20000608045835.A6540@inet.net> Message-ID: <20000608102052.A9780@beelzebub> On 08 June 2000, Harry Henry Gebel said: > Okay, None is the correct, so I altered _format_changelog() so that if it > gets a false value it echos it back. Thanks, checked it in. Greg -- Greg Ward - Linux weenie gward@python.net http://starship.python.net/~gward/ The enemy of my enemy is my friend... unless of course we are talking about Microsoft and Sun. From gward@python.net Thu Jun 8 15:27:34 2000 From: gward@python.net (Greg Ward) Date: Thu, 8 Jun 2000 10:27:34 -0400 Subject: [Distutils] remove_tree and PATH_CREATED In-Reply-To: ; from Bastian Kleineidam on Thu, Jun 08, 2000 at 12:15:07PM +0200 References: Message-ID: <20000608102734.B9780@beelzebub> On 08 June 2000, Bastian Kleineidam said: > in dir_util.py we have a cache which directories are > created: PATH_CREATED. This is filled by mkpath. But it is not > emptied by remove_tree because we use shutil.rmtree for this. Oops! Good catch. > Solution 3: write your own rmtree function. > I would prefer this solution. Agreed. Feel free to submit a patch -- but I'm gone for the next 6 days, so won't be able to check it in. (Unless one of the other folks with Python checkin privileges would care to usurp while I'm away... ;-) This is a somewhat more obscure bug than the "undefined changelog" one, though, so I don't think it's the end of the world if this goes unfixed for a week. BTW, two useful additions to "bdist_rpm" would be: --sdist= use this source distribution instead of creating our own (maybe "--source" would be better??? "--use-sdist"? "--use-source"?) --spec-file= use this spec file instead of creating our own ("--use-spec" maybe?) Any takers? BTW, the SourceForge patch and bug trackers for Python have been enabled, and since the Distutils are part of Python, this should work for the Distutil too. Feel free to submit patches via SF rather than the list -- if enough people do it, then I'll probably get in the habit of checking it. This would be especially useful while I'm away, so patches don't pile up in my inbox (or the list archive). Greg -- Greg Ward - Linux geek gward@python.net http://starship.python.net/~gward/ I had pancake makeup for brunch! From R.Liebscher@gmx.de Thu Jun 8 18:05:09 2000 From: R.Liebscher@gmx.de (Rene Liebscher) Date: Thu, 08 Jun 2000 19:05:09 +0200 Subject: [Distutils] install_headers,install_data References: Message-ID: <393FD245.FEC46D55@gmx.de> This is a multi-part message in MIME format. --------------619C704BE9D2B60BEEDC9A1A Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, when I tried to build a binary distribution I found that there were no headers in it. (But a normal install worked.) Also I found bdist_rpm didn't work with headers and data files. There were two problems: Someone simply forgot the headers in the install command. From install_headers and install_data you couldn't get the copied files (outfiles.) (rpm seems to use it.) And here is now a patch which solves both problems. Shouldn't header files be installed in /usr/local/python1.5/include instead of /usr/local/python/1.5/include ? Another problem is that MANIFEST is build from two sources. MANIFEST.in > MANIFEST parameters of setup() If someone changes the parameter of setup() the MANIFEST file should be rebuild. The best way to do so is to check the date of file sys.argv[0], in almost all cases setup() is called from there. It is also included in this patch. Kind regards Rene Liebscher PS: I send the last version of my cygwin-compiler class with this mail. If someone wants to try it, simply copy it in the commands directory. (The compiler mapping is already inserted in the current cvs version.) --------------619C704BE9D2B60BEEDC9A1A Content-Type: text/plain; charset=us-ascii; name="install.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="install.patch" diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/install.py distutils.patched/distutils/command/install.py --- distutils.orig/distutils/command/install.py Tue Jun 6 11:17:05 2000 +++ distutils.patched/distutils/command/install.py Thu Jun 8 18:10:13 2000 @@ -18,7 +18,7 @@ 'unix_prefix': { 'purelib': '$base/lib/python$py_version_short/site-packages', 'platlib': '$platbase/lib/python$py_version_short/site-packages', - 'headers': '$base/include/python/$py_version_short/$dist_name', + 'headers': '$base/include/python$py_version_short/$dist_name', 'scripts': '$base/bin', 'data' : '$base/share', }, @@ -272,7 +272,7 @@ # If a new root directory was supplied, make all the installation # dirs relative to it. if self.root is not None: - for name in ('lib', 'purelib', 'platlib', 'scripts', 'data'): + for name in ('lib', 'purelib', 'platlib', 'scripts', 'data','headers'): attr = "install_" + name new_val = change_root (self.root, getattr (self, attr)) setattr (self, attr, new_val) diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/install_data.py distutils.patched/distutils/command/install_data.py --- distutils.orig/distutils/command/install_data.py Tue Jun 6 11:17:05 2000 +++ distutils.patched/distutils/command/install_data.py Thu Jun 8 18:46:58 2000 @@ -25,7 +25,7 @@ def initialize_options (self): self.install_dir = None - self.outfiles = None + self.outfiles = [] self.root = None self.data_files = self.distribution.data_files @@ -35,6 +35,13 @@ ('root', 'root'), ) + def copy_file(self,src,dst): + # we need a list of our output files + if os.path.isdir (dst): + dst = os.path.join (dst, os.path.basename (src)) + Command.copy_file(self,src,dst) + self.outfiles.append(dst) + def run (self): self.mkpath(self.install_dir) for f in self.data_files: @@ -56,4 +63,4 @@ return self.data_files or [] def get_outputs (self): - return self.outfiles or [] + return self.outfiles diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/install_headers.py distutils.patched/distutils/command/install_headers.py --- distutils.orig/distutils/command/install_headers.py Sat May 27 03:25:16 2000 +++ distutils.patched/distutils/command/install_headers.py Thu Jun 8 18:47:07 2000 @@ -7,6 +7,7 @@ __revision__ = "$Id: install_headers.py,v 1.1 2000/05/27 01:25:16 gward Exp $" +import os from distutils.core import Command @@ -21,11 +22,19 @@ def initialize_options (self): self.install_dir = None + self.outfiles = [] def finalize_options (self): self.set_undefined_options('install', ('install_headers', 'install_dir')) + def copy_file(self,src,dst): + # we need a list of our output files + if os.path.isdir (dst): + dst = os.path.join (dst, os.path.basename (src)) + Command.copy_file(self,src,dst) + self.outfiles.append(dst) + def run (self): headers = self.distribution.headers if not headers: @@ -35,6 +44,11 @@ for header in headers: self.copy_file(header, self.install_dir) + def get_inputs (self): + return self.distribution.headers or [] + + def get_outputs (self): + return self.outfiles # run() # class install_headers diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/sdist.py distutils.patched/distutils/command/sdist.py --- distutils.orig/distutils/command/sdist.py Thu Jun 8 17:35:23 2000 +++ distutils.patched/distutils/command/sdist.py Thu Jun 8 18:10:13 2000 @@ -177,8 +177,16 @@ if template_exists: template_newer = newer (self.template, self.manifest) + # some parts of MANIFEST result of parameters to the setup function call + # setup is probably called from the file which is sys.argv[0] + # so we check this dates too + manifest_exists = os.path.isfile (self.manifest) + if manifest_exists: + setup_py_newer = newer (sys.argv[0], self.manifest) + # Regenerate the manifest if necessary (or if explicitly told to) if ((template_exists and template_newer) or + (manifest_exists and setup_py_newer) or self.force_manifest or self.manifest_only): --------------619C704BE9D2B60BEEDC9A1A Content-Type: text/plain; charset=us-ascii; name="cygwinccompiler.py" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="cygwinccompiler.py" """distutils.cygwinccompiler Contains the CygwinCCompiler class, a subclass of UnixCCompiler that handles the Gnu Win32 C compiler. It also contains the Mingw32CCompiler class which handles the mingw32 compiler (same as cygwin in no-cygwin mode.) """ # created 2000/05/05, Rene Liebscher __revision__ = "$Id: cygwinccompiler.py,v $" import os,sys,string,tempfile from distutils import sysconfig from distutils.unixccompiler import UnixCCompiler # Because these compilers aren't configured in Python's config.h file by default # we should at least warn the user if he used this unmodified version. def check_if_config_h_is_gcc_ready(): """ checks, if the gcc-compiler is mentioned in config.h if it is not, compiling probably doesn't work """ from distutils import sysconfig import string,sys try: # It would probably better to read single lines to search. # But we do this only once, and it is fast enough f=open(sysconfig.get_config_h_filename()) s=f.read() f.close() try: string.index(s,"__GNUC__") # is somewhere a #ifdef __GNUC__ or something similar except: sys.stderr.write ("warning: Python's config.h doesn't seem to support your compiler.\n") except: # unspecific error => ignore pass # This is called when the module is imported, so we make this check only once check_if_config_h_is_gcc_ready() # XXX Things not currently handled: # * see UnixCCompiler class CygwinCCompiler (UnixCCompiler): compiler_type = 'cygwin' def __init__ (self, verbose=0, dry_run=0, force=0): UnixCCompiler.__init__ (self, verbose, dry_run, force) # our compiler uses other names self.cc='gcc' self.ld_shared='dllwrap' self.ldflags_shared=[] # some variables to manage the differences between cygwin and mingw32 self.dllwrap_options=["--target=i386-cygwin32"] # specification of entry point is not necessary self.dll_additional_libraries=[ # cygwin shouldn't need msvcrt, but without the dll's will crash # perhaps something about initialization (Python uses it, too) # mingw32 needs it in all cases "msvcrt" ] # __init__ () def link_shared_object (self, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None): if libraries==None: libraries=[] python_library=["python"+str(sys.hexversion>>24)+str((sys.hexversion>>16)&0xff)] libraries=libraries+python_library+self.dll_additional_libraries # if you don't need the def-file afterwards, it is # better to use for it tempfile.mktemp() as its name # (unix-style compilers don't like backslashes in filenames) win_dll_def_file=string.replace(tempfile.mktemp(),"\\","/") #win_dll_def_file=output_filename[:-len(self.shared_lib_extension)]+".def" #win_dll_exp_file=output_filename[:-len(self.shared_lib_extension)]+".exp" #win_dll_lib_file=output_filename[:-len(self.shared_lib_extension)]+".a" # Make .def file # (It would probably better to check if we really need this, but for this we had to # insert some unchanged parts of UnixCCompiler, and this is not what I want.) f=open(win_dll_def_file,"w") f.write("EXPORTS\n") # intro # always export a function "init"+module_name if not debug: f.write("init"+os.path.basename(output_filename)[:-len(self.shared_lib_extension)]+"\n") else: # in debug mode outfile_name is something like XXXXX_d.pyd f.write("init"+os.path.basename(output_filename)[:-(len(self.shared_lib_extension)+2)]+"\n") # if there are more symbols to export # insert code here to write them in f if export_symbols!=None: for sym in export_symbols: f.write(sym+"\n") f.close() if extra_preargs==None: extra_preargs=[] extra_preargs=extra_preargs+[ #"--verbose", #"--output-exp",win_dll_exp_file, #"--output-lib",win_dll_lib_file, "--def",win_dll_def_file ]+ self.dllwrap_options # who wants symbols and a many times greater output file # should explicitely switch the debug mode on # otherwise we let dllwrap strip the outputfile # (On my machine unstripped_file=stripped_file+254KB # 10KB < stripped_file < ??100KB ) if not debug: extra_preargs=extra_preargs+["-s"] try: UnixCCompiler.link_shared_object(self, objects, output_filename, output_dir, libraries, library_dirs, runtime_library_dirs, None, # export_symbols, we do this with our def-file debug, extra_preargs, extra_postargs) finally: # we don't need the def-file anymore os.remove(win_dll_def_file) # link_shared_object () # class CygwinCCompiler # the same as cygwin plus some additional parameters class Mingw32CCompiler (CygwinCCompiler): compiler_type = 'mingw32' def __init__ (self, verbose=0, dry_run=0, force=0): CygwinCCompiler.__init__ (self, verbose, dry_run, force) self.ccflags = self.ccflags + ["-mno-cygwin"] self.dllwrap_options=[ # mingw32 doesn't really need 'target' # and cygwin too (it seems, it is enough # to specify a different entry point) #"--target=i386-mingw32", "--entry","_DllMain@12" ] # no additional libraries need # (only msvcrt, which is already added by CygwinCCompiler) # __init__ () # class Mingw32CCompiler --------------619C704BE9D2B60BEEDC9A1A-- From Moshe Zadka Thu Jun 8 18:49:40 2000 From: Moshe Zadka (Moshe Zadka) Date: Thu, 8 Jun 2000 20:49:40 +0300 (IDT) Subject: [Distutils] install_headers,install_data In-Reply-To: <393FD245.FEC46D55@gmx.de> Message-ID: On Thu, 8 Jun 2000, Rene Liebscher wrote: > PS: I send the last version of my cygwin-compiler > class with this mail. If someone wants to try it, > simply copy it in the commands directory. (The > compiler mapping is already inserted > in the current cvs version.) Great work, but one small nit: you use try/except in two places there. The first just catch ValueError's, and the second can catch (IOError, os.error), though I'm not sure what for: if there are problems reading config.h, it seems we're in a pretty mess: pretending everything is alright won't make it so -- Moshe Zadka http://www.oreilly.com/news/prescod_0300.html http://www.linux.org.il -- we put the penguin in .com From calvin@cs.uni-sb.de Thu Jun 8 20:35:41 2000 From: calvin@cs.uni-sb.de (Bastian Kleineidam) Date: Thu, 8 Jun 2000 21:35:41 +0200 (CEST) Subject: [Distutils] remove_tree and PATH_CREATED In-Reply-To: <20000608102734.B9780@beelzebub> Message-ID: >Agreed. Feel free to submit a patch -- but I'm gone for the next 6 >days, so won't be able to check it in. (Unless one of the other folks >with Python checkin privileges would care to usurp while I'm away... ;-) I submitted a patch to sourceforge patch manager. Bastian From R.Liebscher@gmx.de Fri Jun 9 16:49:10 2000 From: R.Liebscher@gmx.de (Rene Liebscher) Date: Fri, 09 Jun 2000 17:49:10 +0200 Subject: [Distutils] install_headers,install_data References: Message-ID: <394111F6.6BB4A9AA@gmx.de> Moshe Zadka wrote: > Great work, but one small nit: you use try/except in two places there. > The first just catch ValueError's, and the second can catch > (IOError, os.error), though I'm not sure what for: if there are problems > reading config.h, it seems we're in a pretty mess: pretending everything > is alright won't make it so If there are problems reading config.h then probably the user deleted it or moved it to another place. In this case the user has the whole responibility for his doing. ( for example he could specify a path to search -I my/new/python/include/directory ) If it was deleted accidently or something similar, then we should let the compiler complain about this missing file. I think we only should print warnings if we are sure that we are right. Without this file we cannot be sure that something is wrong. kind regards Rene Liebscher From thomas.heller@ion-tof.com Thu Jun 15 13:03:33 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Thu, 15 Jun 2000 14:03:33 +0200 Subject: [Distutils] Prerelease: bdist_wininst Message-ID: <03c901bfd6c1$bb53d990$4500a8c0@thomasnb> This is a preliminary version of command/bdist_wininst.py. I still have more plans to extend this, but you are invited to test it. Feedback is very much appreciated. How it works: - 'setup.py bdist_wininst' first builds a binary distribution in zip-format and writes metadata into an ini-file. - These two files are appended to an exe-program which is included compressed and base64 encoded in the bdist_wininst module, so you don't have to build it. - The source code and MSVC project file is temporarily available for download at http://www.ion-tof-com/~thomas. - This should work on unix as well as on win32 systems, as long as the binary distribution does not contain c-extension modules, because distutils cannot cross-compile for windows. The resulting executable, when started, displays an installer-like user interface, checks for python installation(s) via the registry, lets the user select a directory for installation, and extracts all files. If the installation directory is different from the python installation directory, a .pth file is written. Future plans: - Improve the appearance of the installer dialog, add an icon, ... - Provide a help button - Provide a rollback capability if the installation failed. - Provide an uninstaller. - More stuff ----- Options (command line flags) for bdist_wininst: --target-compile Set a flag to compile all .py files to .pyc on the target system --target-optimize Set a flag to compile all .py files to .pyo on the target system --target-version=[1.5|1.6] Require python 1.5 or 1.6 on the target system Thomas Appended are: 1. context-diffs to fully integrate bdist_wininst into distutils 2. source code for bdist_wininst.py --------> start patch <-------- Index: command/__init__.py =================================================================== RCS file: /cvsroot/python/distutils/distutils/command/__init__.py,v retrieving revision 1.13 diff -c -r1.13 __init__.py *** command/__init__.py 2000/05/28 23:49:03 1.13 --- command/__init__.py 2000/06/15 11:47:58 *************** *** 20,23 **** --- 20,24 ---- 'bdist', 'bdist_dumb', 'bdist_rpm', + 'bdist_wininst', ] Index: command/bdist.py =================================================================== RCS file: /cvsroot/python/distutils/distutils/command/bdist.py,v retrieving revision 1.11 diff -c -r1.11 bdist.py *** command/bdist.py 2000/06/07 03:00:06 1.11 --- command/bdist.py 2000/06/15 11:47:58 *************** *** 38,43 **** --- 38,44 ---- 'tar': ('bdist_dumb',"tar-file"), 'rpm': ('bdist_rpm',"rpm distribution"), 'zip': ('bdist_dumb',"zip-file"), + 'wininst': ('bdist_wininst',"windows installer"), } # prints all possible arguments to --format --------> end patch <-------- --------> start bdist_wininst.py <-------- Implements the Distutils 'bdist_wininst' command: create a windows installer exe-program.""" # created 2000/06/02, Thomas Heller __revision__ = "$Id$" import os, sys from distutils.core import Command from distutils.util import get_platform, create_tree, remove_tree from distutils.errors import * class bdist_wininst (Command): description = "create a \"wininst\" built distribution" user_options = [('bdist-dir=', 'd', "temporary directory for creating the distribution"), ('keep-tree', 'k', "keep the pseudo-installation tree around after " + "creating the distribution archive"), ('target-compile', 'c', "compile to .pyc on the target system"), ('target-optimize', 'o', "compile to .pyo on the target system"), ('target-version=', 'v', "require a specific python version" + " on the target system (1.5 or 1.6)"), ] def initialize_options (self): self.bdist_dir = None self.keep_tree = 0 self.target_compile = 0 self.target_optimize = 0 self.target_version = None # initialize_options() def finalize_options (self): if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'wininst') if not self.target_version: self.target_version = "" else: if not self.target_version in ("1.5", "1.6"): raise DistutilsOptionError ( "target version must be 1.5 or 1.6") if self.distribution.has_ext_modules(): short_version = sys.version[:3] if self.target_version and self.target_version != short_version: raise DistutilsOptionError ("target version can only be" + short_version) self.target_version = short_version # finalize_options() def run (self): self.run_command ('build') # XXX don't use 'self.get_finalized_command()', because it always # runs 'ensure_finalized()' on the command object; we explictly # want a command object that has *not* been finalized, so we can set # options on it! (The option we set, 'root', is so that we can do # a proper "fake install" using this install command object.) install = self.distribution.get_command_obj('install') install.root = self.bdist_dir install_lib = self.distribution.get_command_obj('install_lib') install_lib.compile = 0 install_lib.optimize = 0 # The packager (correct term in distutils speak?) can choose # if pyc and pyo files should be created on the TARGET system # instead at the SOURCE system. ## # The compilation can only be done on the SOURCE system ## # for one python version (assuming 1.6 and 1.5 have incompatible ## # byte-codes). ## short_version = sys.version[:3] ## if self.target_version == short_version: ## if not self.target_compile: ## install_lib.compile = 1 ## if not self.target_optimize: ## install_lib.optimize = 1 install_lib.ensure_finalized() self.announce ("installing to %s" % self.bdist_dir) install.ensure_finalized() install.run() # And make an archive relative to the root of the # pseudo-installation tree. archive_basename = "%s.win32" % self.distribution.get_fullname() # XXX hack! Our archive MUST be relative to sys.prefix # XXX What about .install_data, .install_scripts, ...? root_dir = install.install_lib arcname = self.make_archive (archive_basename, "zip", root_dir=root_dir) self.create_exe (arcname) if not self.keep_tree: remove_tree (self.bdist_dir, self.verbose, self.dry_run) # run() def create_inifile (self): # create an inifile containing data describing the installation. # This could be done without creating a real file, but # a file is (at least) usefull for debugging bdist_wininst. import string metadata = self.distribution.metadata ini_name = "%s.ini" % self.distribution.get_fullname() self.announce ("creating %s" % ini_name) inifile = open (ini_name, "w") # write the [metadata] section. values are written with repr()[1:], # so they do not contain unprintable characters, and are not # surrounded by quote chars inifile.write ("[metadata]\n") # 'info' will be displayed in the installers dialog box, # describing the items to be installed info = metadata.long_description + '\n' for name in dir (metadata): if (name != 'long_description'): data = getattr (metadata, name) if data: info = info + ("\n %s: %s" % \ (string.capitalize (name), data)) inifile.write ("%s=%s\n" % (name, repr (data)[1:-1])) # The [setup] section contains entries controlling # the installer runtime. inifile.write ("\n[Setup]\n") inifile.write ("info=%s\n" % repr (info)[1:-1]) inifile.write ("pthname=%s.%s\n" % (metadata.name, metadata.version)) inifile.write ("pyc_compile=%d\n" % self.target_compile) inifile.write ("pyo_compile=%d\n" % self.target_optimize) if self.target_version: vers_minor = string.split (self.target_version, '.')[1] inifile.write ("vers_minor=%s\n" % vers_minor) title = self.distribution.get_fullname() inifile.write ("title=%s\n" % repr (title)[1:-1]) inifile.close() return ini_name # create_inifile() def create_exe (self, arcname): import struct, zlib cfgdata = open (self.create_inifile()).read() comp_method = zlib.DEFLATED co = zlib.compressobj (zlib.Z_DEFAULT_COMPRESSION, comp_method, -15) zcfgdata = co.compress (cfgdata) + co.flush() installer_name = "%s.win32.exe" % self.distribution.get_fullname() self.announce ("creating %s" % installer_name) file = open (installer_name, "wb") file.write (self.get_exe_bytes ()) file.write (zcfgdata) crc32 = zlib.crc32 (cfgdata) header = struct.pack ("iiiiiiii", 0x12345678, # tag comp_method, # compression method crc32, # checksum len (cfgdata), # uncompressed length len (zcfgdata), # compressed length 0, 0, 0) # reserved fields file.write (header) file.write (open (arcname, "rb").read()) # create_exe() def get_exe_bytes (self): import zlib, base64 return zlib.decompress (base64.decodestring (EXEDATA)) # class bdist_wininst if __name__ == '__main__': import zlib, base64 file = r"c:\wininst\wininst.exe" data = open (file, "rb").read() cdata = zlib.compress (data, 9) bdata = base64.encodestring (cdata) open ("EXEDATA", "w").write (bdata) print "%d %d %d" % (len (data), len (cdata), len (bdata)) EXEDATA = """ eNrtfQt4U9eV7pEl28IIJIJNlMRJlCBaN3JcE5uMiYDK2HJMsI1s2TIkDsbYMrLwK9IRj4akENkT DhvlMU06aW/bSZp2pnMnM5OZ5jY0bYONSQzkwcMp0JJpIO1NZQyEJATMU/df+2z5BalnvszMN/f7 fPi29jl7r7X2WmuvvdbaW0em9P6nJK0kSTqUWEyStknq5ZDGv46iTL31tanSK5PeuW2bpuSd2yp9 TUFLe6BtVaCuxVJf19raJltWei2BUKulqdVSuMRtaWlr8GZNmZJiFTT66x9r/ceEE/Pj5eAtR+e/ hDrrlg/n/zPqitujvN57c2z+TzjMyfmfCdgXeP9HvPbrjnO8iqZ6H/XFeXQ5JalEo5M8rxTPHebb qJmsSVKFdKltf1OCD1P82aHem1S9SNJwLT0v4HAl8E+TeDYNtZtG6Ci1UpK20s1TkuRLkP7zLvC5 VfPF3Vmyd51MkiwQDDnGMIbLIkkrsgINdXKdJL0/WchuGtaJNGwLjiwVTCrMwscKFZnXo+G6sgLB QL0kZH1K0Nt4NT1p4pq4Jq6Ja+KauCauiWvimrgmrolr4vpvvarYCebUe9jpzi65aou+Y7e8ZOP5 mlDhlmKNY+P57A3RjedzHp2x8XyrPHnj+UDot28mTSka6HszKaVo4EykVO/Xl7tiaaddDim80zAv JaSj/s1JIFk08I+bpxY5Bv5u41ek5Q/29HiYbNV7ooftkrSMTXllnUOKFGoS2JSXcde5+0VqCKV7 otvQ7wDJ50HS43qReqM/RNvAHa7yWNogWpfxxs6uZfKNPtMKh+SKrkO/JzaHwzbjPrzTtLwHgm06 YcIO2e2pVvtiab8COpvzY+LWO4hySdpOFKpdivNM7CAkYIc7j8jfjDkH3ZHO01diMV86DRBLc5SD Xd7iilUZQB/aSow5Lw1kQ9Jzh2/qCh81hLvqXXG01KvQohfxGd6Z6o6FBn0JOkmKzcl+gniaB5hq vxQ7uGzZwMZY6EwsTY8W5ry0rHb5A7tVMej0IafLM9epf51u5TkuqN5V7omF9C6fNA3E0p4ifUU6 pUuxGLXG0kzlfE7wEEvbis6BpM28V4UBwGY0RkpNttPlkY5EFc/gQftP+WSaVDi/yVfCZZmzM0Lc FoJqTtfyOF9Qb8RpcAE2xsf1UcsoGjFOo+ZqGrt7XtiGSfGEBxPkRWwONYYHtXJBeFAjL/TP9KXX OSRfB/AE2sHwYJI8I2d3eDDZ+Gz3ovCxhHzW/SKRGOjtTaSaThz8mqXLe8Bgj9/q8xGybDUNEYgm Lae5chDz5W5Pztlqj4+OJvxaj1/jo3MKri2ZrGQwHIvJtojzkqs6ltZMyvV4/AmeasUJiGfwXM3m byTAw7FD4YuxkC6na+AmgtG5Y2nPocPNTscOMaeBleoVPXuTT6abFoGpuvOsfB/bYDVtXCDJ+f4a TyxNoik/vazz7DI5G+sFQ7o4baKc6qfnXBfZfLVsjf4rpmXZ2R6TPOXNpJqi0GsQGcR7fK/SCV5a CbHmy64jRbe7aHW8dpkMzzDwu/AJAyu0prvZzSRhFXPMgDiFVlNO7NdA7Zq7wWoJTcvpCs/nyjQ+ 0+VAr6Waqwh6zKiurkI1L9bHToevxEJ+dQBMWugG6qYSvRHzvQxr09jxW2AN/EN40CVPcqlsDdwB EGs0EQuBQxDDKnV/whjaUwnSJ0OK/sfU0a3R1y6CdKTQmuqCFNmNrDilkTkM5H7mkSVTBz7M9JHu gk7zSBPATK3266o96qR52BwxaQdJtZP5MDUYZuCW6upqf8LQ3EVjB+0fh9J5f/EIZbZc4srEZCew N2qXP/gAHsicwifyMLkhQyMr0jfO10vGzu+TdP68iHOXH3if3S1JrOg6QDvYIybF+Tb8hl+jON9j RTMeUJyH/Xm+XRiGoD9xKY/silZOkTDf8jSX72W0RyM06ezwsoGvEYjOFa2cCj+HpXKDy/d9Amim BbzmOna4OlomcRcIQFf01wYiUytnuXwdBOaM07m5sbMrNCO2ZkYsZILVR0vuJiSDX/PAQELOEb4O HKSpHrJbjy9Kq3EfV4SV26oHqjH7NfhMj6WlogkatnCXky58rxmugJWa3OxBg6eabZh8IVI4+bji vGQrNtj2hvtnsP3aC5vyXIsTk5SqM8bObwM87DVJjeF1KZLxiQ14HNCyqjOs5NY7IrpbI7nTtJ8R uCbB2LkKnZsWuBZrdcbOBwivNwscR1JvNW5feotSddq43WUxbneka/u0vRg+Ms9k3F6UbtzuuVG7 S7tfW3UmUnjjLYrzRKQzyn3z/DnwY/zed7qOpvkrc1QVqv3CV3Yk0pPiHASxG11qXyx0Gt0nqFvQ 2itJQ/cDuUQmdeOvEv+E5xq5wRPHGnT5pehqbkwUSxbHQic8rujP1KXa2WXs6BhB5scgE4nQfbhf q+12+U7QVP4tJw7g0JQ44HODNLvOS2wORRXjq46U7qMmjOTTDAecgxgccz4yBh0ESswJHTlS5qLa +pcgpnqV3fClA+ew3nRkizw9QBrw9ZD2TanGEfpYnWgrTXSVHr7O7YmUJByvtuWbbPmGcPTuTXNp etnpiG6GsfNFSLQpb50n9zpj51/jvvOsceuTqLGSddt1oNGolEZZsUkp/ZQVG5TSs6xYz04rpads 7aZqNSGA4SI+r450vk/iorGYe0V5vtsvqY2+vJU88haqHdaI8yjkd/sTolcuIPaVHvWUu6IlXO/p FAtm9gzc4jOvHFrgA8m+M1AuJidMulyW0xWPwuET6fAeLorWOdBOdXXE+cdqV+wgRrkVt+TjKNrz u2LcDYEMHKmNx0sDpAQRSgsQbCleNmNo3/NMnRdDpPPMFTWOzuNiICWxIATlnHX5NWqfx0UH6xsR McjknIO9zkFSnSviPOOTvgkcD5KCS7E0HbrjoxIADO8SJ20Yps7TE+4o9GKES2NHgHHNQoBXQojx zkseTl2vUkdXytyQQU6EpcBlUE6w6USqRk1UEinfouCiN3a8hba5ifvQgIhJvmNOJbnYql+e0EqS seOv6PsGFzdH34B2OC/KBKgvox6QouWQqqe0DWQIUZ8ZXVWxgz4D1RjJivvBleq9BfdRcZ8OLVqk WKU13ff2yhHUKDJgmn/zOaYZYKnLAGKuiqWtc1F2Mjfxx1uxgjq+/V/PnV+zXMnm/L08lj9P9G6w p0FUWzaGPYTtBx+Qzf5s30/JgjaTBQvWKJPaTrbwehdEqPZEH8lGyk35cqHvKBKhagRIi2/DsAng OcO3Tn3mzn0QLdmu6KIzsAYssigPpMK7Z9Qu37STprkHXkEfPuG4k+fYVZ5qY8ejuCuW7XeehgHJ puLQQ36K3Cu49gYo1q4QrkhVpWxtUBUZ/QEWZP93gGV8tdBaU1xs7LgdpO78E6DknHA0UdYXF4dm +pMGEvwwt+jLFMSWcXv3faxSqomlbeRpZX8FyLBmayWbv5RWoeTrB0QVUrGbK8tJxD4/0g084853 FLPjO8H7OTrXmI+vF04YzXkU2qK3fx1LYhv11iyTp/Ag4Ylq0CjY8ETNXxdKnuTxRFPPEoOe6EAW 0J7fDjQpevFTLL85G8lI5vxxPaEcHIy7/+uj3RDJtzPOjjqVA5N9L41h0K+J895PMZDH36VIDtHV 7yE3LFsrfRsfBlIUSB5FmARfdlwfOUfcXCEeKOROVSG/cftOqS10/8vTWtoy8Qeu7F8g7fInIVcp tDZEX8IDUvCdprkl1kq01ISm2rtDKb514LP/e1grL3QwSgkTQzqlxFqDlJ3fVBK4/LVtNI7LTclZ NglD5P94gVSF9HuYh5zdAK+Rre44Yyo0eIj+XEC7R0BWhu4i+FBmbA4NTomgr7J+hIMzoMnk4mr0 qLoYuJPdTPWwCXlgDfPiysYDGOofYojHQkr1HDtMEg8FjvAjBqN8PZJznj6pu6x2moVXJFJfxNmF 2MA3E6T6w1DfgwY4B5Ij5bvLzp3P2e07g+HK1Quj/QpmizswnUkeZL6FopE7dgiyKs7UWFo6nl+3 PEx282wmTM3l8Rv9RuTyVnSAeRgXjylpZkpzow8JmBR/CrX2cU4NJE1aKo8cXSp768BR7fKcrgd2 q6JtyzDBVqszSQjsj2A0RK7XeZjeEeh1vj/7VoekhP6ohI7C40nfIhtzRpXQiVhaDdentFFSnKdj aRlAw6Y64jz8y7wGSKKEBpUHEZdWAIoyz+s9vky0+wwNQxs87rgojes8/DEWg9Qwcgo9ZLDzSX+I Qf5pEMRvwofHo0J7XLCItAaemWI3F0vzqRlpM7Woey/P60fXxRc3/FKaDxz6aDl6oic/gVW9SIsS C5hYe6phOON/+LS6fbpeXbyuqP4cQec+oUIji1/af4kmnd3cQNuqatd2mia/69e/ohhY9fpmknNj A/HTVx3degrYsTmE7ndxf1zlWxfvbBvu9NEX53wpV/na1X7+FF0MGHbzCjoIUSFzTlb5GlQIteFF irVVvqWj2iicVflKxEgv0kqJGq6QJKryDcS77570+HT4vbT3iaV1lMcdlroheIGo1drfQPRJxvTU 8HC0HMbztnpRrphzwL7DI+ew4nT7HjlTcaUqLr3iMrOHDOd+f9PZivBHyS5lNnOks+LU8uhAIk9j iYhO2kY5Ct08Fb/4sRE2zPewonR4yhxWZu3cLWcyRyqeUpAzvzWd8PXoZmUZrvKYx4qn3qJ0Oty6 BlHwh+1ITszea+w4B5At0pYptPO6p9vY+SfaOG2wmvOMne9L3Jka7OdCKRy/lmRkRRblUbO9N5TS W2Qx5cHEH82Y+6g1lNxbZM3GIzjwY1MEJiwQyd6rFKUD/dIQeonVpKxLZZ50+17lm4ZHDGD63G97 HZQWSuHz+g3LwueN36pE/zZq6Tuq3GdiZems3HDudzcdcJ07sOnDo3c7pAqkBVAaejCIkk/0PHO/ mRoyRveC0+Hhou14pAQW957oz6hvSJLabRe4UkzDmlYvRHI6o+g8i3iu09GmNZ22I+ex/sMLkBBR eGBIRXKOhC/otiMcxIzP9iz+dSJJ8IeLSo3VTDOhD5+fYnx8J4UyayQ7gzSj69xt7NiMlkU5B5Qy HSvT57OLSpmeTd0yTXHpCGsGdgLhY8aFG8/rlRlyWq80hWbBk95bZL4Ew1X8uoEfAYS5TN39unC3 3r5njXkkUFQF6v8muOqlkyhwryPup2HY4pzdShGG0TvYRbY8XSnSs6ScA7++lWxA71CSWIGu+6he 233u884D8m29Wk4WTEEiLh3o7yP6Pl0/HXKc7bYYOzdhjF5tMkHGwfovQ8cw7GpPedRB+hvEJIVj l0Nm4jFBUO118PeJ+vfRWUgslMAuhmMaY2dTgjrmReZKjRTryj0V0bfVJjqbLDbA8if3SgbC/M4V klE/LOOdACzGGEJIkhYSsotb9N3HzMp9uCchMbQ0aRhpkHIGD+ageKHi0XPU9JwDW6aBg2J994cm 7R6leARmyjDm638eUz8Gc/IwZscITI4GfI5ZDCSYxDAan2vMsrFjGSl6xExvEzP9FDbMoyaJHwLy gUKTWC9F7R36EXzC9Ip0GIp03P2hGX4JKipLx3C9Gu21MGcUj9JnUfqWFJod6NSk3a+iezg65bhX o08dQj8g0K+tICXji3i+SkOj9KNXyrJ7pSQMvY0EH8IdYWlF5p9CWcLghANQoYaGKkvv1ZBRca8j GrddHoZExRHpfpXVIf0e5b2vOKSpX3VIpSibUd5DqZrlkHagnEOZjf7VKAYsfjNK3L9w/0s+vZqO 0FnZPIV0uMFqCg/q5ETKHKcyj4Hdm1HhilWTKw8vSApNgfuoLo9uvF64+oxeEllSinKVomxWlCfc fWcX3DLdyFOR5ONfbJ9SNE+5N7t2ec+Qf6OzKKvJ7/BrMAjGsLDTdIpyNqSjU1S2JMP3PCzJry9H F/nXIivmZRqrzvBUqAzxI4EeMjkQcPs1rjhgBgBvRXwCbDnBohvgHtcotBLadWoPV3uU5ZlKWZ4q SPQj/uWAgacqPaP8cfhENlSW58Z4eVVMz+ApCyxsdTqyagNbnEvnt6wg22PfVa1UIrqUWAuDibbu 4oFEVpBp66YdJtOGBycZH7/BQM64swQBBOo3hy9rg/MYYW+wptKynAI3lrO7eIuxt9BK70JKbD97 p+/D8Bt6GmPyp/cCQwGiAvjAuwM6wmNvho8ms137o+FjmvCgVllsXvs0xpAxRviktlfLXfA74WPJ 3ae0fads/YTf3wxLQgQppm1oRaTEmuGKVFqzy/GYV+GKvoSZhJJqAJFLgod3ppbjObOCGlzlFVE2 hZ+pKQXcmXwMrkGcCPMRSZ39KRhhZCOt7P7PyS+jhWYfhFPDly3BTGQqF4wdzyeR6NBfyRb9kmGx N5DYDsDR8UDgPXaQvYsQfIzeku0+bsrZb+z8ESGeZN32N5TFOqXZajZ2fEUj1qKi7X/sCpfU1HnA 2PGrJC5XOqJg5w9ILcFMdBXaD4ZmYv7Ywxn2XvkGdsi+D2wUBpNtO4rZrgGd7VP2rsKxQqvAdAko FLvK3Yo7N/qzm0DEncuC2ZRqHASPJSoqe9e2ZxHmf3GmbQ+MgNDt+0IWGuIcH+KgGOLTMoZ5tO1g u9QhjB3Lk3hwh0Xp4lZg37Emge2wd+OzG+pLhfoK2S62v7s/4bOfsD2ATg8f09r2ffZjMm2uXNla qCWSqWyxzjaoPW3bRarEbBRi4HRoytjpI79dYFa/OUuGqqovq7MTvjw1mDfSLO8a3yyncpM8EDfJ WbFvAGoXDCR87Nbw+ZuNjyeRWPuQPMEQNl14no6dHv8Ui7w7mhg+eqtfF+nQJ9AhGsZ1seKM8piL L+gCfhAbIcBTU8Mnp/YWULhFwCdXOqAXxpTK3FiS+u7jKeEdOvuOoI9W1l0kAmHnJv07VhVnny3W 8+UEi2Wpkedo47LYQFase5q59QsVt57twFDxcQLPAWHbdJqhXcHbCHkIqVf3NB8JWGwP8Oy7Ah/Q gmOLrRWRAlPEnVpe0StR1uJiBQZXdNF16ooqtJrBcudtEFgp0PdqE0eLWaCjUfaR0j68FXqLdCSQ 1uy7jOGHKaQXmOzRYA7luGRKdspQ9+fs3mK8jxwTiQ2h+z6M6wGi26Nc8neYrnMpnQ4uTp35JsJc ZbcmousGkpk5dOFBE/jKDd7E9tiOM7eh7xSYUHRboHEHmOw/Rnnn4HW/IGlkbaT403D0OrJmsizt Husg7rPDXZPt/UF7nLOjumtzhv7skdz1c+52U7LL9mBcUGWGCHE6811tNz32ndLusfUTQ9S3WEer givn2K2RrSmkHFoe2n32/cbH/17Hn3IJL3zBFJoUPq8xPvZttPIniMYqt1waSMg5wB425BcrlU9e Cn1Oeleg9C9W/WOd5GPgFZjbCrBycqgO+NNCfpeJO2s5TKKC7QNa93HCL1+YqAFyhau3IJXbM7zs JLV2kPuMfjeN7MFK9kD2wf0OXxVW3GJl6MlKclV5islHY/x55J8tBJteDi/+UTI3KVoB1ToyJ53q mkeYUyFwaT8UtCir01k2O6Qg2yvW2w4qeVpyKyWU6CCcVbjcyuLc6HucoiE8iDSZ59Uy8At0HhfY ruQxdKWR9kQ68qYLmFvESDNiJDi2kwtKJZu6ZoQs4IZPX633anlevmsQWgWHgru9zMR8ehuxVajt B1cl5S6RUSk+vZLHHfLtMziH6klRdk9cwF4tKTf8xmWs5V6HeZ0XmatKFZgQWc8O+S/b9tMcao+7 BDkI3Jc2mlzJEDezWZNeKdexfdCVBsMUao9zfTXpKxAaCnKjz12NqnLB9vkv9+ablw7zQLRsB7XH OaHicmW9DmQ4EfdVRMxcI4st5OjVOfPp2X4wwedJZUJopYIE4WIY0sZqxcxFQRIDB0hk5pI4+TqK yey0orGd054CD9Ao0YNE0d2pVyu2cshyoDDkRCa2Nz49/kuu4UmJpP6ZSWGHMCG5V00InwzI4788 YjoKxxC65sIID14OJQna43BJ+iwfwegfp1/FqEA9BBPxDTHFlTLG+MDeT74Q/d9lu41Xo8MjVQxL 5yI3KCTbC62ZR2mNRIP4QzNweYRgk0eTpvOV0UoqGakkdUGMENZcMWIStl93zdn8IvRhSwBueAwu fJerwh1tHt2s7uYHDESAuymZu7gSUHB53NEFgIZHYW6edO2X/4I4xNgK/A3FkizFo2OHXLbfsFa9 9rhHadUrC/joiWOH0V9rGDO3mAIuTRbrJWIeve0Nv0a7z0O7bJXWL6Zdc2Vy3NGrkyZmxAJV54XT CE0bqw3zkDbdliF86JM2LFfYfk6jmFzFEI3ZY2jEznzNIZ28wyGtsCGaZzqke+50SLdlOaT2bId0 /RyH9CjKDpSlgFmDchhl2WzHqCMo2hsaaItm8Eue6ug7n8AR35vByrCVMvDTPYaNVRFtrLBBxBN1 6KvFsR/tsUZvn0bQY3tF7v6xCbu9FLHZ3WGQaG9l7jxi/MuP6X24TRdfhstiPYHEbXRjO4wUxLj1 BbLWaPdJXc6BcNS0ZUb4TZN2D5IVzyfa8+rNp/Gbz+I3Z+I3n8dvzsZvzsVvBuM35+M3F+I3F+M3 l+I3l+M3V+I3MbrRni81djbE6K0a2YDWGdo9RdrzxaEzrDvnwC8+gcjnPmG92+mGAevcuc4j7ILx 8enAeJD1PtB91FQ7uZsUEd+fY6b1rvLoB9x160crlL71c0XN3Bvqevhzqj8dm+mhvBlc3L6l0qrb AiqbXSaYlmFz8TTudfkbh3QeXGzuGdrfppL+LfzY0cq0SKMQkjOYx8KwtW/VIWZbmSe3mj2KXQyC twnBewcF76JM2w7amLFSKXwe+9srSfywUe9wSPMpOTI+9gP1ONeUYnzsr1Rnk8Htu4hCT6byaDqz YzPCdtn2sof12vOKVnlYr3hyWZWZOVPdngqkiKXToM8qE+07g5ReINXfBR4fTcfIhXQaXEms0i7c AXbDO82cx+yRPHbuJi7l6YvO/fam3eFjCeHuZKVU6nfSLtiZSmOYFKdeKTX0OtUjS6fBPhgsjG8g anTq0WUh37VmItvJlviRJbZje/uOQqCMcK9+8i6gYWQSMDPfTmlvZuBXzKAm1hB8JgD0Ed0uTsm8 pZjCfUZflBJXrm7KZ822wZyuLRp6L4gt4vFYKdWDK76nfhZ55k9Ncnr4qBHssnyd4uQg6Kfdbn+I +h3GDidk+KnF2PEHLdc49ZNH7a+iPNWph2gL46LdqONb4sxi/hIaRh4hUFxOEkw/VrDX4zsGtM/s ZqU67S4SRynVsVJ9XxRDUhanymUbZE4zpHbqMZnQ8hj1fkf7363eEUqMK5mmngJyf/ZlrsRO+gJd cRqg5YihW0xE//TLV2nwcMJ/kgYNcQ0a4hpMHKnBogxsv0gH2GumwarhdbU7bISnJtBI69HPd0FO XWcXcQzVauhETn3Xh5Vl2vdTOh66jZZ1WYa9W57O9tv3qSuF3ks023YMcH3A/lbRMqy0Zle4PdG3 UujQl5bYPL7EDFhiyLZGLjFQpzUmRrgd5Ckf+7NDGDuOaNQDmYVDcz5p8320lUrPL7aXZYqpSw0l gxyXrFS3CBZm7Mygbxec6o+Xv3WRvO6XlvFPk/5rZORfcJUOmcLmlIVkKalx7rsv8F1OBlyhcIrM BlfIdvUW8PzQ9o6ihV9UvaJgdd6kEUE/tQek+N6xwOxodFzLxRJB7mWxyXnHLbwskpnc6Kf6L6CU AUoDr/xHGXtxNLk/x4qitb0zFr1hNHo4lrwmjfAJOfyxHjtyIkacQJnAcwEnW8+njZXxKdsj0xED 57nMwlFtNBqWm4udd9sus9V67cfKZGW1Kv5nyWPF1187SA1rUDNGgy8n/7tF9l8ZgyuPxn3qvTyH 9PRch9R8j0M6jfJPdodkneeQFs5H7vYNh/QkSukCPsU6F08S1L3B2ASh3E3JlsWv80+H2fEfnMfP 2Q9TcnAkNEn9hvKBZZR1ppPJeqpYszU9AtbddNZrqahy8fP76f7p5dEHiMLp8M6M8JXLoRtZdYa7 ovde89a1Dkk9V2dvPriciIWvXJSTwo9IUsiAfh/6X6evMDjCaMhR+cymE6dpgK3WMxJ/jYm9YqVX BHJOVivN1kKUYpQSFBdKJcpSlBqUFSgNKD6UZpR2FBllHcoG5SUrvdfMDjJNuFvHajoKI4UdhQX3 KebQybmytTB0K0bkL8g+Y03n78wpX1PuoMnYtJP46WHf5+2/oIwgQom5nc5Q52aEJuWHu3Th88Y1 n7Fu+3lazcEkMk12/jUjwb7CB56bFdLfFz6ls/8mdMZ+AVlK5pokfth1gb63kxR730f2PcHrIjVb C20562blh3t0+9ES+DRieJbnaJiFSI2hkJUYCm2fKLLVsd409I2QYFH7LqTcTMCTc3bfJ0/POaIt SS8GpfuUrenUHvoY0nFlHmH80PIdOv+Vb2fPbKW3W9lL1gz6/cBW/qTUPCstVKaRSeSchHL06Cqw /zbwBp0rsQ/OHWFbUznWMxxLUSFoddm7oXEreOFkgA+7M9PPEdC0k5qarfOMT25K4GdGuZGSjkIe DSlzS2H7F3UeIGGNHQsAEDHY7d3GJ5I1XAN5CGviywJAZ8JG6egiT/uBrc+p3Ws/RAf+BLYmAXv0 ZnC5y/aW+OI+8ojG3rvmq+G9Maz7ZmuGthfqNufjYzp7RBd+Q7f/KPqTbb1oCpxkHVZ6h3Y7x/0T kzDV87SDm2L0RZTx8Y9VM7GQrjJ30HqJPNNBggk0hc7LzZ1dyh1yHuXQm5GAKq/wF4j5Qfpbmwut sxG93+yLsvsukb9jn9s+6b6itZ1WUrsVuVs3MAmkyBoV8h9ELhVqeDJGKdtWru4t+6CJ9Dv6Nlda Z4MXUn3E8LT9fCD5TbjDroFi9heApPcY7J8EUzddoUz2pgPhD58P71gBnOwBi+0TANB7g90fJWxJ nY0Hem9w4w4Xy51NEOFeHcROZ5SHWG1vvcZ18SF7qy9qR1QM3hIpeUMCD9naHcrcyLzfcCN9SIdp QG/gI0iVylUfuY++cbH2He3cIetz9u2Pdu4IDXLFsrdy9pGioOCt6tvVHR3CYqxLZl6wn5etoG8O R3VLwAj/msj2gcAEjp7DhN6nqMutYheFUguPtLuNnTsu8696eJLlIFunvIgOHDOMTzytfrfhyDlp /1y+HjuSTI1s2nZx9GqirevQA33hSk4y/jzKv1bxbzDz/DofmQQZ+zWc7GTxGsiDqpulr9KsZMBD TjaXDmwzXeW+5yocks9MH3QqXFURPU5ZATnczrPGzj7ViqzhPMnY8aYkzrARaIYI5RGhDP6bjHLf U24i5qafIhl+WlEe/eEwrZCV4ML3SCH9pss01Nrp9P3piG9HH+RenJz8kgx3OZx43rphJx/vvgjX KbrT1wkfPxbmkkwhYHAoBBD8WJgRseS9tVcPo5J45ZpRRIUZ3g/r2JQVlPxUWvWK/oWGRp5WG5QE OpDJ6erV+NDSm+Bb46CJLKfdroHvds1sNfa1D2ezIoP9MmXwZHdrtGx1Jisy2T62R+FYop0nZSNM xnIxRGkc/3abeVJtb2h/oxSZFE8qK8jDhnsqWzyvqro8tk8pmEdfib/DznEjFV/T0cnSnvAxrfaN z37M2xdnai/DRHEbepQV5LIgklX6ujSkVYK5tNTBmu0Uu9f0xUxUq0zca1KqRzLhEUzcm82dzzts PxvkTGjfYHvENsssWFHUw+B0UlTtcqXcoBQQlnmEeul8gOd/cNnuKtaUy8otHvZQdjXLYw6d/RSn mJ9OmgtOsn1eBiFS4c4WZSJFpG8gydOrX9rwHB6rc/jREh5MDd5OGdMiiqD0jRD7hO3q+yjcpZ98 8F70Bj7kroAwZWv2zD05R7akvxvJfbfziLHjCQpsu7eUafqOYxOEcc72mEJzz/Zg+zaTYo3hB3yD tVw3c4/2rZGIVddAlHvDfzDaegQSMMrotdlMeJ7j4UHjn2XSOMSkheLbMJNXMTebM5eo+SLmrmJq L5iy9wRt/JtV82gezoOHP9Gulvg4lG/voX1J4BCbp1Iu0828YOvRnmdvwdwz2ed9x+kg0faWmJQ8 tijD9on9XOB6xKJzzi1TizaXxkQVHkgYsNouA5fgHsq0nbN/sGa67YMtUzeXSs6iJaGzakeGaFiM BrA3cMMQ/1vKdOihAZ3EcOqmDdZUOhIK3MOPgwI5/Qnqt2bzwJyJPaTrzeebDttnMJ9MdppY7j6l tX9mfIzeA+zvU18GVKHLdLa32OHuAa39t8EELl6e7bzitkRS3+Fbkx1KQTo3/RnYUxfp6VW3vcoC 2x5tt4Kn1bmqp6Oc+2yPRfb8p9EdenmHbwVGyea4lmwBHaMGGuYKH+ZzdRh2SAykPc3y9YixbLbt oDJXu6NWyadxEJrII6q7hqeeis06Qy8gz7rEP3X0tugsPf808890/mnAp/p+aPl8erEV0UMfSN3U T/d30kenhrcHTyBR2dmpYceYHuvbRT9g8cd8+kqElewyh9TwAv/TVw3KLKrDJ3xuT7XijeYcUR68 5E+Ipb1Cr8WGp+TRW+/hKfOoiqVtoxeqp7xNi14fS+viT7v40ws76UF60QHA6P09sdjcm5+n3yEb fLeX0Quvu4hctJ/+nJVhBVjQ4yP6Hr3mvpPwnc9EnM+4YnO66MfMzu+7Is6nUJ53xdL20cvFOkKR COUF/os86wvv0XDZSmjrxgW3h+4pws2WpHt6ZN2820OfUpNuRJNlzafKg/sizh+DXAfwzjr3aeRp xled7w1M3bjAsuYwwQ587k9Z6vK43bG0pfxt5Rl99Au154BzmMZynoAeJymlm13l0RkS/Vyhh3mj sdDmWNpR9L8dm/VHPm/v88+3XfwVbi19aKTo9SpCTlfP28NXbNbLHPYllzqjE7+g///7Sr0fH/er 99PEX2rbukySvo+yDWUnyksoH6K8t0yFe88jSVdQDNWSZEW5G+U+lJ1oi6Ksw/0WlB+ivETtKEdR nkPfKyh/i3I/nn0oMu67sMe/B3URSgXKYygNHnWs+8HbGpSNKP8KuB+ibEV5FOUASivKcpT7UBag ZKFYUdJRpqIkoZwG7kco76PchTIPpQjFhfIcSgNKK8oBlCdQulB+hPISys9R9gj9NC5FP8qPUP4J RYeSimJByUJZiOJB6ULZh7IC+ipDmYeShXILigHlCvp+j3IcZQNK67KRM0LfUal/Ng/zIV0nWulw iA7S6YyMDuTpVVw6o6UXa+lMjN7fpFNveu2TDuSnShL/OsEo8C1NrY3NdbLXMjtrdlaOpaCtfX2g aZVPtsyeO3fOnfjIs5TWBVZb8huavQGLNPQ3IRPFeMmCh0li7MliLKPgk95EIodxEwq9Uz2Tggm9 gk9vKKEU0PEKCv1twCC5QxT6RWgPyh+IZ81/zG41Y0rCmKIdU3RjSuKYQle7KNIImiP1ENf/FCHz DSi3ocxGyUehv4+4CaWb8OknyigaEKFXi+lnb/QnJzVQIr1sq8EEa7Bz00DXmmwUB8qKL5ZzrFxj 5UgaMU/xuYrPV3zO4vM2WdiLQcgyhVtdLPZvpQ7pE5SXKofHz6R17sKaH9F2Fus2F21vVw23bYQN Z5ZjfY+EQ1sq4J4f0WaltYQ2xwjcC2h73jXhn/6n+6eCJaUFlSU5d2U1NDfDurTNQTnQ7G2F6b+t KWmrr2suCni90j9LRW2Bljq51BsM1q3yovegprSu3dPkXbuksaip2QsfUdDcFvQW17XC2UhzpIKA F56JugDX3tS6CjjXae71ytTkbvqmV8odAZMv3Uh9JXVB2RkItAUk6aEE96jnOwV0YVPAWy+3BdaD 3pQ4vXxZDjStDMneIFqbCZNaK5tavFKtVNgWLAQiPVW2DbW/nFDV2jJKgnqiVultaaensroWktIb b3PVyT48vyKROkqaVgbqAuulHdBQXYN4Qu8CgnYF2urzGxoC0JQkfYVaStsaQs1CM4Cqlgq9zd64 3LkqTtMasAjURjQuapXzpXuubndDSK5H6zDVEbwudlaUOYdmMhVaaG0Ynq+XEtYG24EvN+ZLr2tE +8K2dfnSs1JhU7C9Tq73DUM/llAZqGsNUnARjbBkjcvrXT0MY+QjFDavWiR7W4aaM0n7orHSuw6S 3C0V+Lz1qyvqGpraFoZkua1Vkn4hOYHaVNfctkrSkTSjMF5Fb93KZm91U2tD21qKI8MQkvRLwnXV QRSsKOpxrw9yDqCe+iB5wIXeVU2tAqID2m5UCfGZkaSnE6raGyBYnLo/we1rWxt/WibsTH12Qj+f aipAD0MECprrgmRh3+PzXhAKBNsC+dK3JVUQKNNVF6hryZeq3M6K+Dy4xWwvWemH3UrSZxo3WdQ6 uaCtmew6MYEeloQgtvQu9S1cjZn1Sr24bwZGHO/u+GppI+soFU/utuamhoWBUBDZ/b2Fi8SgDxPH 5SFvYL2nrjnkJSGkALUtafe2Lvaup4b8Qk++K44g7UrAspfbcPdzuquvw4h/l4Ahmpvb6qXXeFv7 etJdi9okvZ6gOgp4woRGchFSr0pjtSQd09SuCbaq1obISe2thP4qp+OD1H+d0OJt4RS/S3dBL8Yr SWisJxcCn5fQuDbQJOOuOqGxDTxL2zhmCwL5dpUaGFya0CiGcCTUC65K3Z6CikpVpj6p1ruuSZaK pdql9e3kETCF0qIE3ig9KdXW1bc0NLdKS6Xa2lVeuQX2UhdYFZSMmtqm1iYZwC3IaGprwVwo6CXv 5/MGwPsPgNngDwXl2saGpjWwH8C019bWt7XQ38GWpDb1uVF92qRSqIUTrJXXt6NlD/FV722Xa33c JQSQTr0qAb9VDrQ1N0JGF7dquS4gh9oXtTa25UvbNbUQuyHUPrG5mbgmronrP3RtQJkVnEXbNKmp pb0tIFva15PDakf2YB9xnyVqS0bgq7OCX/0avfUdapWRL1lEGibd39y0Mv6wZI03wB21BT41KCM5 sVCe8g0a5wv6gt9ISXFRbmRZ5nRb5DZLfkl1/jK3pe0LwDNT2jl02RICLnN6nBXjwhbklxU4Szhx 92LskeGlmxpCiBDrs0by1dYuN7W10r51TGZpyZgVJNGlURmuaL0qr72qXW0QW3OkKpYAAkigNWiZ 1UD6F1v2kY2ibRGizl0jO/i2nvbX99SsRUhqDco1jXVNzcEsHgklae1K5PgIojW0Dwda+9B/09DU uqYOmYGlLWBpqGtBYtbAc/22UHODhf7/hnrOrQVpE6wByStXoPRoQ0hytzXKa+sC3hrXetnX1iqq gja0zGrImtVQswhsQJeUEPP9Ne+f1UByrOV2VjMrmNXOO7mZBC1t9fWhQMDbYFnrI/WoNgbNSRRZ 2zlfosUCaWjeULVlZWVJX9BXL/pc62uXYBJbsJsoaq5bhWdYa60bJh5PljlMEQJ7M+04cE86blKf kHEgiyPKqgwqUdU4efCl0ZpUaSFLRcWSinssFd6HQrCToMCxwJqCsCLLbKgmDlOg/h8ZjbA8S13r eksoSMlsHENQrCPjw3iLRjxaaHa9DVy2Ue2kMkoiGyy8z7lODtTVDxs+cU6bmqCloq2lrlXYwqzg 6DkPiCzWspantpZ6ymZV2CzvOm/chtTEl6e6hE8C1rY0tdJ6x6zEPQXu64fuYb9t3BZkXyv2IpLc JDcP0RvFAyVznGfOXasXEjU01ZOMtJ9qaq1vC9AitNB/TGGpp20D91lD7T5vXQMkED1xKxcCBWlW Q62rW9vWqiqjqST1tXih+YZh+JVNsgWp6yrZB6W0eynZleS2NksLzZbooJUDddW11nstwfUtK9ua g0P4QXgJcL4SKedqAR9U+RT0eYea7dFFP9ZOb3RI9MdDTKgllDNeh3QUZR/KNq/aR3K2YCfWROYi LIvwV4YaGyG1V7hgwAXR0lTf5G2VIVwLfJbENSYgkCp64QSG4LnCx/S1jtDHkKD1PGUdam+GmwzU NX9dqET0qmdPdD61IlkcZOnFfy+iV884K/XqeWBFsnpuSO3tos4WBLporSWr51fUvkLUFtH/fPyA VNQbRe0Q/UcFfpJoXypqs+in/6bEnayeU1L7OlHnif59qMqT1TM/aveJOkP0vyye9aLeLOpi0X9a jK8T7ZWipp/fVenV808a3ybaZVHnCvxdYvwpor1B1FbR/1PxHKffIepC0R8V48f5qxF1uuh/juYh WT2fpfYNop4n+g+L+bletDeLOlP0bxPPBlFvFXWJ6B8U42tFe4WorxPyvyjknynaA6K+S+DvFPJP Fu0rRX276P+xeE4Q9WOiXij6/yjGTxbt94v6RtH/jJC/QLR/U9T3iP73hPzTRbtf1HeI/lfEc9w+ t4j6PtF/RoyfKNo9oqZv5LqE3ZL8OaJ9jajvFvhvC/mNor1R1F8R/S+J57h9/6Woi0T/CTH+JNG+ XNS3iP7vC/nrRfujol4g+t8X8t8k2ltFnSX6fyWep4r6CVGXif5LY9Z/ueifJuY/PGb9PyTq2QJ/ x5j1Xyfq20T/j8SzRtSbRJ0v+j8cs/6XifoG0f9XY9b/elHPFf0Hxqz/JlF/TfT/q3iO61cR9SLR /+mY9V8l6jRq16vffYxc/yFRzxH4e8asf6+oZ4n+/y2e4/bVKWqn6D8+Zv0/KOqbRf/3xqz/R0Q9 X/T/bsz6bxH1naL/NfEc5y8i6lLRf2HM+o+PM13Mf8+Y9R8UdY7Af3PM+o/b6UzR/7fiOU4/LOoC 0f/RmPX/gKhvEv3fGbP+Hxa1XfQfHLP+V4vaJvp/Lp7j/DFRLxb9Z8es/2pRX/8F63+tqP9C4L87 Zv2vEvVXRf8/iee4fI+L+l7Rf2rM+q8V9a2i/4dj1v+3RP0N0f/7Meu/TdRfF/2vi+c4f0+Keono v/Il43/3OPH/hXHi/7Fx4v/T48T//ePE/38ZJ/5/8iXj/+5x4v/fjxP/+8eJ/98dJ/7/dpz4/4tx 4v/5Lxn/3xgn/v9knPj/f8eJ/8+OE/9/M078/z/jxP/Pv2T8f2ec+P+P48T/k+PE/x+ME///bZz4 /+tx4v/lLxn/e8aJ/y+OE///ME78//Y48b9vnPj/s3Hi/2dfMv6/NU78/4dx4v/AOPH/f40T/4+M E/9/OU78v/gl43/vOPH/78aJ/38aJ/7/9Tjx/9A48f/VceL/uS8Z//eOE///eZz4//E48f9vxon/ H4wT/7ePE//phSZXoro+qxPVd2Pciep6eiBRfRemPFHVz7JE9V2ZqkR1/T6YqL4bQ/g0v0sT1Xdq KhPV9V+TqL5DU5Goynd/ovqOjSdR9QNdiep7NYSfIMbfJMa/IT6+WR0/OT5+kjp+XXx8ga+Lj69V x58dHz9bHX9KfHyDOn73iPHV8xo6mLM0rG+ta2mqH3G0FLTI9LUoHVYHQyuD9YGmlXTa9UVwI2iN OXbh3WPpXBPG29Iurx8+zaFGy9omdI86oxrmeSQg9Y3ldWx//N0lrXgfySjeCyObIvsim4gBIEZ/ IxQAMQDEAEB/vCv2rfhbcMKnT1wT18Q1cU1cE9fE9V94aXgOZr7qf2zX8D1H9jXak3XqOceKp5Af XeP/t+/S7+I4fO8mpWo+4PUi7CGDkowMqxn/6nDXhKyylaeNpdgfWFDqOAzdeaUA+hvFiBp+fFQp 7ZHuwo6zXxuLbQQM0QqoJycExWGeEDAJEsEUYKQ2UIynJxs5TLq0TfodYAa0LeirB4Vm1LVSO6i1 IdMOAD6Ifzn8NMI1pnW24CmB00qWXpKSkHyeAE+PCflIsnoxok7/LwIuGXAbpSjgNom+SeJYLFna irw3RTrF5ari/FrQtR6UfFxHFoyape4NSQppE8e7Q/oepJ0qfXwNmksEzdPj0Lx7aNbi8vwAOZue vxv+mFQISUhu0lEb7tar5yMj9D0IHtLAw6d8nCz+b+KauCauiWvimrgmrolr4pq4Jq6Ja+L6n3H9 Pzrvwu8= """ --------> end bdist_wininst.py <-------- From R.Liebscher@gmx.de Thu Jun 15 17:18:10 2000 From: R.Liebscher@gmx.de (Rene Liebscher) Date: Thu, 15 Jun 2000 18:18:10 +0200 Subject: [Distutils] Prerelease: bdist_wininst References: <03c901bfd6c1$bb53d990$4500a8c0@thomasnb> Message-ID: <394901C2.4C94318E@gmx.de> Hi, I haven't tried it yet, but there are some problems. First of all, you use the zlib module, which is not always installed. (It is comment out in python's source code.) Would it be possible to use an external zip program as make_zipfile in archive_util.py does? Second you use struct without to specify the byte-order, for Windows you need little-endian. (Sun uses big-endian, and your installer wouldn't work?) So you had to write " header = struct.pack ("iiiiiiii", > 0x12345678, # tag > comp_method, # compression method > crc32, # checksum > len (cfgdata), # uncompressed length > len (zcfgdata), # compressed length > 0, 0, 0) # reserved fields see also http://www.python.org/doc/current/lib/module-struct.html And finally, it seems you use the registry to find out if there is a python installation. However, it is possible to have a working python installation on a zip-medium (you only have to add the directory to the PATH) and this has certainly no registry entries. (I use this if I want to try python programs and extensions on another configuration. For example on NT, because I use python on Win98.) It should be possible if there are no registry entries, let the user specify the directories (and python1?.dll) to use. (I know python1?.exe find its directory for itself, but what happens if you load only the DLL? I think then you need the function void Py_SetProgramName (char *name) to help python with this.) kind regards Rene Liebscher From thomas.heller@ion-tof.com Thu Jun 15 19:41:27 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Thu, 15 Jun 2000 20:41:27 +0200 Subject: [Distutils] Prerelease: bdist_wininst References: <03c901bfd6c1$bb53d990$4500a8c0@thomasnb> <394901C2.4C94318E@gmx.de> Message-ID: <008601bfd6f9$507ea0e0$4500a8c0@thomasnb> > Hi, > > I haven't tried it yet, but there are some problems. > > First of all, you use the zlib module, which is not > always installed. (It is comment out in python's > source code.) Would it be possible to use an external > zip program as make_zipfile in archive_util.py does? It is only used to compress the ini-file which will not have more than a some hundred bytes. These could easily go uncompressed. I found the compressed base64 encoded bytes of the exe-file nice in bdist_wininst, but there will also be another solution. The funny thing is: - On windows it is enabled by default. - On windows, there is usually no external zip-program (I suspect many people will have winzip installed, but this has no command line interface). - Python 1.6 will include the zipfile module, which would not be very usefull without zlib. BTW: My suse 6.2 box which I occasionally use HAS zlib enabled. So: Do we really have to assume zlib is unavailable? > > > Second you use struct without to specify the byte-order, > for Windows you need little-endian. (Sun uses > big-endian, and your installer wouldn't work?) Oops, will fix that. > And finally, it seems you use the registry to find out if there > is a python installation. Yes, finding python installations is something I have scheduled for later. > > kind regards > > Rene Liebscher > Thanks for the feedback. Thomas From akuchlin@mems-exchange.org Fri Jun 16 03:38:06 2000 From: akuchlin@mems-exchange.org (A.M. Kuchling) Date: Thu, 15 Jun 2000 22:38:06 -0400 Subject: [Distutils] OSF/1 glitch? Message-ID: <200006160238.WAA01394@207-172-57-117.s117.tnt2.ann.va.dialup.rcn.com> This was reported on the XML-SIG by Mark Favas, and looks like it might be a Distutils problem. ================= The link step also appears to have a wildcard quoting problem. The ld command used is: ld -shared -expect_unresolved "*" build/temp.osf1V-alpha/extensions/pyexpat.o build/temp.osf1V-alpha/extensions/expat/xmltok/xmltok.o build/temp.osf1V-alpha/extensions/expat/xmltok/xmlrole.o ... which works correctly if put into a /bin/sh script produces pyexpat.so without warnings of unresolved externals (the -expect_unresolved "*" pattern matches all). However, when run by Python via the "python setup.py build" command, ld complains about all the unresolved externals: ld: Warning: Unresolved: fread strlen strncpy strcmp ... as if the pattern that ld is trying to match is literally "*" ================= Presumably the link step quotes the * for the sake of the shell, and sysconfig.py doesn't know this, so it winds up passing "*" as the argument. --amk From R.Liebscher@gmx.de Fri Jun 16 16:35:59 2000 From: R.Liebscher@gmx.de (Rene Liebscher) Date: Fri, 16 Jun 2000 17:35:59 +0200 Subject: [Distutils] Prerelease: bdist_wininst References: <03c901bfd6c1$bb53d990$4500a8c0@thomasnb> <394901C2.4C94318E@gmx.de> <008601bfd6f9$507ea0e0$4500a8c0@thomasnb> Message-ID: <394A495F.A1A69BC7@gmx.de> Thomas Heller wrote: > > I found the compressed base64 encoded bytes of the exe-file > nice in bdist_wininst, but there will also be another solution. > If it would be a base64 encoded zip-file which contains this exe-file you could use zipfile or a real zip program as make_zipfile in archive_util.py does. > The funny thing is: > - On windows it is enabled by default. > - On windows, there is usually no external zip-program (I suspect > many people will have winzip installed, but this has no command > line interface). > - Python 1.6 will include the zipfile module, which would not be > very usefull without zlib. > BTW: My suse 6.2 box which I occasionally use HAS zlib enabled. > > So: Do we really have to assume zlib is unavailable? I tried four systems, Windows and SuSE 6.2 had zlib, another Linux and AIX didn't have it. But I still can on the latter two do a "bdist --formats=zip" because an external zip is available. I tried it meanwhile, it looks great. But I found a new problem. If you don't provide a long description, it is set to None(?), so the marked line fails. > # 'info' will be displayed in the installers dialog box, > # describing the items to be installed > ====> info = metadata.long_description + '\n' > > for name in dir (metadata): > if (name != 'long_description'): > kind regards Rene Liebscher From thomas.heller@ion-tof.com Fri Jun 16 19:19:43 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Fri, 16 Jun 2000 20:19:43 +0200 Subject: [Distutils] Source and patch: swig support (and more) Message-ID: <036101bfd7bf$71d40930$4500a8c0@thomasnb> This is a multi-part message in MIME format. ------=_NextPart_000_035E_01BFD7D0.353E54B0 Content-Type: text/plain; charset="Windows-1252" Content-Transfer-Encoding: 7bit The included source code and patch implements a swig class (derived from ccompiler). Currently the swig options used cannot be configured with command-line flags or somehow else although they certainly should. Simply include 'xxx.i' files into your extension source-files, and swig will be used to generate 'xxx.cpp' files, which will then be compiled and linked. Other stuff included (only useful for the windows crowd) Resource scripts (*.rc) and message compiler files (*.mc) can also be used as extension source files, and MSVC will invoke rc.exe and mc.exe to create .res files and pass them to the linker. Comments welcome! Thomas ------=_NextPart_000_035E_01BFD7D0.353E54B0 Content-Type: text/plain; name="swig-diff.txt" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="swig-diff.txt" Index: ccompiler.py =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/python/distutils/distutils/ccompiler.py,v retrieving revision 1.22 diff -c -r1.22 ccompiler.py *** ccompiler.py 2000/06/07 03:00:05 1.22 --- ccompiler.py 2000/06/16 18:05:42 *************** *** 655,660 **** --- 655,664 ---- for src_name in source_filenames: (base, ext) =3D os.path.splitext (src_name) if ext not in self.src_extensions: + # if extension unknown, return it as object name + # and assume someone other (maybe the linker) + # can use it. + obj_names.append (src_name) continue if strip_dir: base =3D os.path.basename (base) Index: msvccompiler.py =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/python/distutils/distutils/msvccompiler.py,v retrieving revision 1.30 diff -c -r1.30 msvccompiler.py *** msvccompiler.py 2000/05/30 02:02:49 1.30 --- msvccompiler.py 2000/06/16 18:05:43 *************** *** 170,179 **** # Private class data (need to distinguish C from C++ source for = compiler) _c_extensions =3D ['.c'] _cpp_extensions =3D ['.cc','.cpp'] =20 # Needed for the filename generation methods provided by the # base class, CCompiler. ! src_extensions =3D _c_extensions + _cpp_extensions obj_extension =3D '.obj' static_lib_extension =3D '.lib' shared_lib_extension =3D '.dll' --- 170,182 ---- # Private class data (need to distinguish C from C++ source for = compiler) _c_extensions =3D ['.c'] _cpp_extensions =3D ['.cc','.cpp'] + _rc_extensions =3D ['.rc'] + _mc_extensions =3D ['.mc'] =20 # Needed for the filename generation methods provided by the # base class, CCompiler. ! src_extensions =3D _c_extensions + _cpp_extensions + = _rc_extensions + _mc_extensions ! res_extension =3D '.res' obj_extension =3D '.obj' static_lib_extension =3D '.lib' shared_lib_extension =3D '.dll' *************** *** 195,200 **** --- 198,205 ---- self.cc =3D find_exe("cl.exe", version) self.link =3D find_exe("link.exe", version) self.lib =3D find_exe("lib.exe", version) + self.rc =3D find_exe("rc.exe", version) # resource = compiler + self.mc =3D find_exe("mc.exe", version) # message = compiler set_path_env_var ('lib', version) set_path_env_var ('include', version) path=3Dget_msvc_paths('path', version) *************** *** 209,214 **** --- 214,221 ---- self.cc =3D "cl.exe" self.link =3D "link.exe" self.lib =3D "lib.exe" + self.rc =3D "rc.exe" + self.mc =3D "mc.exe" =20 self.preprocess_options =3D None self.compile_options =3D [ '/nologo', '/Ox', '/MD', '/W3' ] *************** *** 223,228 **** --- 230,266 ---- =20 # -- Worker methods = ------------------------------------------------ =20 + def object_filenames (self, + source_filenames, + strip_dir=3D0, + output_dir=3D''): + # Copied from ccompiler.py, extended to return .res as = 'object'-file + # for .rc input file + if output_dir is None: output_dir =3D '' + obj_names =3D [] + for src_name in source_filenames: + (base, ext) =3D os.path.splitext (src_name) + if ext not in self.src_extensions: + # Better to raise an exception instead of silently = continuing + # and later complain about sources and targets having + # different lengths + raise CompileError ("Don't know how to compile %s" % = src_name) + if strip_dir: + base =3D os.path.basename (base) + if ext in self._rc_extensions: + obj_names.append (os.path.join (output_dir, + base + = self.res_extension)) + elif ext in self._mc_extensions: + obj_names.append (os.path.join (output_dir, + base + = self.res_extension)) + else: + obj_names.append (os.path.join (output_dir, + base + = self.obj_extension)) + return obj_names +=20 + # object_filenames () +=20 +=20 def compile (self, sources, output_dir=3DNone, *************** *** 254,267 **** if skip_sources[src]: self.announce ("skipping %s (%s up-to-date)" % (src, = obj)) else: if ext in self._c_extensions: input_opt =3D "/Tc" + src elif ext in self._cpp_extensions: input_opt =3D "/Tp" + src =20 output_opt =3D "/Fo" + obj -=20 - self.mkpath (os.path.dirname (obj)) try: self.spawn ([self.cc] + compile_opts + pp_opts + [input_opt, output_opt] + --- 292,345 ---- if skip_sources[src]: self.announce ("skipping %s (%s up-to-date)" % (src, = obj)) else: + self.mkpath (os.path.dirname (obj)) +=20 if ext in self._c_extensions: input_opt =3D "/Tc" + src elif ext in self._cpp_extensions: input_opt =3D "/Tp" + src + elif ext in self._rc_extensions: + # compile .RC to .RES file + input_opt =3D src + output_opt =3D "/fo" + obj + try: + self.spawn ([self.rc] + + [output_opt] + [input_opt]) + except DistutilsExecError, msg: + raise CompileError, msg + continue + elif ext in self._mc_extensions: + # compile .MC to .RC file to .RES file + # '-h dir' specifies the directory for the = generated include file + # '-r dir' specifies the target directory of the = generated RC file + # and the binary message resource it includes. +=20 + # For now (since there are no options to change = this), + # we use the source-directory for the include file + # and the build directory for the RC file + # and message resources. This works at least for = win32all. + h_dir =3D os.path.dirname (src) + rc_dir =3D os.path.dirname (obj) + try: + # first compile .MC to .RC and .H file + self.spawn ([self.mc] + + ['-h', h_dir, '-r', rc_dir] + = [src]) + base, _ =3D os.path.splitext (os.path.basename = (src)) + rc_file =3D os.path.join (rc_dir, base + = '.rc') + # then compile .RC to .RES file + self.spawn ([self.rc] + + ["/fo" + obj] + [rc_file]) +=20 + except DistutilsExecError, msg: + raise CompileError, msg + continue + else: + # how to handle this file? + raise CompileError ( + "Don't know how to compile %s to %s" % \ + (src, obj)) =20 output_opt =3D "/Fo" + obj try: self.spawn ([self.cc] + compile_opts + pp_opts + [input_opt, output_opt] + *************** *** 374,382 **** if extra_postargs: ld_args.extend (extra_postargs) =20 - print "link_shared_object():" - print " output_filename =3D", output_filename - print " mkpath'ing:", os.path.dirname (output_filename) self.mkpath (os.path.dirname (output_filename)) try: self.spawn ([self.link] + ld_args) --- 452,457 ---- Index: unixccompiler.py =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/python/distutils/distutils/unixccompiler.py,v retrieving revision 1.25 diff -c -r1.25 unixccompiler.py *** unixccompiler.py 2000/05/30 02:02:49 1.25 --- unixccompiler.py 2000/06/16 18:05:43 *************** *** 131,136 **** --- 131,139 ---- # '_prep_compile()'. =20 for i in range (len (sources)): src =3D sources[i] ; obj =3D objects[i] + if src =3D=3D obj: + # this is probably already an object file + continue if skip_sources[src]: self.announce ("skipping %s (%s up-to-date)" % (src, = obj)) else: Index: command/build_ext.py =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/python/distutils/distutils/command/build_ext.py,v retrieving revision 1.42 diff -c -r1.42 build_ext.py *** command/build_ext.py 2000/06/07 03:00:06 1.42 --- command/build_ext.py 2000/06/16 18:05:44 *************** *** 147,152 **** --- 147,153 ---- # also Python's library directory must be appended to = library_dirs if os.name =3D=3D 'nt': self.library_dirs.append (os.path.join(sys.exec_prefix, = 'libs')) + self.build_implib =3D self.build_temp if self.debug: self.build_temp =3D os.path.join (self.build_temp, = "Debug") else: *************** *** 157,162 **** --- 158,164 ---- def run (self): =20 from distutils.ccompiler import new_compiler + from distutils.swig import Swig =20 # 'self.extensions', as supplied by setup.py, is a list of # Extension instances. See the documentation for Extension = (in *************** *** 173,178 **** --- 175,185 ---- if not self.extensions: return =20 + # Setup a swig object to use + self.swig =3D Swig(verbose=3Dself.verbose, + dry_run=3Dself.dry_run, + force=3Dself.force) +=20 # If we were asked to build any C/C++ libraries, make sure = that the # directory where we put them is in the library search path = for # linking extensions. *************** *** 366,373 **** continue # 'for' loop over all extensions else: self.announce ("building '%s' extension" % ext.name) =20 ! # First step: compile the source code to object files. = This # drops the object files in the current directory, = regardless # of where the source is (may be a bad thing, but that's = how a # Makefile.pre.in-based system does it, so at least = there's a --- 373,387 ---- continue # 'for' loop over all extensions else: self.announce ("building '%s' extension" % ext.name) +=20 + # First step: Pass all sources to swig, let swig generate = files + # as needed, and return a list of files to pass to the = compiler + sources =3D self.swig.compile (sources, + output_dir=3Dself.build_temp, + #macros=3Dmacros, + = include_dirs=3Dext.include_dirs) =20 ! # Second step: compile the source code to object files. = This # drops the object files in the current directory, = regardless # of where the source is (may be a bad thing, but that's = how a # Makefile.pre.in-based system does it, so at least = there's a *************** *** 434,445 **** modname =3D string.split (ext.name, '.')[-1] extra_args.append('/export:init%s'%modname) =20 ! # The MSVC linker generates unneeded .lib and .exp = files, ! # which cannot be suppressed by any linker switches. = So ! # make sure they are generated in the temporary build ! # directory. implib_file =3D os.path.join ( ! self.build_temp, self.get_ext_libname (ext.name)) extra_args.append ('/IMPLIB:' + implib_file) self.mkpath (os.path.dirname (implib_file)) --- 448,461 ---- modname =3D string.split (ext.name, '.')[-1] extra_args.append('/export:init%s'%modname) =20 ! # The MSVC linker generates .lib and .exp files, ! # which cannot be suppressed by any linker switches. = The .lib ! # files may even be needed! Make sure they are = generated in ! # the temporary build directory. Since they have = different ! # names for debug and release builds, they can go ! # into the same directory. implib_file =3D os.path.join ( ! self.build_implib, self.get_ext_libname (ext.name)) extra_args.append ('/IMPLIB:' + implib_file) self.mkpath (os.path.dirname (implib_file)) ------=_NextPart_000_035E_01BFD7D0.353E54B0 Content-Type: text/plain; name="swig.py" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="swig.py" # created 1999/07/05, Thomas Heller __revision__ = "$Id$" from distutils.errors import * from distutils.util import newer_pairwise, newer_group import string, os from distutils.ccompiler import CCompiler def find_exe (exe): for p in string.split (os.environ['Path'],';'): fn = os.path.join(os.path.abspath(p),exe) if os.path.isfile(fn): return fn # for vers in ("1.3", "1.2", "1.1"): fn = os.path.join(r"c:\swig%s" % vers ,exe) if os.path.isfile (fn): return fn return exe class Swig (CCompiler): src_extensions = ['.i'] obj_extension = '.cpp' ## obj_extension = '.c' def __init__ (self, verbose=0, dry_run=0, force=0): CCompiler.__init__ (self, verbose, dry_run, force) self.exe = find_exe ("swig.exe") def compile (self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None): (output_dir, macros, include_dirs) = \ self._fix_compile_args (output_dir, macros, include_dirs) (objects, skip_sources) = self._prep_compile (sources, output_dir) print "SWIG!", include_dirs print "SWIG!", self.include_dirs for i in range (len (sources)): src = sources[i] ; obj = objects[i] if src == obj: # nothing to do continue ext = (os.path.splitext (src))[1] if skip_sources[src]: self.announce ("skipping %s (%s up-to-date)" % (src, obj)) else: self.announce ("swigging %s to %s" % (src, obj)) self.mkpath (os.path.dirname (obj)) try: self.spawn ([self.exe] + [ "-python", "-dnone", "-c++", "-ISWIG", "-o", obj] + [src]) except DistutilsExecError, msg: raise CompileError, msg return objects def object_filenames (self, source_filenames, strip_dir=0, output_dir=''): if output_dir is None: output_dir = '' obj_names = [] for src_name in source_filenames: (base, ext) = os.path.splitext (src_name) if ext not in self.src_extensions: obj_names.append (src_name) continue if strip_dir: base = os.path.basename (base) obj_names.append (os.path.join (output_dir, base + self.obj_extension)) return obj_names # object_filenames () ------=_NextPart_000_035E_01BFD7D0.353E54B0-- From mhammond@skippinet.com.au Fri Jun 16 23:14:14 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Fri, 16 Jun 2000 15:14:14 -0700 Subject: [Distutils] Prerelease: bdist_wininst In-Reply-To: <394901C2.4C94318E@gmx.de> Message-ID: > (I know python1?.exe find its directory for itself, but what > happens if you load only the DLL? sys.dllhandle is the HMODULE to the current Python DLL. But on Windows, this is in the system directory, so isnt much use. > I think then you need the function > void Py_SetProgramName (char *name) > to help python with this.) How generic do you want this to be? Eg, if Python.exe is not the host, then it may be something _completely_ unrelated to Python (eg, MSOffice). So even if you know the directory of the executable, I dont really see how that helps you. Id be inclined to use the same technique as Python itself to locate its home - look for a "landmark" module - os.py is used in Python 1.6 - then one directory up should/could/may be the Python home. Mark. From gward@python.net Sat Jun 17 03:19:01 2000 From: gward@python.net (Greg Ward) Date: Fri, 16 Jun 2000 22:19:01 -0400 Subject: [Distutils] remove_tree and PATH_CREATED In-Reply-To: ; from Bastian Kleineidam on Thu, Jun 08, 2000 at 09:35:41PM +0200 References: <20000608102734.B9780@beelzebub> Message-ID: <20000616221901.A497@beelzebub> On 08 June 2000, Bastian Kleineidam said: > >Agreed. Feel free to submit a patch -- but I'm gone for the next 6 > >days, so won't be able to check it in. (Unless one of the other folks > >with Python checkin privileges would care to usurp while I'm away... ;-) > I submitted a patch to sourceforge patch manager. Thanks, got it -- checked it in, tweaked it a bit, and now I'm happy. Greg -- Greg Ward - maladjusted nerd gward@python.net http://starship.python.net/~gward/ Whatever became of eternal truth? From gward@python.net Sat Jun 17 03:29:27 2000 From: gward@python.net (Greg Ward) Date: Fri, 16 Jun 2000 22:29:27 -0400 Subject: [Distutils] Prerelease: bdist_wininst In-Reply-To: <008601bfd6f9$507ea0e0$4500a8c0@thomasnb>; from Thomas Heller on Thu, Jun 15, 2000 at 08:41:27PM +0200 References: <03c901bfd6c1$bb53d990$4500a8c0@thomasnb> <394901C2.4C94318E@gmx.de> <008601bfd6f9$507ea0e0$4500a8c0@thomasnb> Message-ID: <20000616222927.B497@beelzebub> On 15 June 2000, Thomas Heller said: > It is only used to compress the ini-file which will > not have more than a some hundred bytes. These could easily > go uncompressed. If zlib is available by default on Windows, go ahead and use it. I don't imagine that creating Windows installers on Unix will be more than a small sideline, simply because of the lack of cross-compilation. Also, we can generally expect that people creating built distributions will be fairly sophisticated Pythoneers, at least sophisticated enough to comment out the "zlib" line in Setup when building Python. > I found the compressed base64 encoded bytes of the exe-file > nice in bdist_wininst, but there will also be another solution. I find it really weird, but if it works... How problematic would it be just to include a wininst_stub.exe right in the Distutils source (ie. under CVS control, installed alongside the code and system config file)? If it's small enough to include encoded in Python source, then IMHO it's small enough to include as a separate file in the source tree. You would then find the stub in the same way as the system config file is found: os.path.dirname(sys.modules['distutils']) BTW, what was your alternate plan for finding the exe stub? Oh, let me know when/if you want me to check this code in: the patch of course is trivial, and I will read through bdist_wininst.py itself just for paranoia's sake. But if you're happy enough with it to let it go in CVS and code snapshots, just say the word. Greg -- Greg Ward - maladjusted computer geek gward@python.net http://starship.python.net/~gward/ There are no stupid questions -- only stupid people. From gward@python.net Sat Jun 17 03:33:04 2000 From: gward@python.net (Greg Ward) Date: Fri, 16 Jun 2000 22:33:04 -0400 Subject: [Distutils] OSF/1 glitch? In-Reply-To: <200006160238.WAA01394@207-172-57-117.s117.tnt2.ann.va.dialup.rcn.com>; from A.M. Kuchling on Thu, Jun 15, 2000 at 10:38:06PM -0400 References: <200006160238.WAA01394@207-172-57-117.s117.tnt2.ann.va.dialup.rcn.com> Message-ID: <20000616223304.C497@beelzebub> On 15 June 2000, A.M. Kuchling said: > This was reported on the XML-SIG by Mark Favas, and looks like it > might be a Distutils problem. > > ================= > The link step also appears to have a wildcard quoting problem. The ld > command used is: > ld -shared -expect_unresolved "*" [...] > Presumably the link step quotes the * for the sake of the shell, and > sysconfig.py doesn't know this, so it winds up passing "*" as the > argument. You mean what's happening is this: exec(['ld', '-shared', '-expect_unresolved', '"*"']) when it should be exec(['ld', '-shared', '-expect_unresolved', '*']) Hmmm. The right solution, of course, is to shlex everything coming out of Python's Makefile, and then quote it again when we print it out. ;-( Sigh... added to the todo list... Greg -- Greg Ward - Unix geek gward@python.net http://starship.python.net/~gward/ The real Nazis run your schools / They're coaches, businessmen and cops -- Dead Kennedys From akuchlin@mems-exchange.org Sat Jun 17 13:50:28 2000 From: akuchlin@mems-exchange.org (Andrew Kuchling) Date: Sat, 17 Jun 2000 08:50:28 -0400 Subject: [Distutils] OSF/1 glitch? In-Reply-To: <20000616223304.C497@beelzebub>; from gward@python.net on Fri, Jun 16, 2000 at 10:33:04PM -0400 References: <200006160238.WAA01394@207-172-57-117.s117.tnt2.ann.va.dialup.rcn.com> <20000616223304.C497@beelzebub> Message-ID: <20000617085028.A10736@newcnri.cnri.reston.va.us> On Fri, Jun 16, 2000 at 10:33:04PM -0400, Greg Ward wrote: >You mean what's happening is this: That is Favas' theory; it should be pretty easy to check by finding someone else using Distutils on Digital Unix. --amk From gward@python.net Sun Jun 18 16:32:35 2000 From: gward@python.net (Greg Ward) Date: Sun, 18 Jun 2000 11:32:35 -0400 Subject: [Distutils] Re: PyXML build problems In-Reply-To: <394C2A2E.DF42AF0C@per.dem.csiro.au>; from m.favas@per.dem.csiro.au on Sun, Jun 18, 2000 at 09:47:26AM +0800 References: <20000616223554.D497@beelzebub> <394C2A2E.DF42AF0C@per.dem.csiro.au> Message-ID: <20000618113235.B697@beelzebub> [cc'd to distutils-sig, in case anyone out there knows anything about OSF/1 and its progeny] On 18 June 2000, Mark Favas (in private email) said: > The generated ld command above is fine for using through the shell, but > will fail if the quotes are not stripped - the pattern will be a literal > *. If I change the definition for LDSHARED in my > /usr/local/lib/python1.6/config/Makefile from > LDSHARED= ld -shared -expect_unresolved "*" > to > LDSHARED= ld -shared -expect_unresolved * > and re-run "python setup.py build" the link step works fine. The > Makefile is attached. Good thinking -- I was afraid I'd have to implement a general quoting-and-unquoting mechanism when parsing Python's Makefile (or rather, the bits of it that are shell commands). I bet I can get away with an OSF1-specific hack to deal with this problem, though. ;-) Note that (I think) your fix will break builds with the old Makefile.pre.in mechanism, so you'll want to go back to the original Makefile once I've fixed Distutils. BTW, what do os.uname() and sys.platform return on your system? Do you know how consistent these are across various flavours of OSF/1? Also, didn't OSF/1 mutate into Digital Unix, and then Tru64 Unix? Do you know if these later versions are similarly affected? Thanks -- Greg -- Greg Ward - programmer-at-big gward@python.net http://starship.python.net/~gward/ Never try to outstubborn a cat. From thomas.heller@ion-tof.com Mon Jun 19 21:13:40 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Mon, 19 Jun 2000 22:13:40 +0200 Subject: [Distutils] Prerelease: bdist_wininst References: <03c901bfd6c1$bb53d990$4500a8c0@thomasnb> <394901C2.4C94318E@gmx.de> <008601bfd6f9$507ea0e0$4500a8c0@thomasnb> <20000616222927.B497@beelzebub> Message-ID: <00a101bfda2a$dc4bcce0$4500a8c0@thomasnb> > > I found the compressed base64 encoded bytes of the exe-file > > nice in bdist_wininst, but there will also be another solution. > > I find it really weird, but if it works... It's not really my own idea, /F uses something similar in his squeeze utility, and also in PythonWorks. The advantage is that there only is a single file. > > How problematic would it be just to include a wininst_stub.exe right in > the Distutils source (ie. under CVS control, installed alongside the > code and system config file)? If it's small enough to include encoded > in Python source, then IMHO it's small enough to include as a separate > file in the source tree. You would then find the stub in the same way > as the system config file is found: > os.path.dirname(sys.modules['distutils']) I would certainly prefer to include the whole source into distutils, but first: currently distutils cannot build exe-files (not even on windows), secondly how would the exe been build under unix? Third, can distutils _install_ exe-files? > > BTW, what was your alternate plan for finding the exe stub? Haven't thought too much about it. > > Oh, let me know when/if you want me to check this code in: the patch of > course is trivial, and I will read through bdist_wininst.py itself just > for paranoia's sake. But if you're happy enough with it to let it go in > CVS and code snapshots, just say the word. Well, it is certainly not nearly finished, but I would like to get some more feedback from users before working on it. So yes, please go on, check it in. Maybe you want to fix the problem before Rene Liebscher found: change header = struct.pack ("iiiiiiii", into header = struct.pack (" [Follow-up to the Distutils SIG, please.] There are a few steps needed to find and install a package: 1) Discovery : which module does what I need? 2) Download : where can I get a copy? 3) Security : is this actually from the package author, and not a Trojan? 4) Installation : how do I set it up? 5) Checking for new versions: I have 1.0 installed; is a newer version available? Distutils focuses on the hardest and most complicated step, #4. For #1, you would need to browse through a list of available packages, browse through a hierarchy like Parnassus, or do keyword searches. #2 is pretty simple, since you just get one or more download URLs corresponding to a given package name, using the same database as in #1. For #3, you'd have to check a signature on the downloaded package, using something external like GnuPG. This means this step has to be skipped if the external tool isn't available. We could implement our own signature scheme with Python code, but that's a bad idea; security is hard, and few people will bother to generate keys that are only useful for this one application of distributing Python modules. (Side note: the sdist and bdist_* commands should have a --sign switch to sign the generated .tgz, .rpm, or whatever file.) For #5, the existing stuff in Tools/versioncheck might be partially applicable, though it requires that every package have a text file somewhere which gives the latest version. You'd want to use the same database for everything, to ensure that people actually use it! To start off with, we'd need some sort of generic API to the above functions, so that different interfaces can be written. A command-line interface would then be easiest. I don't know how network communications should be handled: HTTP to CGI scripts that return sets of RFC-822 headers, maybe? Combined with a DNS alias like modules.python.org, or modules.{us,uk,...}.python.org? Some potential sources of inspiration: Debian: apt Perl: CPAM.pm FreeBSD: ports system RPMfind (rpmfind.net) XEmacs: packages system -- A.M. Kuchling http://starship.python.net/crew/amk/ "Jo, it's a pity escapology wasn't part of your curriculum." "Funny you should say that. Look." -- The Doctor and Jo, tied up, in "Terror of the Autons" From gward@python.net Wed Jun 21 03:07:20 2000 From: gward@python.net (Greg Ward) Date: Tue, 20 Jun 2000 22:07:20 -0400 Subject: [Distutils] Autoconf in Python Message-ID: <20000620220719.A1208@beelzebub> Those of you who follow python-checkins closely probably already know this, but for the rest of you I think this will be news: I now have a working demonstration of the long-mythical, frequently procrastinated, "Autoconf-in-Python"! Marc-Andre, you were right -- it wasn't too bad. I think I probably spent more time combing the Autoconf docs for inspiration, and figuring out how to sensibly translate Autoconf's byzantine shell/M4 interface into sensible OO Python, than I did actually coding it. Here's the bird's-eye view of how it works: * module developer defines a custom command, "config_xxx", which inherits from the standard "config" command (distutils.command.- config.config). (I suggest we adopt the convention "config_" + distribution_name -- which, come to think of it, is probably a good convention for *all* extended commands defined in setup scripts.) * this custom "config" command then calls the various methods provided by the standard "config" to probe the system. Currently available: 'try_cpp()', 'search_cpp()', 'try_compile()', 'try_link()', 'try_run()', 'check_header()', and 'check_func()'. (The 'try' methods are fairly low-level and expect you to provide a chunk of custom-crafted C/C++ code; the 'check' methods just take a header name or function name or what-have-you, and Do The Right Thing.) * the custom "config" command uses the result of the system probing to determine preprocessor macros to define/undefine, include directories to search, libraries to link against, library dirs to search, and whatever else might be needed. Currently the standard "config" command provides no support for this, although it probably should. (My thinking is something like this: users can provide manual overrides by editing the "[config]" section of the setup.cfg file; the custom config command -- if any! -- will then either respect the manual overrides or probe the system (or a combination, depending on which manual overrides are present). At the end of the day, there are a bunch of settings -- macros, include dirs, libraries, and library dirs -- sitting in the "config" command object, which are then used by the various "build" commands. (This is not terribly general -- what if you want to build one extension (or library or executable one way), but others differently? -- but it's good enough. If you need to get fancy, go right ahead: this is Python, the only barrier is your own creativity. No fighting with shell quoting rules or M4 bizarritude. Hooray!) A note on portability: yes, this is all heavily geared towards C and C++. No matter what Sun says (lying all the way to the bank, no doubt), I expect an Autoconf-ish facility will be necessary for grokking Java installations to build JPython extensions -- but that ability is a long ways off, definitely post-Distutils 1.0. Also, I had to add a 'preprocess()' method to the CCompiler interface, which is currently only implemented in UnixCCompiler. Thus, the preprocessor-depending "config" methods ('try_cpp()', 'search_cpp()', 'check_header()') will die horribly on Windows and Mac OS. Please take a look at the 'preprocess()' docstring and let me know if it can be implemented portably, or if the interface will have to change. Oh, Unix wizards: currently I just do "cc -E filename.c -o filename.i" to run the preprocessor. Works with GCC, and ISTR that SGI's compiler supports "-E" too. Anyone know how widely spread this convention is? Should I implement some heuristics to figure out whether to use "cc -E" or "/lib/cpp"? What other options are there? I'm gonna check this in now. No time to make a snapshot tonight -- please get the latest CVS code and give this a whirl. The only test case is mxDateTime (examples/mxdatetime_setup.py), and only 'check_func()' (and therefore 'try_link()') have been tested. Next up is to add autoconfiguration to PIL's setup script. Whee! this is fun... I guess I've written my code for the week, now back to wading through all those patches... Greg -- Greg Ward - nerd gward@python.net http://starship.python.net/~gward/ Support bacteria -- it's the only culture some people have! From gward@python.net Wed Jun 21 03:47:29 2000 From: gward@python.net (Greg Ward) Date: Tue, 20 Jun 2000 22:47:29 -0400 Subject: [Distutils] Example of "config" command Message-ID: <20000620224729.A1223@beelzebub> Oh, here's an example of how easy it is to autoconfigure Python extensions now. This is taken from examples/mxdatetime_setup.py; here're the essentials 'run()' method of the "config_mxDateTime" command class: def run (self): have = {} have['strftime'] = self.check_func('strftime', ['time.h']) have['strptime'] = self.check_func('strptime', ['time.h']) have['timegm'] = self.check_func('timegm', ['time.h']) define = [] undef = [] for name in have.keys(): # ('strftime', 'strptime', 'timegm'): macro_name = 'HAVE_' + string.upper(name) if have[name]: define.append((macro_name, None)) else: undef.append(macro_name) Note that the bulk of the code is the bureaucracy of figuring out which macros to define, ie. generateing HAVE_STRFTIME and friends. Obviously this could (and should) be taken care of by the standard "config" command; we'll get there! Here's the output of "setup.py config" (very noisy because --noisy and --dump-source are both enabled by default for now): running config compiling '_configtest.c': #include int main () { strftime; } gcc -c -g -O2 -fPIC _configtest.c -o _configtest.o gcc _configtest.o -o _configtest success! removing: _configtest.c _configtest.o _configtest compiling '_configtest.c': #include int main () { strptime; } gcc -c -g -O2 -fPIC _configtest.c -o _configtest.o _configtest.c: In function `main': _configtest.c:4: `strptime' undeclared (first use in this function) _configtest.c:4: (Each undeclared identifier is reported only once _configtest.c:4: for each function it appears in.) failure. removing: _configtest.c _configtest.o compiling '_configtest.c': #include int main () { timegm; } gcc -c -g -O2 -fPIC _configtest.c -o _configtest.o gcc _configtest.o -o _configtest success! removing: _configtest.c _configtest.o _configtest macros to define: [('HAVE_STRFTIME', None), ('HAVE_TIMEGM', None)] macros to undefine: ['HAVE_STRPTIME'] Note that ('HAVE_STRFTIME', None) means "-DHAVE_STRFTIME" -- i.e. define the macro without any particular value. No, I don't know why 'strptime()' isn't showing up, but at least it demonstrates a failure case. Greg -- Greg Ward - geek-on-the-loose gward@python.net http://starship.python.net/~gward/ Save energy: be apathetic. From gward@python.net Wed Jun 21 04:36:21 2000 From: gward@python.net (Greg Ward) Date: Tue, 20 Jun 2000 23:36:21 -0400 Subject: [Distutils] install_headers,install_data In-Reply-To: <393FD245.FEC46D55@gmx.de>; from R.Liebscher@gmx.de on Thu, Jun 08, 2000 at 07:05:09PM +0200 References: <393FD245.FEC46D55@gmx.de> Message-ID: <20000620233621.A1462@beelzebub> On 08 June 2000, Rene Liebscher said: > when I tried to build a binary distribution > I found that there were no headers in it. > (But a normal install worked.) > Also I found bdist_rpm didn't work with > headers and data files. > > There were two problems: > Someone simply forgot the headers in the > install command. > > From install_headers and install_data > you couldn't get the copied files (outfiles.) > (rpm seems to use it.) Good catch. Thanks! > And here is now a patch which solves both > problems. OK, I've checked in fixes that were "inspired" by your patch. Note that 'copy_file()' returns the name of the output file, so there's no need to override it and generate the filename ourselves; just get the value returned from 'copy_file()' and append to 'outfiles' > Shouldn't header files be installed in > /usr/local/python1.5/include > instead of > /usr/local/python/1.5/include ? Already fixed, thanks. > Another problem is that MANIFEST > is build from two sources. > > MANIFEST.in > > MANIFEST > parameters of setup() > > If someone changes the parameter of setup() > the MANIFEST file should be rebuild. Duh, good point! So-obvious-I-should-have-thought-of-it-myself. Again I checked in a fix strongly inspired by yours. Another note: 'newer()' doesn't mind if the *target* doesn't exist; it just returns true, meaning that the target needs to be regenerated. So the 'isfile()' check on 'manifest' is unneeded. > PS: I send the last version of my cygwin-compiler > class with this mail. OK, I just checked it in, unreviewed and untested. (What the hell.) Now at least others can try it and it'll get in the next code snapshot, whenever I do that. Greg -- Greg Ward - Unix nerd gward@python.net http://starship.python.net/~gward/ Laziness, Impatience, Hubris. From gward@python.net Wed Jun 21 04:39:12 2000 From: gward@python.net (Greg Ward) Date: Tue, 20 Jun 2000 23:39:12 -0400 Subject: [Distutils] install_headers,install_data In-Reply-To: ; from moshez@math.huji.ac.il on Thu, Jun 08, 2000 at 08:49:40PM +0300 References: <393FD245.FEC46D55@gmx.de> Message-ID: <20000620233912.B1462@beelzebub> On 08 June 2000, Moshe Zadka said: > Great work, but one small nit: you use try/except in two places there. > The first just catch ValueError's, and the second can catch > (IOError, os.error), though I'm not sure what for: if there are problems > reading config.h, it seems we're in a pretty mess: pretending everything > is alright won't make it so As of a few days ago, the "correct" way to deal with IOError and os.error is to call 'grok_environment_error()'. Eg. from core.py (well, this is how it *should* look...): try: dist.run_commands () except KeyboardInterrupt: raise SystemExit, "interrupted" except EnvironmentError, exc: error = grok_environment_error(exc) if DEBUG: sys.stderr.write(error + "\n") raise else: raise SystemExit, error 'grok_environment_error()' makes the best of a bad situation, ie. the number of inconsistent ways that an IOError or os.error object can exist (sigh). Greg -- Greg Ward - Unix geek gward@python.net http://starship.python.net/~gward/ I once decorated my apartment entirely in ten foot salad forks!! From gward@python.net Wed Jun 21 04:43:12 2000 From: gward@python.net (Greg Ward) Date: Tue, 20 Jun 2000 23:43:12 -0400 Subject: [Distutils] Source and patch: swig support (and more) In-Reply-To: <036101bfd7bf$71d40930$4500a8c0@thomasnb>; from thomas.heller@ion-tof.com on Fri, Jun 16, 2000 at 08:19:43PM +0200 References: <036101bfd7bf$71d40930$4500a8c0@thomasnb> Message-ID: <20000620234312.C1462@beelzebub> On 16 June 2000, Thomas Heller said: > The included source code and patch implements > a swig class (derived from ccompiler). Disclaimer: I haven't looked at SWIG or read its docs in something like 3 years, I have only scanned your patch, and I have barely thought about the right way to implement SWIG support. That said, this seems like a strange way to do it. I had been vaguely thinking of adding a pre-compilation step to the build_ext command; the idea of a new CCompiler class for something that really isn't a C compiler at all hadn't occurred to me, probably because it's just plain weird. Any particular reason you did it this way? > Simply include 'xxx.i' files into your extension source-files, > and swig will be used to generate 'xxx.cpp' files, which will > then be compiled and linked. That can probably be handled by a little conspiracy between the Extension class and the build_ext command; again, I fail to see the benefit of a CCompiler class for this. > Other stuff included (only useful for the windows crowd) > Resource scripts (*.rc) and message compiler files (*.mc) > can also be used as extension source files, and MSVC > will invoke rc.exe and mc.exe to create .res files > and pass them to the linker. Sounds uncontroversial. Can you submit that as a separate patch? Thanks! Greg -- Greg Ward - programmer-at-big gward@python.net http://starship.python.net/~gward/ I brought my BOWLING BALL -- and some DRUGS!! From gward@python.net Wed Jun 21 04:48:58 2000 From: gward@python.net (Greg Ward) Date: Tue, 20 Jun 2000 23:48:58 -0400 Subject: [Distutils] Prerelease: bdist_wininst In-Reply-To: <00a101bfda2a$dc4bcce0$4500a8c0@thomasnb>; from thomas.heller@ion-tof.com on Mon, Jun 19, 2000 at 10:13:40PM +0200 References: <03c901bfd6c1$bb53d990$4500a8c0@thomasnb> <394901C2.4C94318E@gmx.de> <008601bfd6f9$507ea0e0$4500a8c0@thomasnb> <20000616222927.B497@beelzebub> <00a101bfda2a$dc4bcce0$4500a8c0@thomasnb> Message-ID: <20000620234858.D1462@beelzebub> On 19 June 2000, Thomas Heller said: > > > I found the compressed base64 encoded bytes of the exe-file > > > nice in bdist_wininst, but there will also be another solution. > > > > I find it really weird, but if it works... > It's not really my own idea, /F uses something similar in his squeeze > utility, and also in PythonWorks. > > The advantage is that there only is a single file. Yeah, but if you can just as easily find that other file through os.path.dirname(sys.modules['distutils']), then I don't see a big win. There are already 20 or 30 source files in the Distutils, what's one more? (OK, OK, even if it is a binary.) The only problem I can see is putting a binary file in CVS and distributing it in the source distribution, but I think I know the right way to do that. ("cvs admin -kk wininst_stub.exe" should do the trick.) > I would certainly prefer to include the whole source into distutils, > but first: currently distutils cannot build exe-files (not even > on windows), secondly how would the exe been build under unix? > Third, can distutils _install_ exe-files? Are you sure? The code (implementation of 'link_executable()') is definitely there in UnixCCompiler and MSVCCompiler. I don't recall having tested it thoroughly, but it certainly exists... > Well, it is certainly not nearly finished, but I would like to get some > more feedback from users before working on it. > So yes, please go on, check it in. Arg, it's getting late... tomorrow! Can you just resend it to include Rene's fix (and any other recent changes) please? Thanks... Greg -- Greg Ward - Unix bigot gward@python.net http://starship.python.net/~gward/ Know thyself. If you need help, call the CIA. From DavidA@ActiveState.com Wed Jun 21 05:23:14 2000 From: DavidA@ActiveState.com (David Ascher) Date: Tue, 20 Jun 2000 21:23:14 -0700 Subject: [Distutils] RE: [Python-Dev] Installation requirements In-Reply-To: <200006210146.VAA01220@207-172-37-166.s166.tnt7.ann.va.dialup.rcn.com> Message-ID: > [Follow-up to the Distutils SIG, please.] > > There are a few steps needed to find and install a package: > 1) Discovery : which module does what I need? > 2) Download : where can I get a copy? > 3) Security : is this actually from the package author, and not a Trojan? > 4) Installation : how do I set it up? > 5) Checking for new versions: I have 1.0 installed; is a newer version > available? > Some potential sources of inspiration: > > Debian: apt > Perl: CPAM.pm > FreeBSD: ports system > RPMfind (rpmfind.net) > XEmacs: packages system Perl: OSD/PPM Open Software Distribution (OSD) www.w3.org/tr/note-osd.html, www.microsoft.com/workshop/management/osd/osdfaq.asp OSD is an XML vocabulary for describing a software distribution package as a "bill of materials" and defining relationships and dependencies among its parts. OSD-based software distribution implementers include Marimba Inc.'s Castanet, Microsoft's Internet Explorer, Novell Inc.'s ZENworks and ActiveState Tool Corp.'s Win32 Perl. From mal@lemburg.com Wed Jun 21 08:38:02 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Wed, 21 Jun 2000 09:38:02 +0200 Subject: [Distutils] Autoconf in Python References: <20000620220719.A1208@beelzebub> Message-ID: <395070DA.A9A2248F@lemburg.com> Greg Ward wrote: > > Those of you who follow python-checkins closely probably already know > this, but for the rest of you I think this will be news: > > I now have a working demonstration of the long-mythical, frequently > procrastinated, "Autoconf-in-Python"! Marc-Andre, you were right -- it > wasn't too bad. I think I probably spent more time combing the Autoconf > docs for inspiration, and figuring out how to sensibly translate > Autoconf's byzantine shell/M4 interface into sensible OO Python, than I > did actually coding it. Great :-) > [...] > > Also, I had to add a 'preprocess()' method to the CCompiler interface, > which is currently only implemented in UnixCCompiler. Thus, the > preprocessor-depending "config" methods ('try_cpp()', 'search_cpp()', > 'check_header()') will die horribly on Windows and Mac OS. Please take > a look at the 'preprocess()' docstring and let me know if it can be > implemented portably, or if the interface will have to change. > > Oh, Unix wizards: currently I just do "cc -E filename.c -o filename.i" > to run the preprocessor. Works with GCC, and ISTR that SGI's compiler > supports "-E" too. Anyone know how widely spread this convention is? > Should I implement some heuristics to figure out whether to use "cc -E" > or "/lib/cpp"? What other options are there? Uhm, why not simply compile the whole thing instead of just running the preprocessor ? (I think that's how autoconf does it too) This would have the advantage of being portable and wouldn't rely on some commonly used command line flag (note that the C preprocessor is usually also reachable directly, e.g. on Linux its /usr/bin/cpp). -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From mal@lemburg.com Wed Jun 21 08:44:31 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Wed, 21 Jun 2000 09:44:31 +0200 Subject: [Distutils] Example of "config" command References: <20000620224729.A1223@beelzebub> Message-ID: <3950725F.98723A7B@lemburg.com> Greg Ward wrote: > > Oh, here's an example of how easy it is to autoconfigure Python > extensions now. This is taken from examples/mxdatetime_setup.py; > here're the essentials 'run()' method of the "config_mxDateTime" command > class: > > def run (self): > have = {} > have['strftime'] = self.check_func('strftime', ['time.h']) > have['strptime'] = self.check_func('strptime', ['time.h']) > have['timegm'] = self.check_func('timegm', ['time.h']) > > define = [] > undef = [] > for name in have.keys(): # ('strftime', 'strptime', 'timegm'): > macro_name = 'HAVE_' + string.upper(name) > if have[name]: > define.append((macro_name, None)) > else: > undef.append(macro_name) > > Note that the bulk of the code is the bureaucracy of figuring out which > macros to define, ie. generateing HAVE_STRFTIME and friends. Obviously > this could (and should) be taken care of by the standard "config" > command; we'll get there! > > Here's the output of "setup.py config" (very noisy because --noisy and > --dump-source are both enabled by default for now): > > running config > compiling '_configtest.c': > #include > > int main () { > strftime; > } > gcc -c -g -O2 -fPIC _configtest.c -o _configtest.o > gcc _configtest.o -o _configtest > success! > removing: _configtest.c _configtest.o _configtest > compiling '_configtest.c': > #include > > int main () { > strptime; > } > gcc -c -g -O2 -fPIC _configtest.c -o _configtest.o > _configtest.c: In function `main': > _configtest.c:4: `strptime' undeclared (first use in this function) > _configtest.c:4: (Each undeclared identifier is reported only once > _configtest.c:4: for each function it appears in.) > failure. > removing: _configtest.c _configtest.o > compiling '_configtest.c': > #include > > int main () { > timegm; > } > gcc -c -g -O2 -fPIC _configtest.c -o _configtest.o > gcc _configtest.o -o _configtest > success! > removing: _configtest.c _configtest.o _configtest > macros to define: [('HAVE_STRFTIME', None), ('HAVE_TIMEGM', None)] > macros to undefine: ['HAVE_STRPTIME'] > > Note that ('HAVE_STRFTIME', None) means "-DHAVE_STRFTIME" -- i.e. define > the macro without any particular value. No, I don't know why > 'strptime()' isn't showing up, but at least it demonstrates a failure > case. Because it will only show up if the _XOPEN_SOURCE symbol is defined before including time.h -- weird, I know, but that's gcc... it may be worthwhile to provide such defines to the config functions in some way (or to make them default for gcc in the compiler class, e.g. always define _GNU_SOURCE which enables all of GNU CC's features). -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From thomas.heller@ion-tof.com Wed Jun 21 08:58:32 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Wed, 21 Jun 2000 09:58:32 +0200 Subject: [Distutils] Autoconf in Python References: <20000620220719.A1208@beelzebub> Message-ID: <00e501bfdb56$80380a90$4500a8c0@thomasnb> > Oh, Unix wizards: currently I just do "cc -E filename.c -o filename.i" > to run the preprocessor. Works with GCC, and ISTR that SGI's compiler > supports "-E" too. Anyone know how widely spread this convention is? > Should I implement some heuristics to figure out whether to use "cc -E" > or "/lib/cpp"? What other options are there? MSVC supports the -E flag which writes the prerpocessed file to standard output, and the -P flag to create an xxx.i file. No separate preprocessor executable is available to the user. Borland 5.5 seems to have a separate cpp as cpp32.exe. Thomas From calvin@cs.uni-sb.de Thu Jun 22 01:23:54 2000 From: calvin@cs.uni-sb.de (Bastian Kleineidam) Date: Thu, 22 Jun 2000 02:23:54 +0200 (CEST) Subject: [Distutils] copy_file semantics changed? In-Reply-To: <3950725F.98723A7B@lemburg.com> Message-ID: Hi, I noticed the following Traceback with bdist_rpm command: Traceback (innermost last): File "setup.py", line 120, in ? data_files = [('share/locale/de/LC_MESSAGES', File "/usr/lib/python1.5/site-packages/distutils/core.py", line 112, in setup dist.run_commands () File "setup.py", line 47, in run_commands self.run_command (cmd) File "/usr/lib/python1.5/site-packages/distutils/dist.py", line 788, in run_command cmd_obj.run () File "/usr/lib/python1.5/site-packages/distutils/command/install.py", line 474, in run outputs[counter] = outputs[counter][root_len:] TypeError: unsliceable object Bad exit status from /var/tmp/rpm-tmp.56627 (%install) error: command 'rpm' failed with exit status 1 Reason is that file_util.py:copy_file does not return the copyied file name any more (it used to I think) but instead a boolean value for successful copying. This is not good because it breaks the get_outputs() functions of install commands (see the above traceback). For example get_outputs() of install_data looks like [0, 0, 0]. I suggest that you change back to the old behaviour: if copy_file fails, throw an exception else return target file name (even if you copied nothing because the target file was newer) Bastian Kleineidam From calvin@cs.uni-sb.de Thu Jun 22 01:30:58 2000 From: calvin@cs.uni-sb.de (Bastian Kleineidam) Date: Thu, 22 Jun 2000 02:30:58 +0200 (CEST) Subject: [Distutils] copy_file patch In-Reply-To: <3950725F.98723A7B@lemburg.com> Message-ID: Hello, apply this patch to make copy_file return the target file instead of 0/1: diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/file_util.py distutils/distutils/file_util.py --- distutils.orig/distutils/file_util.py Sat May 20 18:05:34 2000 +++ distutils/distutils/file_util.py Thu Jun 22 02:27:45 2000 @@ -123,7 +123,7 @@ if update and not newer (src, dst): if verbose: print "not copying %s (output up-to-date)" % src - return 0 + return dst try: action = _copy_action[link] @@ -137,7 +137,7 @@ print "%s %s -> %s" % (action, src, dst) if dry_run: - return 1 + return dst # On a Mac, use the native file copy routine if os.name == 'mac': @@ -171,7 +171,7 @@ if preserve_mode: os.chmod (dst, S_IMODE (st[ST_MODE])) - return 1 + return dst # copy_file () From gward@python.net Thu Jun 22 02:28:23 2000 From: gward@python.net (Greg Ward) Date: Wed, 21 Jun 2000 21:28:23 -0400 Subject: [Distutils] Autoconf in Python In-Reply-To: <395070DA.A9A2248F@lemburg.com>; from mal@lemburg.com on Wed, Jun 21, 2000 at 09:38:02AM +0200 References: <20000620220719.A1208@beelzebub> <395070DA.A9A2248F@lemburg.com> Message-ID: <20000621212823.A584@beelzebub> On 21 June 2000, M.-A. Lemburg said: > Uhm, why not simply compile the whole thing instead of > just running the preprocessor ? (I think that's how autoconf > does it too) Because sometimes all you want to know is "is __linux__ defined?" or "does including get strftime's declaration?". Granted, both of these can be answered by just compiling a test program. Hmm... there must be *some* reason, after I spent all of 15 minutes implementing the preprocessor interface in UnixCCompiler... Any history-of-autoconf wizards out there who can answer this one? I wouldn't be surprised if it boils down to, "running GCC 1.x on a 16 MHz i386 under SunOS 3.x is really slow, so let's just run the preprocessor". > This would have the advantage of being portable and wouldn't > rely on some commonly used command line flag (note that the > C preprocessor is usually also reachable directly, e.g. on > Linux its /usr/bin/cpp). True 'nuff. Well, hey, nobody will force module developers to use 'check_header()' -- if it turns out to be indispensable, we'll figure out how to do it portably; if not, it can wither and die. Greg -- Greg Ward - geek-at-large gward@python.net http://starship.python.net/~gward/ I love ROCK 'N ROLL! I memorized the all WORDS to "WIPE-OUT" in 1965!! From gward@python.net Thu Jun 22 02:39:08 2000 From: gward@python.net (Greg Ward) Date: Wed, 21 Jun 2000 21:39:08 -0400 Subject: [Distutils] Duelling SWIG patches Message-ID: <20000621213908.A792@beelzebub> Well, I was inspired by Thomas' patch for SWIG support to come up with my own patch. Here it is: completely untested, so I haven't checked it in yet. (I don't have SWIG installed at home, so I figured I'd let someone Out There who actually uses it test this for me. Remember: laziness is a virtue!) Note that Thomas' patch was Windows/C++-centric; mine tries to be OS-agnostic, but is C-centric. Is it possible to tell from a SWIG .i file whether it is destined to be C or C++? I can't think of a good way to do it, but then my knowledge if SWIG is roughly epsilon. (Out of curiosity, I took the manual home and read it about three years ago. It struck me as being *way* to easy, and I wanted to write Perl extensions like a *real* man. Ahh, the folly of youth...) Here's da patch: =================================================================== RCS file: /cvsroot/python/distutils/distutils/command/build_ext.py,v retrieving revision 1.43 diff -u -r1.43 build_ext.py --- build_ext.py 2000/06/17 23:04:31 1.43 +++ build_ext.py 2000/06/22 01:30:49 @@ -367,12 +367,13 @@ else: self.announce ("building '%s' extension" % ext.name) - # First step: compile the source code to object files. This - # drops the object files in the current directory, regardless - # of where the source is (may be a bad thing, but that's how a - # Makefile.pre.in-based system does it, so at least there's a - # precedent!) + # First, scan the sources for SWIG definition files (.i), run + # SWIG on 'em to create .c files, and modify the sources list + # accordingly. + sources = self.swig_sources(sources) + # Next, compile the source code to object files. + # XXX not honouring 'define_macros' or 'undef_macros' -- the # CCompiler API needs to change to accomodate this, and I # want to do one thing at a time! @@ -428,6 +429,74 @@ # build_extensions () + + def swig_sources (self, sources): + + """Walk the list of source files in 'sources', looking for SWIG + interface (.i) files. Run SWIG on all that are found, and + return a modified 'sources' list with SWIG source files replaced + by the generated C (or C++) files. + """ + + new_sources = [] + swig_sources = [] + swig_targets = {} + + # XXX this drops generated C files into the source tree, which + # is fine for developers who want to distribute the generated + # source -- but there should be an option to put SWIG output in + # the temp dir. + + for source in sources: + (base, ext) = os.path.splitext(source) + if ext in self.swig_ext(): + new_sources.append(base + ".c") # umm, what if it's C++? + swig_files.append(source) + swig_targets[source] = new_sources[-1] + else: + new_sources.append(source) + + if not swig_files: + return new_sources + + swig = self.find_swig() + swig_cmd = [swig, "-python", "-dnone", "-ISWIG"] # again, C++?!? + + for source in swig_sources: + self.announce ("swigging %s to %s" % (src, obj)) + self.spawn(swig_cmd + ["-o", swig_targets[source], source]) + + return new_sources + + # swig_sources () + + def find_swig (self): + """Return the name of the SWIG executable. On Unix, this is + just "swig" -- it should be in the PATH. Tries a bit harder on + Windows. + """ + + if os.name == "posix": + return "swig" + elif os.name == "nt": + + # Look for SWIG in its standard installation directory on + # Windows (or so I presume!). If we find it there, great; + # if not, act like Unix and assume it's in the PATH. + for vers in ("1.3", "1.2", "1.1"): + fn = os.path.join("c:\\swig%s" % vers, "swig.exe") + if os.path.isfile (fn): + return fn + else: + return "swig.exe" + + else: + raise DistutilsPlatformError, \ + ("I don't know how to find (much less run) SWIG " + "on platform '%s'") % os.name + + # find_swig () + # -- Hooks --------------------------------------------------------- ======================================================================== Greg -- Greg Ward - Unix geek gward@python.net http://starship.python.net/~gward/ All right, you degenerates! I want this place evacuated in 20 seconds! From hgebel@inet.net Thu Jun 22 17:46:25 2000 From: hgebel@inet.net (Harry Henry Gebel) Date: Thu, 22 Jun 2000 12:46:25 -0400 Subject: [Distutils] Duelling SWIG patches In-Reply-To: <20000621213908.A792@beelzebub>; from gward@python.net on Wed, Jun 21, 2000 at 09:39:08PM -0400 References: <20000621213908.A792@beelzebub> Message-ID: <20000622124624.A27087@inet.net> On Wed, Jun 21, 2000 at 09:39:08PM -0400, Greg Ward wrote: > Note that Thomas' patch was Windows/C++-centric; mine tries to be > OS-agnostic, but is C-centric. Is it possible to tell from a SWIG .i > file whether it is destined to be C or C++? I can't think of a good way > to do it, but then my knowledge if SWIG is roughly epsilon. (Out of > curiosity, I took the manual home and read it about three years ago. It > struck me as being *way* to easy, and I wanted to write Perl extensions > like a *real* man. Ahh, the folly of youth...) The only way I can think of is to analyze the file in some way, SWIG does handle C and C++ differently, but this is specified on the command line not in the interface file. I don't know C++ so I do not know what to look for in a file that would definitively identify it as C++. Can `file` recognize the difference? If it can then maybe the 'magic' file could be examined to duplicate whatever `file` does (since `file` is not available on all systems I guess Distutils would have to duplicate it.) -- Harry Henry Gebel, Senior Developer, Landon House SBS ICQ# 76308382 West Dover Hundred, Delaware From mmuller@enduden.com Fri Jun 23 01:26:07 2000 From: mmuller@enduden.com (Michael Muller) Date: Thu, 22 Jun 2000 20:26:07 -0400 Subject: [Distutils] Duelling SWIG patches Message-ID: <200006230032.UAA15434@bogus.com> Greg Ward wrote: [snip] > OS-agnostic, but is C-centric. Is it possible to tell from a SWIG .i > file whether it is destined to be C or C++? I can't think of a good way [snip] I'm pretty sure that the only way to do this short of parsing the file is to run "swig" with no options and then (if it fails) run "swig -c++" (enabling the C++ processing features). This seems more like something you'd want to do during configuration then during the build. Maybe it would be best to adopt a convention for SWIG files in distutils (uppercase ".I" in C++, maybe?) or find some other way to allow the user to explicitly indicate a C++ file. ============================================================================= michaelMuller = mmuller@enduden.com | http://www.cloud9.net/~proteus ----------------------------------------------------------------------------- We are explorers in the further reaches of experience: demons to some, angels to others. - "Pinhead" from "Hellraiser" ============================================================================= From gward@python.net Fri Jun 23 02:32:59 2000 From: gward@python.net (Greg Ward) Date: Thu, 22 Jun 2000 21:32:59 -0400 Subject: [Distutils] copy_file semantics changed? In-Reply-To: ; from calvin@cs.uni-sb.de on Thu, Jun 22, 2000 at 02:23:54AM +0200 References: <3950725F.98723A7B@lemburg.com> Message-ID: <20000622213259.A933@beelzebub> On 22 June 2000, Bastian Kleineidam said: > I noticed the following Traceback with bdist_rpm command: > Traceback (innermost last): [...] > File "/usr/lib/python1.5/site-packages/distutils/command/install.py", > line 474, in run > outputs[counter] = outputs[counter][root_len:] > TypeError: unsliceable object > Bad exit status from /var/tmp/rpm-tmp.56627 (%install) > error: command 'rpm' failed with exit status 1 > > Reason is that file_util.py:copy_file does not return the copyied file > name any more (it used to I think) but instead a boolean value for > successful copying. ~#@!$^~@#@#%!#^$#! My mistake: I got confused over copy_file's interface, obviously. > I suggest that you change back to the old behaviour: > if copy_file fails, throw an exception > else return target file name (even if you copied nothing because the > target file was newer) That assumes that I changed the interface to return boolean arbitrarily. I did not: I believe there is code that depends on it returning boolean. And now there is also code that depends on it returning the output filename. Damn! Time to grep the source for copy_file and see how it's *really* used... (and also time to write those regression tests!) Greg -- Greg Ward - nerd gward@python.net http://starship.python.net/~gward/ A man wrapped up in himself makes a very small package. From gward@python.net Fri Jun 23 02:43:41 2000 From: gward@python.net (Greg Ward) Date: Thu, 22 Jun 2000 21:43:41 -0400 Subject: [Distutils] copy_file semantics changed? In-Reply-To: <20000622213259.A933@beelzebub>; from greg on Thu, Jun 22, 2000 at 09:32:59PM -0400 References: <3950725F.98723A7B@lemburg.com> <20000622213259.A933@beelzebub> Message-ID: <20000622214341.B933@beelzebub> On 22 June 2000, I spoke too soon: > That assumes that I changed the interface to return boolean arbitrarily. > I did not: I believe there is code that depends on it returning > boolean. And now there is also code that depends on it returning the > output filename. Damn! Time to grep the source for copy_file and see > how it's *really* used... Well, from poking through the CVS logs, it appears that 'copy_file()' has *always* returned boolean. And from scanning the source, it appears that no code actually expects it to return boolean -- the only bits that pays attention to the return value are my recent additions that use 'copy_file()'s supposed string return value to build list of files copied. So, Bastian's patch is exactly the right thing. (Except you forgot to fix the docstring! Don't worry, I did it.) Applied, checked in, and now maybe things will work again. Greg -- Greg Ward - geek-at-large gward@python.net http://starship.python.net/~gward/ The NSA. We care: we listen to our customers. From thomas.heller@ion-tof.com Fri Jun 23 09:18:38 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Fri, 23 Jun 2000 10:18:38 +0200 Subject: Fw: [Distutils] Duelling SWIG patches Message-ID: <047001bfdceb$a25e2f50$4500a8c0@thomasnb> Thomas Heller ION-TOF GmbH ----- Original Message ----- From: "Thomas Heller" To: Sent: Friday, June 23, 2000 9:08 AM Subject: Re: [Distutils] Duelling SWIG patches > > > > Greg Ward wrote: > > [snip] > > > OS-agnostic, but is C-centric. Is it possible to tell from a SWIG .i > > > file whether it is destined to be C or C++? I can't think of a good way > > [snip] > > and Michael wrote: > > > > I'm pretty sure that the only way to do this short of parsing the file is > to > > run "swig" with no options and then (if it fails) run "swig -c++" > (enabling > > the C++ processing features). This seems more like something you'd want > to > > do during configuration then during the build. > Unfortunately swig does not fail in C-mode on an I-file > which is destined for C++: The C-compiler will fail with syntax > errors. > > Thomas > > > From thomas.heller@ion-tof.com Fri Jun 23 09:42:56 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Fri, 23 Jun 2000 10:42:56 +0200 Subject: [Distutils] Duelling SWIG patches References: <20000621213908.A792@beelzebub> Message-ID: <048001bfdcef$0735e410$4500a8c0@thomasnb> > Well, I was inspired by Thomas' patch for SWIG support to come up with > my own patch. Here it is: completely untested, so I haven't checked it > in yet. (I don't have SWIG installed at home, so I figured I'd let > someone Out There who actually uses it test this for me. Remember: > laziness is a virtue!) > > Note that Thomas' patch was Windows/C++-centric; mine tries to be > OS-agnostic, but is C-centric. Is it possible to tell from a SWIG .i > file whether it is destined to be C or C++? I can't think of a good way > to do it, but then my knowledge if SWIG is roughly epsilon. (Out of > curiosity, I took the manual home and read it about three years ago. It > struck me as being *way* to easy, and I wanted to write Perl extensions > like a *real* man. Ahh, the folly of youth...) > I don't like this patch. While I won't argue whether ccompiler is an appropriate superclass for swig, swig shares some important properties: Swig has command line flags to specify include directories -I, libraries -l, define symbols -Dsymbol like C-compilers. Other options which are maybe usefull for python extensions are -t , -shadow (create shadow classes), -module name (set module name) and maybe more. From this I have the impression that swig should be a separate class implemented in swig.py, and there should be distutils command line flags for setting the above options (and also the -c++ option). Although I did not implement them so far. (Sidenote: I also needed a swig-object in build_ext for my setup-script for win32all. I had to extend distutils in the setup-script because there are also exe-files to be built from C++ and swig sources). As I pointed out in a separate post, there should also be an option to specify C or C++ processing. If I find time, I will submit a new patch. Thomas From thomas.heller@ion-tof.com Fri Jun 23 09:57:29 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Fri, 23 Jun 2000 10:57:29 +0200 Subject: [Distutils] ccompiler problem Message-ID: <048a01bfdcf1$0fdacd90$4500a8c0@thomasnb> Consider the object_filenames method: def object_filenames (self, source_filenames, strip_dir=0, output_dir=''): if output_dir is None: output_dir = '' obj_names = [] for src_name in source_filenames: (base, ext) = os.path.splitext (src_name) if ext not in self.src_extensions: continue ^^^^^^^^^ Problem is here if strip_dir: base = os.path.basename (base) obj_names.append (os.path.join (output_dir, base + self.obj_extension)) return obj_names # object_filenames () If you specify a source-file with an unknown extension in the sources list, you later get a traceback later saying something like 'sources and targets must have the same length'. IMO we have two possibilities here: - assume that 'ext' is something which should be passed to the linker - raise an error like 'Don't know how to compile this file' Thomas Heller ION-TOF GmbH From thomas.heller@ion-tof.com Fri Jun 23 09:58:39 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Fri, 23 Jun 2000 10:58:39 +0200 Subject: [Distutils] RC and MC patch for msvccompiler Message-ID: <049701bfdcf1$39a7f1c0$4500a8c0@thomasnb> This is a multi-part message in MIME format. ------=_NextPart_000_0494_01BFDD01.FD091580 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit This is the patch for msvccompiler factored out of my previous swig patch, which allows compiling resource scripts (.rc) to .res files, and messages (.mc) to .res files. The resulting .res files are passed to the linker. Additionally .cxx is now recognized as C++ source extension. Thomas ------=_NextPart_000_0494_01BFDD01.FD091580 Content-Type: text/plain; name="msvccompiler.diff.txt" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="msvccompiler.diff.txt" Index: msvccompiler.py =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/python/distutils/distutils/msvccompiler.py,v retrieving revision 1.30 diff -c -r1.30 msvccompiler.py *** msvccompiler.py 2000/05/30 02:02:49 1.30 --- msvccompiler.py 2000/06/23 08:46:53 *************** *** 169,179 **** =20 # Private class data (need to distinguish C from C++ source for = compiler) _c_extensions =3D ['.c'] ! _cpp_extensions =3D ['.cc','.cpp'] =20 # Needed for the filename generation methods provided by the # base class, CCompiler. ! src_extensions =3D _c_extensions + _cpp_extensions obj_extension =3D '.obj' static_lib_extension =3D '.lib' shared_lib_extension =3D '.dll' --- 169,182 ---- =20 # Private class data (need to distinguish C from C++ source for = compiler) _c_extensions =3D ['.c'] ! _cpp_extensions =3D ['.cc','.cpp', '.cxx'] ! _rc_extensions =3D ['.rc'] ! _mc_extensions =3D ['.mc'] =20 # Needed for the filename generation methods provided by the # base class, CCompiler. ! src_extensions =3D _c_extensions + _cpp_extensions + = _rc_extensions + _mc_extensions ! res_extension =3D '.res' obj_extension =3D '.obj' static_lib_extension =3D '.lib' shared_lib_extension =3D '.dll' *************** *** 195,200 **** --- 198,205 ---- self.cc =3D find_exe("cl.exe", version) self.link =3D find_exe("link.exe", version) self.lib =3D find_exe("lib.exe", version) + self.rc =3D find_exe("rc.exe", version) # resource = compiler + self.mc =3D find_exe("mc.exe", version) # message = compiler set_path_env_var ('lib', version) set_path_env_var ('include', version) path=3Dget_msvc_paths('path', version) *************** *** 209,214 **** --- 214,221 ---- self.cc =3D "cl.exe" self.link =3D "link.exe" self.lib =3D "lib.exe" + self.rc =3D "rc.exe" + self.mc =3D "mc.exe" =20 self.preprocess_options =3D None self.compile_options =3D [ '/nologo', '/Ox', '/MD', '/W3' ] *************** *** 223,228 **** --- 230,266 ---- =20 # -- Worker methods = ------------------------------------------------ =20 + def object_filenames (self, + source_filenames, + strip_dir=3D0, + output_dir=3D''): + # Copied from ccompiler.py, extended to return .res as = 'object'-file + # for .rc input file + if output_dir is None: output_dir =3D '' + obj_names =3D [] + for src_name in source_filenames: + (base, ext) =3D os.path.splitext (src_name) + if ext not in self.src_extensions: + # Better to raise an exception instead of silently = continuing + # and later complain about sources and targets having + # different lengths + raise CompileError ("Don't know how to compile %s" % = src_name) + if strip_dir: + base =3D os.path.basename (base) + if ext in self._rc_extensions: + obj_names.append (os.path.join (output_dir, + base + = self.res_extension)) + elif ext in self._mc_extensions: + obj_names.append (os.path.join (output_dir, + base + = self.res_extension)) + else: + obj_names.append (os.path.join (output_dir, + base + = self.obj_extension)) + return obj_names +=20 + # object_filenames () +=20 +=20 def compile (self, sources, output_dir=3DNone, *************** *** 254,267 **** if skip_sources[src]: self.announce ("skipping %s (%s up-to-date)" % (src, = obj)) else: if ext in self._c_extensions: input_opt =3D "/Tc" + src elif ext in self._cpp_extensions: input_opt =3D "/Tp" + src =20 output_opt =3D "/Fo" + obj -=20 - self.mkpath (os.path.dirname (obj)) try: self.spawn ([self.cc] + compile_opts + pp_opts + [input_opt, output_opt] + --- 292,345 ---- if skip_sources[src]: self.announce ("skipping %s (%s up-to-date)" % (src, = obj)) else: + self.mkpath (os.path.dirname (obj)) +=20 if ext in self._c_extensions: input_opt =3D "/Tc" + src elif ext in self._cpp_extensions: input_opt =3D "/Tp" + src + elif ext in self._rc_extensions: + # compile .RC to .RES file + input_opt =3D src + output_opt =3D "/fo" + obj + try: + self.spawn ([self.rc] + + [output_opt] + [input_opt]) + except DistutilsExecError, msg: + raise CompileError, msg + continue + elif ext in self._mc_extensions: + # compile .MC to .RC file to .RES file + # '-h dir' specifies the directory for the = generated include file + # '-r dir' specifies the target directory of the = generated RC file + # and the binary message resource it includes. +=20 + # For now (since there are no options to change = this), + # we use the source-directory for the include file + # and the build directory for the RC file + # and message resources. This works at least for = win32all. + h_dir =3D os.path.dirname (src) + rc_dir =3D os.path.dirname (obj) + try: + # first compile .MC to .RC and .H file + self.spawn ([self.mc] + + ['-h', h_dir, '-r', rc_dir] + = [src]) + base, _ =3D os.path.splitext (os.path.basename = (src)) + rc_file =3D os.path.join (rc_dir, base + = '.rc') + # then compile .RC to .RES file + self.spawn ([self.rc] + + ["/fo" + obj] + [rc_file]) +=20 + except DistutilsExecError, msg: + raise CompileError, msg + continue + else: + # how to handle this file? + raise CompileError ( + "Don't know how to compile %s to %s" % \ + (src, obj)) =20 output_opt =3D "/Fo" + obj try: self.spawn ([self.cc] + compile_opts + pp_opts + [input_opt, output_opt] + *************** *** 374,382 **** if extra_postargs: ld_args.extend (extra_postargs) =20 - print "link_shared_object():" - print " output_filename =3D", output_filename - print " mkpath'ing:", os.path.dirname (output_filename) self.mkpath (os.path.dirname (output_filename)) try: self.spawn ([self.link] + ld_args) --- 452,457 ---- ------=_NextPart_000_0494_01BFDD01.FD091580-- From R.Liebscher@gmx.de Fri Jun 23 17:48:13 2000 From: R.Liebscher@gmx.de (Rene Liebscher) Date: Fri, 23 Jun 2000 18:48:13 +0200 Subject: [Distutils] building extensions with AIX Message-ID: <395394CD.9401FB61@gmx.de> This is a multi-part message in MIME format. --------------41DD571985AC7F26155FDA3E Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, I have seen in the TODO file that there was an entry about AIX. I tried it and found some little problems. It seems some paths in the Makefile are wrong. After playing a little bit around with it, I wrote a new compiler class. (I think, these changes could be included in unixccompiler, but to test it, it is nice to have a own file for it.) Maybe we should also change the default compiler table. I think we should have entries for sys.platform in it, too. So we could try a more specific name first ('aix4') and if there is no entry the usual os.name ('posix'.) The AIXCCompiler class is attached, maybe someone wants to try it, and find out if this is really all we have to change against the standard unixccompiler. (Don't forget to make an entry for it in ccompiler.py.) kind regards Rene Liebscher PS: I used AIX 4.3 and its 'cc' compiler. --------------41DD571985AC7F26155FDA3E Content-Type: text/plain; charset=us-ascii; name="aixccompiler.py" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="aixccompiler.py" """distutils.aixccompiler Contains the AIXCCompiler class, a subclass of UnixCCompiler that handles some path problems with AIX. The makefile isn't correct for distutils' standard compiler. """ # created 2000/06/23, Rene Liebscher __revision__ = "$Id: aixccompiler.py $" from distutils import sysconfig from distutils.unixccompiler import UnixCCompiler # XXX Things not currently handled: # * see UnixCCompiler class AIXCCompiler (UnixCCompiler): compiler_type = 'aix' def __init__ (self, verbose=0, dry_run=0, force=0): UnixCCompiler.__init__ (self, verbose, dry_run, force) # we have to correct some paths self.ld_shared=sysconfig.get_python_lib(standard_lib=1)+'/config/ld_so_aix' self.ldflags_shared.append('-bI:'+sysconfig.get_python_lib(standard_lib=1)+'/config/python.exp') # __init__ () # class AIXCCompiler --------------41DD571985AC7F26155FDA3E-- From sanner@scripps.edu Fri Jun 23 19:38:59 2000 From: sanner@scripps.edu (Michel Sanner) Date: Fri, 23 Jun 2000 11:38:59 -0700 Subject: [Distutils] Duelling SWIG patches In-Reply-To: "Thomas Heller" "Re: [Distutils] Duelling SWIG patches" (Jun 23, 10:42am) References: <20000621213908.A792@beelzebub> <048001bfdcef$0735e410$4500a8c0@thomasnb> Message-ID: <1000623113859.ZM348943@noah.scripps.edu> I have been following the SWIG support discussion for a while. I am not sure I see the point in having distutil run SWIG. Why not simply provide the result or running swig as part of the source code that get's compiled. There are a number of versions of SWIG that have different types of arguments, in addition the interface might use user defined typemaps ! It seems to me that this would be very difficult to get to work properly and I cannot see any real benefit. -Michel On Jun 23, 10:42am, Thomas Heller wrote: > Subject: Re: [Distutils] Duelling SWIG patches > > Well, I was inspired by Thomas' patch for SWIG support to come up with > > my own patch. Here it is: completely untested, so I haven't checked it > > in yet. (I don't have SWIG installed at home, so I figured I'd let > > someone Out There who actually uses it test this for me. Remember: > > laziness is a virtue!) > > > > Note that Thomas' patch was Windows/C++-centric; mine tries to be > > OS-agnostic, but is C-centric. Is it possible to tell from a SWIG .i > > file whether it is destined to be C or C++? I can't think of a good way > > to do it, but then my knowledge if SWIG is roughly epsilon. (Out of > > curiosity, I took the manual home and read it about three years ago. It > > struck me as being *way* to easy, and I wanted to write Perl extensions > > like a *real* man. Ahh, the folly of youth...) > > > I don't like this patch. > > While I won't argue whether ccompiler is an appropriate superclass > for swig, swig shares some important properties: > > Swig has command line flags to specify include directories -I, > libraries -l, define symbols -Dsymbol like C-compilers. > Other options which are maybe usefull for python extensions > are -t , -shadow (create shadow classes), > -module name (set module name) and maybe more. > > >From this I have the impression that swig should be a separate class > implemented in swig.py, and there should be distutils command line > flags for setting the above options (and also the -c++ option). > Although I did not implement them so far. > > (Sidenote: I also needed a swig-object in build_ext for my setup-script > for win32all. I had to extend distutils in the setup-script > because there are also exe-files to be built from C++ > and swig sources). > > As I pointed out in a separate post, there should also be an option > to specify C or C++ processing. > > If I find time, I will submit a new patch. > > Thomas > > > _______________________________________________ > Distutils-SIG maillist - Distutils-SIG@python.org > http://www.python.org/mailman/listinfo/distutils-sig >-- End of excerpt from Thomas Heller -- ----------------------------------------------------------------------- >>>>>>>>>> AREA CODE CHANGE <<<<<<<<< we are now 858 !!!!!!! Michel F. Sanner Ph.D. The Scripps Research Institute Assistant Professor Department of Molecular Biology 10550 North Torrey Pines Road Tel. (858) 784-2341 La Jolla, CA 92037 Fax. (858) 784-2860 sanner@scripps.edu http://www.scripps.edu/sanner ----------------------------------------------------------------------- From sanner@scripps.edu Fri Jun 23 19:41:53 2000 From: sanner@scripps.edu (Michel Sanner) Date: Fri, 23 Jun 2000 11:41:53 -0700 Subject: [Distutils] distutil install Message-ID: <1000623114153.ZM349779@noah.scripps.edu> Hello, I got the OpenDX Python wrapper from Randall Hopper and asked him why the .so wrapping the DX library ends up not int he package directory but in $exec_prefix/lib/python/site-packages. His answer was that this is where distutil puts it. I feel that it would nicer to have the .so along with all other files of the package in $exec_prefix/lib/python/site-packages/DX. Is there a way to specify this in setup.py ? -Michel -- ----------------------------------------------------------------------- >>>>>>>>>> AREA CODE CHANGE <<<<<<<<< we are now 858 !!!!!!! Michel F. Sanner Ph.D. The Scripps Research Institute Assistant Professor Department of Molecular Biology 10550 North Torrey Pines Road Tel. (858) 784-2341 La Jolla, CA 92037 Fax. (858) 784-2860 sanner@scripps.edu http://www.scripps.edu/sanner ----------------------------------------------------------------------- From gward@python.net Sat Jun 24 03:03:41 2000 From: gward@python.net (Greg Ward) Date: Fri, 23 Jun 2000 22:03:41 -0400 Subject: [Distutils] Duelling SWIG patches In-Reply-To: <048001bfdcef$0735e410$4500a8c0@thomasnb>; from thomas.heller@ion-tof.com on Fri, Jun 23, 2000 at 10:42:56AM +0200 References: <20000621213908.A792@beelzebub> <048001bfdcef$0735e410$4500a8c0@thomasnb> Message-ID: <20000623220341.A1145@beelzebub> On 23 June 2000, Thomas Heller said: > I don't like this patch. Well, at least you're up-front and honest. ;-) > While I won't argue whether ccompiler is an appropriate superclass > for swig, swig shares some important properties: > > Swig has command line flags to specify include directories -I, > libraries -l, define symbols -Dsymbol like C-compilers. > Other options which are maybe usefull for python extensions > are -t , -shadow (create shadow classes), > -module name (set module name) and maybe more. All true. *BUT* SWIG doesn't vary across platforms, there aren't multiple SWIG implementations to worry about, and therefore there's no need for an "abstract SWIG interface". > From this I have the impression that swig should be a separate class > implemented in swig.py, and there should be distutils command line > flags for setting the above options (and also the -c++ option). > Although I did not implement them so far. I'll buy that. I make no claim that my SWIG patch has anywhere near enough support for running SWIG in the real world; I suspect that adding such support will make it grow up into a real class. But that class really has no need to implement the CCompiler interface. Nor should it, since SWIG is not a C compiler: it's a SWIG interface file compiler. > (Sidenote: I also needed a swig-object in build_ext for my setup-script > for win32all. I had to extend distutils in the setup-script > because there are also exe-files to be built from C++ > and swig sources). I thought I mentioned this recently: there *is* a 'link_executable()' method in MSVCCompiler. If it works, why not use it? If it doesn't work, could you submit a patch instead of implementing your own? (And if the interface specified by CCompiler is insufficient, I'd like to find out *now*!) > As I pointed out in a separate post, there should also be an option > to specify C or C++ processing. Agreed -- yet another good argument for a SWIG class. > If I find time, I will submit a new patch. Cool. My time is probably better spent learning SWIG. No wait, I mean documenting and testing the Distutils... sigh... Greg -- Greg Ward - Linux nerd gward@python.net http://starship.python.net/~gward/ I don't believe there really IS a GAS SHORTAGE.. I think it's all just a BIG HOAX on the part of the plastic sign salesmen -- to sell more numbers!! From gward@python.net Sat Jun 24 03:07:52 2000 From: gward@python.net (Greg Ward) Date: Fri, 23 Jun 2000 22:07:52 -0400 Subject: [Distutils] Duelling SWIG patches In-Reply-To: <1000623113859.ZM348943@noah.scripps.edu>; from sanner@scripps.edu on Fri, Jun 23, 2000 at 11:38:59AM -0700 References: <20000621213908.A792@beelzebub> <048001bfdcef$0735e410$4500a8c0@thomasnb> <1000623113859.ZM348943@noah.scripps.edu> Message-ID: <20000623220752.B1145@beelzebub> On 23 June 2000, Michel Sanner said: > I have been following the SWIG support discussion for a while. > I am not sure I see the point in having distutil run SWIG. Why not simply > provide the result or running swig as part of the source code that get's > compiled. There are a number of versions of SWIG that have different types of > arguments, in addition the interface might use user defined typemaps ! I see it as mainly a convenience feature. If Distutils *doesn't* provide a SWIG interface, then every developer who wants to distribute SWIG'ged code will have to write a little bit of code to run SWIG before they build or distribute their code. Ooh, that raises a thorny point: the "sdist" command needs to know about any processing that has to be done before building a source distribution, such as running SWIG so that end-users don't need SWIG to build the extension. Yet another good reason to have a SWIG interface independent of the build_ext command: but there's still the problem that the proposed way of communicating "here are my SWIG interface files" is in the list of Extension objects "owned" by build_ext. I think "build_ext" (or maybe "build") should grow a method or two that "sdist" can use to find out if there are any SWIG files to SWIGify before distributing. We can worry about a general "preprocess these files in this way before distributing" mechanism some other day. Greg -- Greg Ward - just another /P(erl|ython)/ hacker gward@python.net http://starship.python.net/~gward/ All programmers are playwrights and all computers are lousy actors. From gward@python.net Sat Jun 24 03:15:52 2000 From: gward@python.net (Greg Ward) Date: Fri, 23 Jun 2000 22:15:52 -0400 Subject: [Distutils] ccompiler problem In-Reply-To: <048a01bfdcf1$0fdacd90$4500a8c0@thomasnb>; from thomas.heller@ion-tof.com on Fri, Jun 23, 2000 at 10:57:29AM +0200 References: <048a01bfdcf1$0fdacd90$4500a8c0@thomasnb> Message-ID: <20000623221552.C1145@beelzebub> On 23 June 2000, Thomas Heller said: > Consider the object_filenames method: [...] > if ext not in self.src_extensions: > continue > ^^^^^^^^^ Problem is here [...] > If you specify a source-file with an unknown extension > in the sources list, you later get a traceback later > saying something like 'sources and targets must have the same length'. > IMO we have two possibilities here: > - assume that 'ext' is something which should be passed to the linker > - raise an error like 'Don't know how to compile this file' I like the second option: if X is a source file, then the linker almost by definition doesn't know what to do with it. Linkers don't deal with source, that's what compilers are for. (At least on the platforms that I'm familiar with, which is not many!) And of course, there's a precedent in your resource-file patch... ;-) Greg -- Greg Ward - Linux weenie gward@python.net http://starship.python.net/~gward/ Quick!! Act as if nothing has happened! From gward@python.net Sat Jun 24 03:23:51 2000 From: gward@python.net (Greg Ward) Date: Fri, 23 Jun 2000 22:23:51 -0400 Subject: [Distutils] distutil install In-Reply-To: <1000623114153.ZM349779@noah.scripps.edu>; from sanner@scripps.edu on Fri, Jun 23, 2000 at 11:41:53AM -0700 References: <1000623114153.ZM349779@noah.scripps.edu> Message-ID: <20000623222351.D1145@beelzebub> On 23 June 2000, Michel Sanner said: > I got the OpenDX Python wrapper from Randall Hopper and asked him why the .so > wrapping the DX library ends up not int he package directory but in > $exec_prefix/lib/python/site-packages. If you name an extension "foo" (no dots) it winds up in site-packages/foo.so. > I feel that it would nicer to have the .so along with all other files of the > package in $exec_prefix/lib/python/site-packages/DX. Then the extension should be named "DX.foo" -- IOW, the package of an extension is unrelated to the package of any pure Python modules in the same distribution, unless you explicitly make them the same. (This is a feature, but I don't think it's documented yet.) Greg -- Greg Ward - just another Python hacker gward@python.net http://starship.python.net/~gward/ I once decorated my apartment entirely in ten foot salad forks!! From gward@python.net Sat Jun 24 03:32:57 2000 From: gward@python.net (Greg Ward) Date: Fri, 23 Jun 2000 22:32:57 -0400 Subject: [Distutils] building extensions with AIX In-Reply-To: <395394CD.9401FB61@gmx.de>; from R.Liebscher@gmx.de on Fri, Jun 23, 2000 at 06:48:13PM +0200 References: <395394CD.9401FB61@gmx.de> Message-ID: <20000623223257.E1145@beelzebub> On 23 June 2000, Rene Liebscher said: > I have seen in the TODO file > that there was an entry about AIX. Yeah, what the TODO entry fails to mention is that I already tried to fix this, in sysconfig.py: # "Fix" all pathnames in the Makefile that are explicitly relative, # ie. that start with "./". This is a kludge to fix the "./ld_so_aix" # problem, the nature of which is that Python's installed Makefile # refers to "./ld_so_aix", but when we are building extensions we are # far from the directory where Python's Makefile (and ld_so_aix, for # that matter) is installed. Unfortunately, there are several other # relative pathnames in the Makefile, and this fix doesn't fix them, # because the layout of Python's source tree -- which is what the # Makefile refers to -- is not fully preserved in the Python # installation. Grumble. from os.path import normpath, join, dirname for (name, value) in done.items(): if value[0:2] == "./": done[name] = normpath(join(dirname(fp.name), value)) > I tried it and found some little > problems. It seems some paths in the > Makefile are wrong. The above fix *ought* to fix the relative pathname problem, but ISTR that it didn't work. Don't remember the details. > After playing a little bit around > with it, I wrote a new compiler > class. (I think, these changes could > be included in unixccompiler, but > to test it, it is nice to have a > own file for it.) Man, why does everyone want to write CCompiler classes all of a sudden! ;-) I'm not sure if this should be fixed early, in sysconfig, or late, in a platform-specific UnixCCompiler subclass. Note that there's a similar problem with extension-building on OSF/1, and however we fix the AIX problem should be how we fix the OSF/1 problem. Rene, if you cook up new version of this patch, you might just solve this problem for me. Try this: * ditch the code in sysconfig that tries to fix "./" paths * fix your code so it fits in less than 80 columns, uses os.path.join instead of "+", and puts spaces around the "=" in assignments (but *not* default or keyword arguments) * extend the default compiler table, as you suggested, to respect sys.platform Also, do you have access to AIX to test this on? If not, we should bug Vladimir Marangazov (Mr. Python-on-AIX). He almost volunteered recently on python-dev to test Distutils on AIX, but I didn't get a firm commitment out of him. ;-) Greg -- Greg Ward - nerd gward@python.net http://starship.python.net/~gward/ I just read that 50% of the population has a below median IQ! From gward@python.net Sat Jun 24 03:36:06 2000 From: gward@python.net (Greg Ward) Date: Fri, 23 Jun 2000 22:36:06 -0400 Subject: [Distutils] RC and MC patch for msvccompiler In-Reply-To: <049701bfdcf1$39a7f1c0$4500a8c0@thomasnb>; from thomas.heller@ion-tof.com on Fri, Jun 23, 2000 at 10:58:39AM +0200 References: <049701bfdcf1$39a7f1c0$4500a8c0@thomasnb> Message-ID: <20000623223606.F1145@beelzebub> On 23 June 2000, Thomas Heller said: > This is the patch for msvccompiler factored out > of my previous swig patch, which allows compiling > resource scripts (.rc) to .res files, > and messages (.mc) to .res files. Looks pretty good. Can you: * reformat so all code lines are < 80 cols (preferably 75 cols) * split the 'compile()' method up -- looks like it'll become pretty big with this patch and resubmit? Thanks! Greg -- Greg Ward - maladjusted computer geek gward@python.net http://starship.python.net/~gward/ I invented skydiving in 1989! From gward@python.net Sat Jun 24 18:34:26 2000 From: gward@python.net (Greg Ward) Date: Sat, 24 Jun 2000 13:34:26 -0400 Subject: [Distutils] Behaviour of "install_data" changed Message-ID: <20000624133426.A2283@beelzebub> I've just fixed the behaviour of the "install_data" command: the default directory for installating data files is now just the installation base, which is usually sys.prefix. Thus, if you put data_files = ["my_data"] in your setup script, you will wind up installing (eg.) /usr/local/my_data -- definitely the wrong thing on Unix, and probably wrong on Windows too. (Except for applications that have their own prefix, but that's not really dealt with yet.) This is the Right Thing now because of the change to "install_data" that lets you specify where to put data files; the above should be spelled data_files = [("share", ["my_data"])] which will install /usr/local/share/my_data. Of course, this still doesn't solve the problem of, "How does my application/module know where Distutils installed this data file if the user did some wild funky custom installation?". Oh well, better than nothing. Greg -- Greg Ward - Unix nerd gward@python.net http://starship.python.net/~gward/ Vote anarchist. From gward@python.net Sat Jun 24 18:44:36 2000 From: gward@python.net (Greg Ward) Date: Sat, 24 Jun 2000 13:44:36 -0400 Subject: [Distutils] bdist_rpm and RPM 2.x Message-ID: <20000624134436.A2327@beelzebub> The "bdist_rpm" doesn't work with RPM 2.x. This means that building RPMs will only work on Red Hat 6.x -- and presumably any version of Mandrake (since Mandrake started as a fork of Red Hat 6.0), and recent SuSE versions as well, but I don't know how recent. Does anyone care? I don't anymore, since I finally got around to upgrading to Red Hat 6. If compatibility with RPM 2.x matters to you, then please dig in to the bdist_rpm command, figure out why it doesn't work, and submit a patch. Otherwise Distutils will only be able to build RPMs with RPM 3. Greg -- Greg Ward - Linux nerd gward@python.net http://starship.python.net/~gward/ In space, no one can hear you fart. From gward@python.net Sun Jun 25 03:39:31 2000 From: gward@python.net (Greg Ward) Date: Sat, 24 Jun 2000 22:39:31 -0400 Subject: [Distutils] Updated TODO list Message-ID: <20000624223931.A3229@beelzebub> Hey, this to-do list is looking pretty good: lots of "done" items as of today. Highest priority: * bdist_wininst * auto-configuration; currently has enough to support mxDateTime, probably needs some more to support PIL, and then I need to find some other distributions with auto-configuration needs to play with Medium priority: * Cygwin GCC support, Borland C++ support * AIX, OSF/1 support Here's the list... GENERAL ------- * think about how to support distribution-specific "configure" commands -- eg. how can they push option values (include/library directories, that sort of thing) onto the "build_ext" command? [see also "AUTO-CONFIGURATION" section below, and the "config" command] * need a good, general-purpose, portable-if-you-want-it, unportable-if- you-need-control, way for the builder/installer to specify compiler and linker flags (lots of people expect CFLAGS and LDFLAGS to work, so they probably should; but options to either command and/or build are the right way, so those should be preferred) * install_data should install to $prefix by default, not $prefix/share (and should warn if developer doesn't supply any dir component: installing right to $prefix is almost always the wrong thing to do) [done 2000/06/24 GPW] DOCS ---- * write write write * include a standard blurb for README files somewhere PATCH REVIEW/INTEGRATION ------------------------ * review Rene Liebscher's patch for help options: he changed archive_util.py ccompiler.py command/bdist.py command/build.py command/build_clib.py command/build_ext.py command/sdist.py dist.py ...and I checked 'em all in without review because I want other people to try it out and I don't have time to review it right now (and he fixed a stupid bug in bdist.py for me) [done 2000/06/23 GPW] * review Rene Liebscher's cygwinccompiler.py contribution [started and aborted, 2000/06/24 GPW; asked Rene to resubmit patch with stylistic changes] COMMAND-LINE PARSING -------------------- * I think fancy_getopt needs to get fancier to properly support the -I, -D, -l, -L, etc. options of "build_ext": need to be able to accumulate multiple options in a list, should be able to split a string on a given delimiter, probably want to specify if repetitions of the same option will accumulate or replace, etc. * do the above options even work at all? seem to recall hearing reports of dismal failure, but I never looked into it [knowing how FancyGetopt works, there's no way these options can work: damn] COMPILER MODEL & CLASSES ------------------------ * add pre-processor interface to CCompiler (needed to support Autoconf-style 'try_cpp', 'search_cpp', 'search_headers' in config commands) [done, but only UnixCCompiler implements that interface] * fix UnixCCompiler so it doesn't depend on sysconfig (ie. cc must be passed in) [done 2000/06/24 GPW] * allow user to supply cc (compiler executable) in addition to compiler type [done 2000/06/24 GPW] * radically simplify CCompiler method signatures: drop most of the per-invocation customization, and just use the instance attributes for eg. include_dirs, libraries, ... [NB. should probably hold off integrating Cygwin and Borland support until this is done, *if* that is it is the right thing to do...] [update 2000/06/24: I'm cooling to this idea; it turns out the extra complex interface that's been there all along is useful for the "config" command, which has to do lots of little temporary compile and link steps] * Cygwin/Mingw32 support [Rene Liebscher is working on this] * Borland C++ support [Lyle Johnson is working on this] AUTO-CONFIGURATION ------------------ * add more goodies to the standard "config" command, and finish hacking up the example mxDateTime setup script to take advantage of them [partly done: at least enough is there to auto-configure mxDateTime; need to work on PIL's auto-configuration next] EXTENSION BUILDING ------------------ * extension building on AIX [update 2000/06/24: Rene Liebscher has a patch for this, which I have asked him to refine] * support for SWIG -- should just have to specify the .i file and have Distutils take care of running SWIG and knowing what the output is (to be really clever: make sure SWIG's output is included in source distributions, so builders-from-source don't need to have SWIG installed) [update 2000/06/24: Thomas Heller and I have gone back and forth on this a couple times: sounds like Thomas has the right idea, I'll let him work on it] * support for PyFort (lower priority than SWIG!) * OSF/1 problem: ld command has "*" in it, which is appropriate when a shell is involved, but there isn't one here, so we need to strip the quotes (and, ideally, put them back on again when spawn() prints out the command run!) INSTALLATION ------------ * if Distutils installs the first third-party modules in an installation (and creates site-packages), then "install" needlessly warns about having installed to a location not on sys.path -- presumably because site-packages isn't in sys.path at startup, since it doesn't exist until we create it! (I think this is only a problem with 1.5.2, since site-packages is now created when Python is installed -- check!) * need a mechanism for specifying pre-install and post-install hooks, which will be run when installing from a smart built distribution (RPM, wininst, etc.); also, "install" needs to run these hooks *except* for "fake" installs done solely to create a built distribution * bdist_dumb should grow a little intelligence: let packager choose whether to make archive relative to prefix or the root (prefix is essential for proper Windows support ) DISTRIBUTION FORMATS -------------------- * figure out why bdist_rpm doesn't work with RPM 2.x, and make it work if possible [punt: I don't care anymore, if anyone else does, let them fix it] * make "bdist" take multiple formats (both for convenience and consistency with "sdist"); should be doable now that we can reinitialize, refinalize, and (presumably) rerun commands [done 2000/06/06 GPW] * Solaris pkgtool, HP depot [Mark Alexander is working on these] * minimal Windows installer ("bdist_wininst") [Thomas Heller is working on this] * Wise installer for Windows ("bdist_wise") [Thomas Heller said he will work on this when "bdist_wininst" is done] $Id: TODO,v 1.5 2000/06/25 02:37:09 gward Exp $ -- Greg Ward - Linux geek gward@python.net http://starship.python.net/~gward/ No problem is so formidable that you can't just walk away from it. From R.Liebscher@gmx.de Mon Jun 26 10:40:35 2000 From: R.Liebscher@gmx.de (Rene Liebscher) Date: Mon, 26 Jun 2000 11:40:35 +0200 Subject: [Distutils] building extensions with AIX References: <395394CD.9401FB61@gmx.de> <20000623223257.E1145@beelzebub> Message-ID: <39572513.81DAB641@gmx.de> This is a multi-part message in MIME format. --------------4F4DEA373079FEB8E3F5E1E5 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Greg Ward wrote: > > Yeah, what the TODO entry fails to mention is that I already tried to > fix this, in sysconfig.py: > > # "Fix" all pathnames in the Makefile that are explicitly relative, > # ie. that start with "./". This is a kludge to fix the "./ld_so_aix" > # problem, the nature of which is that Python's installed Makefile > # refers to "./ld_so_aix", but when we are building extensions we are > # far from the directory where Python's Makefile (and ld_so_aix, for > # that matter) is installed. Unfortunately, there are several other > # relative pathnames in the Makefile, and this fix doesn't fix them, > # because the layout of Python's source tree -- which is what the > # Makefile refers to -- is not fully preserved in the Python > # installation. Grumble. The problem is the other layout of the installed Python. Makefile refers to ../././Modules or so, this directory doesn't exist. The linker scripts are in the same directory as the Makefile and config.h . > > The above fix *ought* to fix the relative pathname problem, but ISTR > that it didn't work. Don't remember the details. If you set the paths new, you don't have a relative pathname problem. > > Man, why does everyone want to write CCompiler classes all of a sudden! > ;-) Because you don't have to change many other files, if you only want to try a 'bug' workaround? > > I'm not sure if this should be fixed early, in sysconfig, or late, in a > platform-specific UnixCCompiler subclass. Note that there's a similar > problem with extension-building on OSF/1, and however we fix the AIX > problem should be how we fix the OSF/1 problem. > > Rene, if you cook up new version of this patch, you might just solve > this problem for me. Try this: > > * ditch the code in sysconfig that tries to fix "./" paths I put it all now in sysconfig.py right after scanning the Makefile. > * extend the default compiler table, as you suggested, to respect > sys.platform It is also done, even if we don't need anymore a seperate compiler class for AIX. But I included some comments how it would look if we had one. > Also, do you have access to AIX to test this on? If not, we should bug > Vladimir Marangazov (Mr. Python-on-AIX). He almost volunteered recently > on python-dev to test Distutils on AIX, but I didn't get a firm > commitment out of him. ;-) If I hadn't access to AIX, I wouldn't write patches, neither I would need them. (I tried one of my programs, which uses extensively threads, and this runs without problems, so I think it was built correct.) To be more correct, at my university I have access to Linux, AIX and NT with MSVC. (I remember we have here also some Suns.) At home I can use Linux, FreeBSD3 and NT/Win98 with mingw32/cygwin. kind regards Rene Liebscher --------------4F4DEA373079FEB8E3F5E1E5 Content-Type: text/plain; charset=us-ascii; name="aix_sysconfig.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="aix_sysconfig.patch" diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/ccompiler.py distutils/distutils/ccompiler.py --- distutils.orig/distutils/ccompiler.py Mon Jun 26 09:34:34 2000 +++ distutils/distutils/ccompiler.py Mon Jun 26 10:42:47 2000 @@ -801,6 +801,7 @@ # that platform. default_compiler = { 'posix': 'unix', 'nt': 'msvc', +# 'aix4': 'aix', } # Map compiler types to (module_name, class_name) pairs -- ie. where to @@ -814,6 +815,8 @@ "Cygwin port of GNU C Compiler for Win32"), 'mingw32': ('cygwinccompiler', 'Mingw32CCompiler', "Mingw32 port of GNU C Compiler for Win32"), +# 'aix': ('aixccompiler', 'AIXCCompiler', +# "unix with AIX specific shared object linking"), } def show_compilers(): @@ -839,9 +842,11 @@ dry_run=0, force=0): """Generate an instance of some CCompiler subclass for the supplied - platform/compiler combination. 'plat' defaults to 'os.name' - (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler - for that platform. Currently only 'posix' and 'nt' are supported, and + platform/compiler combination. 'plat' defaults to 'sys.platform' + (eg. 'aix4',freebsd3') if a entry for this 'sys.platform' in the + default_compiler table exists and os.name' (eg. 'posix', 'nt') otherwise, + and 'compiler' defaults to the default compiler for that platform. + Currently only 'posix' and 'nt' are supported, and the default compilers are "traditional Unix interface" (UnixCCompiler class) and Visual C++ (MSVCCompiler class). Note that it's perfectly possible to ask for a Unix compiler object under Windows, and a @@ -849,7 +854,10 @@ 'compiler', 'plat' is ignored. """ if plat is None: - plat = os.name + if default_compiler.has_key(sys.platform): + plat = sys.platform + else: + plat = os.name try: if compiler is None: diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/sysconfig.py distutils/distutils/sysconfig.py --- distutils.orig/distutils/sysconfig.py Mon Jun 26 09:34:35 2000 +++ distutils/distutils/sysconfig.py Mon Jun 26 11:19:19 2000 @@ -257,7 +257,21 @@ raise DistutilsPlatformError, my_msg parse_makefile(file, g) - + + # on AIX there are wrong paths to the linker scripts in the Makefile + # (these paths are relative to the python source, but if installed + # these scripts are in another directory) + if sys.platform == 'aix4': # what is with AIX 3.x ? + g['LDSHARED'] = string.join([ + # linker script is in the config directory, not in the + # Modules as the Makefile says + os.path.join(get_python_lib(standard_lib=1), + 'config','ld_so_aix'), + ' ', g['CC'], + ' ', '-bI:', # where is python's exports file + os.path.join(get_python_lib(standard_lib=1), + 'config','python.exp') + ],'') # <= all spaces are explicitly specified def _init_nt(): """Initialize the module as appropriate for NT""" --------------4F4DEA373079FEB8E3F5E1E5-- From R.Liebscher@gmx.de Mon Jun 26 12:38:49 2000 From: R.Liebscher@gmx.de (Rene Liebscher) Date: Mon, 26 Jun 2000 13:38:49 +0200 Subject: [Distutils] Behaviour of "install_data" changed References: <20000624133426.A2283@beelzebub> Message-ID: <395740C9.59CF156D@gmx.de> This is a multi-part message in MIME format. --------------1B9072FF001699F74DA18394 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Greg Ward wrote: > > I've just fixed the behaviour of the "install_data" command: the default > directory for installating data files is now just the installation base, > which is usually sys.prefix. Thus, if you put > > data_files = ["my_data"] > > in your setup script, you will wind up installing (eg.) > /usr/local/my_data -- definitely the wrong thing on Unix, and probably > wrong on Windows too. (Except for applications that have their own > prefix, but that's not really dealt with yet.) > > This is the Right Thing now because of the change to "install_data" that > lets you specify where to put data files; the above should be spelled > > data_files = [("share", ["my_data"])] > > which will install /usr/local/share/my_data. > > Of course, this still doesn't solve the problem of, "How does my > application/module know where Distutils installed this data file if the > user did some wild funky custom installation?". Oh well, better than > nothing. Would you like to have a complete new concept, which could solve all your problems? Here it is. I would like to introduce a class 'Data_Files' similar to the 'Extension' class. It should accept following parameters: * A basis directory to which all other filenames will become relative. base_dir : 'install_data','install_lib','install_headers' or any other path which is defined in 'install' * A directory under this base dir like the 'share' dir in Greg's example above. copy_to : a path name * a files list as usual files : ['foo','bar', ...] * a list of templates as in MANIFEST.in, which is used to manipulate the files list template : a list or a ';' separeted string * a flag which switches the preserving of paths on or off ( file 'foo/bar' would copied to 'base_dir/foo/bar', instead of 'base_dir/bar' ) preserve_path : 0 or 1 How to use this? Consider you had a distutils.cfg template which you want to install. There are now different ways to so: data_files = [ # The old way (the patch doesn't break old code.): ("lib/python1.5/site-packages/distutils",["distutils/distutils.cfg"]), # this is not portable with win32 # the same using a different base dir Data_Files( base_dir='install_lib', files=["distutils/distutils.cfg"], copy_to='distutils' ), # much better, but you still have to specify the target directory # without target directory Data_Files( base_dir='install_lib', files=["distutils/distutils.cfg"], preserve_path=1, ), # the file has already the rght path so we can use this # and now the most sophisticated solution: Data_Files( base_dir='install_lib', template="recursive-include distutils *.cfg", preserve_path=1, ), I think this can solve all our problems. > Of course, this still doesn't solve the problem of, "How does my > application/module know where Distutils installed this data file if the > user did some wild funky custom installation?". You only have to create a config file with the path of the other files and put this config file in your packages directory. (see the example above) Maybe you are not convinced, so here a more complex example. It is taken from a distutils setup.py file for PyOpenGL. (One of the packages I use to test distutils.) It installs some examples in its package directory, these contain data files and some images. Using the old way looks like this: # non python files of examples data_files = [ ('lib/python1.5/site-packages/OpenGL/Demo/dek',[ "OpenGL/Demo/dek/README", "OpenGL/Demo/dek/image.ppm" ]), ('lib/python1.5/site-packages/OpenGL/Demo/dek/OglSurface',[ "OpenGL/Demo/dek/OglSurface/1crn.face", "OpenGL/Demo/dek/OglSurface/1crn.pdb", "OpenGL/Demo/dek/OglSurface/1crn.vert", "OpenGL/Demo/dek/OglSurface/1crn.xyzr", "OpenGL/Demo/dek/OglSurface/README", "OpenGL/Demo/dek/OglSurface/test.ppm", ]), ('lib/python1.5/site-packages/OpenGL/Demo/srenner',[ "OpenGL/Demo/srenner/README", ]), ('lib/python1.5/site-packages/OpenGL/Demo/srenner/Images', glob (os.path.join ("OpenGL/Demo/srenner/Images","*.ppm")) ), ], And the new way is much simpler (and more portable): # non python files of examples data_files = [ Data_Files( base_dir='install_lib', # py-files shouldn't be installed with install_data template=["graft OpenGL","exclude *.py*"] , preserve_path=1, ) ], What does the patch change in distutils? First I created the class 'Data_Files', which is currently located in install_data, maybe it should get its own file as Extension did. There were also some changes in install_data to work with this new class. Then I had to take the template proccesing out of the sdist command. It is now a seperate class in sdist.py. This was necessary because I want to use it in install_data. And finally the patch creates a distutils.cfg template and changes distutils setup.py, so it would install this template. Do you like it so, or is there anything to change? (Maybe some names could get better names, but this not a big problem.) kind regards Rene Liebscher --------------1B9072FF001699F74DA18394 Content-Type: text/plain; charset=us-ascii; name="install_data.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="install_data.patch" diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/install_data.py distutils/distutils/command/install_data.py --- distutils.orig/distutils/command/install_data.py Mon Jun 26 09:34:37 2000 +++ distutils/distutils/command/install_data.py Mon Jun 26 12:51:52 2000 @@ -7,10 +7,59 @@ __revision__ = "$Id: install_data.py,v 1.10 2000/06/24 17:36:24 gward Exp $" -import os -from types import StringType +import os,sys,string +from types import StringType,TupleType,ListType from distutils.core import Command from distutils.util import change_root +from distutils.command.sdist import Template_Processor + +class Data_Files: + """ container for list of data files. + supports alternate base_dirs e.g. 'install_lib','install_header',... + supports a directory where to copy files + supports templates as in MANIFEST.in + supports preserving of paths in filenames eg. foo/xyz is copied to base_dir/foo/xyz + """ + + def __init__(self,base_dir=None,files=None,copy_to=None,template=None,preserve_path=0): + self.base_dir = base_dir + self.files = files + self.copy_to = copy_to + self.template = template + self.preserve_path = preserve_path + self.finalized = 0 + + def warn (self, msg): + sys.stderr.write ("warning: %s: %s\n" % + ("install_data", msg)) + + def debug_print (self, msg): + """Print 'msg' to stdout if the global DEBUG (taken from the + DISTUTILS_DEBUG environment variable) flag is true. + """ + from distutils.core import DEBUG + if DEBUG: + print msg + + + def finalize(self): + """ complete the files list by processing the given template """ + if self.finalized: + return + if self.files == None: + self.files = [] + if self.template != None: + if type(self.template) == StringType: + self.template = string.split(self.template,";") + template_processor = Template_Processor(self.files) + template_processor.set_warnings_function(self.warn) + template_processor.set_debug_print_function(self.debug_print) + for line in self.template: + template_processor.process_line(string.strip(line)) + self.finalized = 1 + +# end class Data_Files + class install_data (Command): @@ -32,34 +81,86 @@ def finalize_options (self): self.set_undefined_options('install', - ('install_data', 'install_dir'), - ('root', 'root'), - ) - + ('install_data', 'install_dir'), + ('root', 'root'), + ) + + def check_data(self,d): + """ check if data are in new format, if not create a suitable object. + returns finalized data object + """ + if not isinstance(d, Data_Files): + self.warn(("old-style data files list found " + "-- please convert to Data_Files instance")) + if type(d) is TupleType: + if len(d) != 2 or not (type(d[1]) is ListType): + raise DistutilsSetupError, \ + ("each element of 'data_files' option must be an " + "Data File instance, a string or 2-tuple (string,[strings])") + d = Data_Files(copy_to=d[0],files=d[1]) + else: + if not (type(d) is StringType): + raise DistutilsSetupError, \ + ("each element of 'data_files' option must be an " + "Data File instance, a string or 2-tuple (string,[strings])") + d = Data_Files(files=[d]) + d.finalize() + return d + + def run (self): - self.mkpath(self.install_dir) - for f in self.data_files: - if type(f) == StringType: - # it's a simple file, so copy it - self.warn("setup script did not provide a directory for " - "'%s' -- installing right in '%s'" % - (f, self.install_dir)) - out = self.copy_file(f, self.install_dir) - self.outfiles.append(out) + self.outfiles = [] + install_cmd = self.get_finalized_command('install') + + for d in self.data_files: + d = self.check_data(d) + + install_dir = self.install_dir + # alternative base dir given => overwrite install_dir + if d.base_dir != None: + install_dir = getattr(install_cmd,d.base_dir) + + # copy to an other directory + if d.copy_to != None: + if not os.path.isabs(d.copy_to): + # relatiev path to install_dir + dir = os.path.join(install_dir, d.copy_to) + elif install_cmd.root: + # absolute path and alternative root set + dir = change_root(self.root,d.copy_to) + else: + # absolute path + dir = d.copy_to else: - # it's a tuple with path to install to and a list of files - dir = f[0] - if not os.path.isabs(dir): - dir = os.path.join(self.install_dir, dir) - elif self.root: - dir = change_root(self.root, dir) - self.mkpath(dir) - for data in f[1]: - out = self.copy_file(data, dir) - self.outfiles.append(out) + # simply copy to install_dir + dir = install_dir + + dir=os.path.normpath(dir) + # create path + self.mkpath(dir) + + # copy all files + for f in d.files: + if d.copy_to == None: + self.warn("setup script did not provide a directory for " + "'%s' -- installing right in '%s'" % + (f, install_dir)) + if d.preserve_path: + # preserve path in filename + self.mkpath(os.path.dirname(os.path.join(dir,f))) + out = self.copy_file(f, os.path.join(dir,f)) + else: + out = self.copy_file(f, dir) + self.outfiles.append(out) + + return self.outfiles def get_inputs (self): - return self.data_files or [] - + inputs = [] + for d in self.data_files: + d = self.check_data(d) + inputs.append(d.files) + return inputs + def get_outputs (self): return self.outfiles diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/sdist.py distutils/distutils/command/sdist.py --- distutils.orig/distutils/command/sdist.py Mon Jun 26 09:34:37 2000 +++ distutils/distutils/command/sdist.py Mon Jun 26 12:39:08 2000 @@ -34,6 +34,260 @@ "List of available source distribution formats:") +class Template_Processor: + + def __init__(self, files_list=[]): + self.files=files_list + self.all_files = findall () + self.template_warn=self.dummy_function + self.debug_print=self.dummy_function + + def set_warnings_function(self, warnings_function): + self.template_warn=warnings_function + + def set_debug_print_function(self, debug_print_function): + self.debug_print=debug_print_function + + def dummy_function(self,warning): + pass + + def search_dir (self, dir, pattern=None): + """Recursively find files under 'dir' matching 'pattern' (a string + containing a Unix-style glob pattern). If 'pattern' is None, find + all files under 'dir'. Return the list of found filenames. + """ + allfiles = findall (dir) + if pattern is None: + return allfiles + + pattern_re = translate_pattern (pattern) + files = [] + for file in allfiles: + if pattern_re.match (os.path.basename (file)): + files.append (file) + + return files + + # search_dir () + + def recursive_exclude_pattern (self, dir, pattern=None): + """Remove filenames from 'self.files' that are under 'dir' and + whose basenames match 'pattern'. + """ + self.debug_print("recursive_exclude_pattern: dir=%s, pattern=%s" % + (dir, pattern)) + if pattern is None: + pattern_re = None + else: + pattern_re = translate_pattern (pattern) + + for i in range (len (self.files)-1, -1, -1): + (cur_dir, cur_base) = os.path.split (self.files[i]) + if (cur_dir == dir and + (pattern_re is None or pattern_re.match (cur_base))): + self.debug_print("removing %s" % self.files[i]) + del self.files[i] + + + def process_line (self, line): + """Read and parse a line of a template file. Process all file + specifications (include and exclude) in the template and + update 'self.files' accordingly (filenames may be added to + or removed from 'self.files' based on the template). + """ + assert self.files is not None and type (self.files) is ListType + + + words = string.split (line) + action = words[0] + + # First, check that the right number of words are present + # for the given action (which is the first word) + if action in ('include','exclude', + 'global-include','global-exclude'): + if len (words) < 2: + self.template_warn \ + ("invalid manifest template line: " + + "'%s' expects ..." % + action) + return + + pattern_list = map(convert_path, words[1:]) + + elif action in ('recursive-include','recursive-exclude'): + if len (words) < 3: + self.template_warn \ + ("invalid manifest template line: " + + "'%s' expects ..." % + action) + return + + dir = convert_path(words[1]) + pattern_list = map (convert_path, words[2:]) + + elif action in ('graft','prune'): + if len (words) != 2: + self.template_warn \ + ("invalid manifest template line: " + + "'%s' expects a single " % + action) + return + + dir_pattern = convert_path (words[1]) + + else: + self.template_warn ("invalid manifest template line: " + + "unknown action '%s'" % action) + return + + # OK, now we know that the action is valid and we have the + # right number of words on the line for that action -- so we + # can proceed with minimal error-checking. Also, we have + # defined either (pattern), (dir and pattern), or + # (dir_pattern) -- so we don't have to spend any time + # digging stuff up out of 'words'. + + if action == 'include': + self.debug_print("include " + string.join(pattern_list)) + for pattern in pattern_list: + files = self.select_pattern (self.all_files, pattern, anchor=1) + if not files: + self.template_warn ("no files found matching '%s'" % + pattern) + else: + self.files.extend (files) + + elif action == 'exclude': + self.debug_print("exclude " + string.join(pattern_list)) + for pattern in pattern_list: + num = self.exclude_pattern (self.files, pattern, anchor=1) + if num == 0: + self.template_warn ( + "no previously-included files found matching '%s'"% + pattern) + + elif action == 'global-include': + self.debug_print("global-include " + string.join(pattern_list)) + for pattern in pattern_list: + files = self.select_pattern (self.all_files, pattern, anchor=0) + if not files: + self.template_warn (("no files found matching '%s' " + + "anywhere in distribution") % + pattern) + else: + self.files.extend (files) + + elif action == 'global-exclude': + self.debug_print("global-exclude " + string.join(pattern_list)) + for pattern in pattern_list: + num = self.exclude_pattern (self.files, pattern, anchor=0) + if num == 0: + self.template_warn \ + (("no previously-included files matching '%s' " + + "found anywhere in distribution") % + pattern) + + elif action == 'recursive-include': + self.debug_print("recursive-include %s %s" % + (dir, string.join(pattern_list))) + for pattern in pattern_list: + files = self.select_pattern ( + self.all_files, pattern, prefix=dir) + if not files: + self.template_warn (("no files found matching '%s' " + + "under directory '%s'") % + (pattern, dir)) + else: + self.files.extend (files) + + elif action == 'recursive-exclude': + self.debug_print("recursive-exclude %s %s" % + (dir, string.join(pattern_list))) + for pattern in pattern_list: + num = self.exclude_pattern( + self.files, pattern, prefix=dir) + if num == 0: + self.template_warn \ + (("no previously-included files matching '%s' " + + "found under directory '%s'") % + (pattern, dir)) + + elif action == 'graft': + self.debug_print("graft " + dir_pattern) + files = self.select_pattern( + self.all_files, None, prefix=dir_pattern) + if not files: + self.template_warn ("no directories found matching '%s'" % + dir_pattern) + else: + self.files.extend (files) + + elif action == 'prune': + self.debug_print("prune " + dir_pattern) + num = self.exclude_pattern( + self.files, None, prefix=dir_pattern) + if num == 0: + self.template_warn \ + (("no previously-included directories found " + + "matching '%s'") % + dir_pattern) + else: + raise RuntimeError, \ + "this cannot happen: invalid action '%s'" % action + + # process_line () + + + + def select_pattern (self, files, pattern, anchor=1, prefix=None): + """Select strings (presumably filenames) from 'files' that match + 'pattern', a Unix-style wildcard (glob) pattern. Patterns are not + quite the same as implemented by the 'fnmatch' module: '*' and '?' + match non-special characters, where "special" is platform-dependent: + slash on Unix, colon, slash, and backslash on DOS/Windows, and colon on + Mac OS. + + If 'anchor' is true (the default), then the pattern match is more + stringent: "*.py" will match "foo.py" but not "foo/bar.py". If + 'anchor' is false, both of these will match. + + If 'prefix' is supplied, then only filenames starting with 'prefix' + (itself a pattern) and ending with 'pattern', with anything in between + them, will match. 'anchor' is ignored in this case. + + Return the list of matching strings, possibly empty. + """ + matches = [] + pattern_re = translate_pattern (pattern, anchor, prefix) + self.debug_print("select_pattern: applying regex r'%s'" % + pattern_re.pattern) + for name in files: + if pattern_re.search (name): + matches.append (name) + self.debug_print(" adding " + name) + + return matches + + # select_pattern () + + + def exclude_pattern (self, files, pattern, anchor=1, prefix=None): + """Remove strings (presumably filenames) from 'files' that match + 'pattern'. 'pattern', 'anchor', 'and 'prefix' are the same + as for 'select_pattern()', above. The list 'files' is modified + in place. + """ + pattern_re = translate_pattern (pattern, anchor, prefix) + self.debug_print("exclude_pattern: applying regex r'%s'" % + pattern_re.pattern) + for i in range (len(files)-1, -1, -1): + if pattern_re.search (files[i]): + self.debug_print(" removing " + files[i]) + del files[i] + + # exclude_pattern () + + class sdist (Command): description = "create a source distribution (tarball, zip file, etc.)" @@ -300,45 +554,6 @@ # add_defaults () - def search_dir (self, dir, pattern=None): - """Recursively find files under 'dir' matching 'pattern' (a string - containing a Unix-style glob pattern). If 'pattern' is None, find - all files under 'dir'. Return the list of found filenames. - """ - allfiles = findall (dir) - if pattern is None: - return allfiles - - pattern_re = translate_pattern (pattern) - files = [] - for file in allfiles: - if pattern_re.match (os.path.basename (file)): - files.append (file) - - return files - - # search_dir () - - - def recursive_exclude_pattern (self, dir, pattern=None): - """Remove filenames from 'self.files' that are under 'dir' and - whose basenames match 'pattern'. - """ - self.debug_print("recursive_exclude_pattern: dir=%s, pattern=%s" % - (dir, pattern)) - if pattern is None: - pattern_re = None - else: - pattern_re = translate_pattern (pattern) - - for i in range (len (self.files)-1, -1, -1): - (cur_dir, cur_base) = os.path.split (self.files[i]) - if (cur_dir == dir and - (pattern_re is None or pattern_re.match (cur_base))): - self.debug_print("removing %s" % self.files[i]) - del self.files[i] - - def read_template (self): """Read and parse the manifest template file named by 'self.template' (usually "MANIFEST.in"). Process all file @@ -357,151 +572,16 @@ rstrip_ws=1, collapse_ws=1) - all_files = findall () - while 1: + template_processor = Template_Processor(self.files) + template_processor.set_warnings_function(template.warn) + template_processor.set_debug_print_function(self.debug_print) - line = template.readline() + while 1: + line = template.readline() if line is None: # end of file break - - words = string.split (line) - action = words[0] - - # First, check that the right number of words are present - # for the given action (which is the first word) - if action in ('include','exclude', - 'global-include','global-exclude'): - if len (words) < 2: - template.warn \ - ("invalid manifest template line: " + - "'%s' expects ..." % - action) - continue - - pattern_list = map(convert_path, words[1:]) - - elif action in ('recursive-include','recursive-exclude'): - if len (words) < 3: - template.warn \ - ("invalid manifest template line: " + - "'%s' expects ..." % - action) - continue - - dir = convert_path(words[1]) - pattern_list = map (convert_path, words[2:]) - - elif action in ('graft','prune'): - if len (words) != 2: - template.warn \ - ("invalid manifest template line: " + - "'%s' expects a single " % - action) - continue - - dir_pattern = convert_path (words[1]) - - else: - template.warn ("invalid manifest template line: " + - "unknown action '%s'" % action) - continue - - # OK, now we know that the action is valid and we have the - # right number of words on the line for that action -- so we - # can proceed with minimal error-checking. Also, we have - # defined either (pattern), (dir and pattern), or - # (dir_pattern) -- so we don't have to spend any time - # digging stuff up out of 'words'. - - if action == 'include': - self.debug_print("include " + string.join(pattern_list)) - for pattern in pattern_list: - files = self.select_pattern (all_files, pattern, anchor=1) - if not files: - template.warn ("no files found matching '%s'" % - pattern) - else: - self.files.extend (files) - - elif action == 'exclude': - self.debug_print("exclude " + string.join(pattern_list)) - for pattern in pattern_list: - num = self.exclude_pattern (self.files, pattern, anchor=1) - if num == 0: - template.warn ( - "no previously-included files found matching '%s'"% - pattern) - - elif action == 'global-include': - self.debug_print("global-include " + string.join(pattern_list)) - for pattern in pattern_list: - files = self.select_pattern (all_files, pattern, anchor=0) - if not files: - template.warn (("no files found matching '%s' " + - "anywhere in distribution") % - pattern) - else: - self.files.extend (files) - - elif action == 'global-exclude': - self.debug_print("global-exclude " + string.join(pattern_list)) - for pattern in pattern_list: - num = self.exclude_pattern (self.files, pattern, anchor=0) - if num == 0: - template.warn \ - (("no previously-included files matching '%s' " + - "found anywhere in distribution") % - pattern) - - elif action == 'recursive-include': - self.debug_print("recursive-include %s %s" % - (dir, string.join(pattern_list))) - for pattern in pattern_list: - files = self.select_pattern ( - all_files, pattern, prefix=dir) - if not files: - template.warn (("no files found matching '%s' " + - "under directory '%s'") % - (pattern, dir)) - else: - self.files.extend (files) - - elif action == 'recursive-exclude': - self.debug_print("recursive-exclude %s %s" % - (dir, string.join(pattern_list))) - for pattern in pattern_list: - num = self.exclude_pattern( - self.files, pattern, prefix=dir) - if num == 0: - template.warn \ - (("no previously-included files matching '%s' " + - "found under directory '%s'") % - (pattern, dir)) - - elif action == 'graft': - self.debug_print("graft " + dir_pattern) - files = self.select_pattern( - all_files, None, prefix=dir_pattern) - if not files: - template.warn ("no directories found matching '%s'" % - dir_pattern) - else: - self.files.extend (files) - - elif action == 'prune': - self.debug_print("prune " + dir_pattern) - num = self.exclude_pattern( - self.files, None, prefix=dir_pattern) - if num == 0: - template.warn \ - (("no previously-included directories found " + - "matching '%s'") % - dir_pattern) - else: - raise RuntimeError, \ - "this cannot happen: invalid action '%s'" % action - + template_processor.process_line(line) # while loop over lines of template file # read_template () @@ -516,57 +596,11 @@ """ build = self.get_finalized_command('build') base_dir = self.distribution.get_fullname() - self.exclude_pattern (self.files, None, prefix=build.build_base) - self.exclude_pattern (self.files, None, prefix=base_dir) - - - def select_pattern (self, files, pattern, anchor=1, prefix=None): - """Select strings (presumably filenames) from 'files' that match - 'pattern', a Unix-style wildcard (glob) pattern. Patterns are not - quite the same as implemented by the 'fnmatch' module: '*' and '?' - match non-special characters, where "special" is platform-dependent: - slash on Unix, colon, slash, and backslash on DOS/Windows, and colon on - Mac OS. - - If 'anchor' is true (the default), then the pattern match is more - stringent: "*.py" will match "foo.py" but not "foo/bar.py". If - 'anchor' is false, both of these will match. - - If 'prefix' is supplied, then only filenames starting with 'prefix' - (itself a pattern) and ending with 'pattern', with anything in between - them, will match. 'anchor' is ignored in this case. - - Return the list of matching strings, possibly empty. - """ - matches = [] - pattern_re = translate_pattern (pattern, anchor, prefix) - self.debug_print("select_pattern: applying regex r'%s'" % - pattern_re.pattern) - for name in files: - if pattern_re.search (name): - matches.append (name) - self.debug_print(" adding " + name) - - return matches - - # select_pattern () - - - def exclude_pattern (self, files, pattern, anchor=1, prefix=None): - """Remove strings (presumably filenames) from 'files' that match - 'pattern'. 'pattern', 'anchor', 'and 'prefix' are the same - as for 'select_pattern()', above. The list 'files' is modified - in place. - """ - pattern_re = translate_pattern (pattern, anchor, prefix) - self.debug_print("exclude_pattern: applying regex r'%s'" % - pattern_re.pattern) - for i in range (len(files)-1, -1, -1): - if pattern_re.search (files[i]): - self.debug_print(" removing " + files[i]) - del files[i] - - # exclude_pattern () + template_processor = Template_Processor(self.files) + # warnings are not of interest here + template_processor.set_debug_print_function(self.debug_print) + template_processor.process_line("prune " + build.build_base) + template_processor.process_line("prune " + base_dir) def write_manifest (self): @@ -688,7 +722,8 @@ fullname = os.path.join (dir, name) else: fullname = name - list.append (fullname) + if not os.path.isdir (fullname): + list.append (fullname) if os.path.isdir (fullname) and not os.path.islink(fullname): push (fullname) diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/distutils.cfg distutils/distutils/distutils.cfg --- distutils.orig/distutils/distutils.cfg Thu Jan 1 01:00:00 1970 +++ distutils/distutils/distutils.cfg Mon Jun 26 12:24:29 2000 @@ -0,0 +1,18 @@ +# +# distutils.cfg +# +# the site-wide Distutils config file. +# This has the purpose of serving as an example of some of +# the things you can do with Distutils config files. +# +# $Id: distutils.cfg $ +# + +[sdist] +#formats=gztar,zip + +[build] +#compiler=unix + +[bdist] +#formats=gztar,rpm diff -BurN --minimal --exclude=*.pyc distutils.orig/setup.py distutils/setup.py --- distutils.orig/setup.py Mon Jun 26 12:47:34 2000 +++ distutils/setup.py Mon Jun 26 12:43:30 2000 @@ -9,6 +9,7 @@ __revision__ = "$Id: setup.py,v 1.16 2000/06/02 02:23:42 gward Exp $" from distutils.core import setup +from distutils.command.install_data import Data_Files setup (name = "Distutils", version = "0.9pre", @@ -26,4 +27,23 @@ # This implies all pure Python modules in ./distutils/ and # ./distutils/command/ packages = ['distutils', 'distutils.command'], + + # non python files + data_files = [# ("lib/python1.5/site-packages/distutils",["distutils/distutils.cfg"]), # old style + Data_Files( + base_dir='install_lib', + files=["distutils/distutils.cfg"], + preserve_path=1, + ), +# Data_Files( +# base_dir='install_lib', +# files=["distutils/distutils.cfg"], +# copy_to='distutils' +# ), +# Data_Files( +# base_dir='install_lib', +# template="recursive-include distutils *.cfg", +# preserve_path=1, +# ), + ], ) --------------1B9072FF001699F74DA18394-- From thomas.heller@ion-tof.com Mon Jun 26 17:02:06 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Mon, 26 Jun 2000 18:02:06 +0200 Subject: [Distutils] Behaviour of "install_data" changed References: <20000624133426.A2283@beelzebub> Message-ID: <024401bfdf87$e09d2fc0$4500a8c0@thomasnb> > I've just fixed the behaviour of the "install_data" command: the default > directory for installating data files is now just the installation base, > which is usually sys.prefix. Thus, if you put > > data_files = ["my_data"] > > in your setup script, you will wind up installing (eg.) > /usr/local/my_data -- definitely the wrong thing on Unix, and probably > wrong on Windows too. (Except for applications that have their own > prefix, but that's not really dealt with yet.) > > This is the Right Thing now because of the change to "install_data" that > lets you specify where to put data files; the above should be spelled > > data_files = [("share", ["my_data"])] > > which will install /usr/local/share/my_data. > > Of course, this still doesn't solve the problem of, "How does my > application/module know where Distutils installed this data file if the > user did some wild funky custom installation?". Oh well, better than > nothing. > > Greg It works for me. Context: I'm currently writing a setup-script for Marks win32 extensions. Mark has put a lot of "data files" inside the source code tree: html docs, cfg files, ... If this is installed into the destination directories, the python-scripts (or PythonWin.exe) will know how to find these files. Thomas From thomas.heller@ion-tof.com Mon Jun 26 17:25:10 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Mon, 26 Jun 2000 18:25:10 +0200 Subject: [Distutils] Duelling SWIG patches References: <20000621213908.A792@beelzebub> <048001bfdcef$0735e410$4500a8c0@thomasnb> <20000623220341.A1145@beelzebub> Message-ID: <026401bfdf8b$19fef250$4500a8c0@thomasnb> This is a multi-part message in MIME format. ------=_NextPart_000_0261_01BFDF9B.DCFFCDA0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit I wrote: > > (Sidenote: I also needed a swig-object in build_ext for my setup-script > > for win32all. I had to extend distutils in the setup-script > > because there are also exe-files to be built from C++ > > and swig sources). but this is of course nonsense. Swig is used to build python-extensions, not exe-files. Sorry for that. Greg: > I thought I mentioned this recently: there *is* a 'link_executable()' > method in MSVCCompiler. If it works, why not use it? If it doesn't > work, could you submit a patch instead of implementing your own? (And > if the interface specified by CCompiler is insufficient, I'd like to > find out *now*!) Yes, I used compile() and link_shared_object() in my win32 setup script. No need to worry about it. > > > As I pointed out in a separate post, there should also be an option > > to specify C or C++ processing. > > Agreed -- yet another good argument for a SWIG class. > > > If I find time, I will submit a new patch. > > Cool. My time is probably better spent learning SWIG. No wait, I mean > documenting and testing the Distutils... sigh... Well, actually I also don't use swig normally. I was forced to use it for Marks win32 stuff. He lets swig generate c++ code, so... Appended is a patch for your swig patches (;-) which adds an --swig-cpp command line option to build_ext, so that I can build the win32 stuff again. There should probably better be an option for the Extension() class, but (hopefully) someone else can do this. This is in chunks 1, 2, 4, 5. Chunks 3 and 6 contain a change for building extensions on NT: MSVC generates .lib and .exp files when building shared libraries. The .exp files are usually unneeded, the .lib files are import libraries, which may be needed for (other) dlls linking to the first one. Up to now these files were created in the build/lib.win32/Release or build/lib.win32/Debug directories. Sometimes python extensions are dependend on each other. One example is the ODBC stuff included in Marks code: The odbc extension links dynamically to the dbi extension. So I changed build_ext to create the .lib (and .exp) files in the build/lib.win32 directory. Since they have different names for debug and release builds, no conficts occur: dbi.lib, dbi_d.lib. Thomas ------=_NextPart_000_0261_01BFDF9B.DCFFCDA0 Content-Type: text/plain; name="build_ext.diff.txt" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="build_ext.diff.txt" Index: build_ext.py =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/python/distutils/distutils/command/build_ext.py,v retrieving revision 1.48 diff -c -r1.48 build_ext.py *** build_ext.py 2000/06/25 02:30:15 1.48 --- build_ext.py 2000/06/26 16:15:18 *************** *** 77,82 **** --- 77,84 ---- "forcibly build everything (ignore file timestamps)"), ('compiler=3D', 'c', "specify the compiler type"), + ('swig-cpp', None, + "let swig create c++ files"), ] =20 help_options =3D [ *************** *** 101,106 **** --- 103,109 ---- self.debug =3D None self.force =3D None self.compiler =3D None + self.swig_cpp =3D None =20 =20 def finalize_options (self): *************** *** 152,157 **** --- 155,161 ---- # also Python's library directory must be appended to = library_dirs if os.name =3D=3D 'nt': self.library_dirs.append (os.path.join(sys.exec_prefix, = 'libs')) + self.implib_dir =3D self.build_temp if self.debug: self.build_temp =3D os.path.join (self.build_temp, = "Debug") else: *************** *** 443,457 **** swig_sources =3D [] swig_targets =3D {} =20 ! # XXX this drops generated C files into the source tree, which # is fine for developers who want to distribute the generated # source -- but there should be an option to put SWIG output = in # the temp dir. =20 for source in sources: (base, ext) =3D os.path.splitext(source) if ext =3D=3D ".i": # SWIG interface file ! new_sources.append(base + ".c") # umm, what if it's = C++? swig_sources.append(source) swig_targets[source] =3D new_sources[-1] else: --- 447,466 ---- swig_sources =3D [] swig_targets =3D {} =20 ! # XXX this drops generated C/C++ files into the source tree, = which # is fine for developers who want to distribute the generated # source -- but there should be an option to put SWIG output = in # the temp dir. =20 + if self.swig_cpp: + target_ext =3D '.cpp' + else: + target_ext =3D '.c' +=20 for source in sources: (base, ext) =3D os.path.splitext(source) if ext =3D=3D ".i": # SWIG interface file ! new_sources.append(base + target_ext) swig_sources.append(source) swig_targets[source] =3D new_sources[-1] else: *************** *** 461,471 **** return new_sources =20 swig =3D self.find_swig() ! swig_cmd =3D [swig, "-python", "-dnone", "-ISWIG"] # again, = C++?!? =20 for source in swig_sources: ! self.announce ("swigging %s to %s" % (src, obj)) ! self.spawn(swig_cmd + ["-o", swig_targets[source], = source]) =20 return new_sources =20 --- 470,483 ---- return new_sources =20 swig =3D self.find_swig() ! swig_cmd =3D [swig, "-python", "-dnone", "-ISWIG"] ! if self.swig_cpp: ! swig_cmd.append ("-c++") =20 for source in swig_sources: ! target =3D swig_targets[source] ! self.announce ("swigging %s to %s" % (source, target)) ! self.spawn(swig_cmd + ["-o", target, source]) =20 return new_sources =20 *************** *** 528,542 **** modname =3D string.split (ext.name, '.')[-1] extra_args.append('/export:init%s' % modname) =20 ! # The MSVC linker generates unneeded .lib and .exp files, ! # which cannot be suppressed by any linker switches. So ! # make sure they are generated in the temporary build ! # directory. implib_file =3D os.path.join ( ! self.build_temp, self.get_ext_libname (ext.name)) extra_args.append ('/IMPLIB:' + implib_file) self.mkpath (os.path.dirname (implib_file)) =20 # msvc_prelink_hack () =20 --- 540,557 ---- modname =3D string.split (ext.name, '.')[-1] extra_args.append('/export:init%s' % modname) =20 ! # The MSVC linker generates .lib and .exp files, ! # which cannot be suppressed by any linker switches. The .lib ! # files may even be needed! Make sure they are generated in ! # the temporary build directory. Since they have different ! # names for debug and release builds, they can go ! # into the same directory. implib_file =3D os.path.join ( ! self.implib_dir, self.get_ext_libname (ext.name)) extra_args.append ('/IMPLIB:' + implib_file) self.mkpath (os.path.dirname (implib_file)) +=20 =20 # msvc_prelink_hack () =20 ------=_NextPart_000_0261_01BFDF9B.DCFFCDA0-- From gward@python.net Tue Jun 27 03:39:56 2000 From: gward@python.net (Greg Ward) Date: Mon, 26 Jun 2000 22:39:56 -0400 Subject: [Distutils] New code snapshots on starship Message-ID: <20000626223955.A748@beelzebub> Hi all -- I've just uploaded two code snapshots (one from Saturday, one from today) to Starship. Unfortunately, Starship seems to have gone down in the time since I uploaded them, so I can't test these URLs. However, try 'em yourself: http://starship.python.net/~gward/python/distutils-20000624.tar.gz http://starship.python.net/~gward/python/distutils-20000624.zip http://starship.python.net/~gward/python/distutils-20000626.tar.gz http://starship.python.net/~gward/python/distutils-20000626.zip I can't think of any reason why you'd want to use Saturday's snapshot, as tonight's is *ever* so much nicer: it includes Thomas' "bdist_wininst" command, and my adaptation of Rene's fix for building extensions on AIX. Please give these (and all the other recent features) a whirl! I want to put together Distutils 0.9 in the next couple of days, so there's time to fix any bugs that people discover before Guido throws up Python 1.6b1. Greg -- Greg Ward - programmer-at-big gward@python.net http://starship.python.net/~gward/ I have a very good DENTAL PLAN. Thank you. From gward@python.net Tue Jun 27 02:45:34 2000 From: gward@python.net (Greg Ward) Date: Mon, 26 Jun 2000 21:45:34 -0400 Subject: [Distutils] Duelling SWIG patches In-Reply-To: <026401bfdf8b$19fef250$4500a8c0@thomasnb>; from thomas.heller@ion-tof.com on Mon, Jun 26, 2000 at 06:25:10PM +0200 References: <20000621213908.A792@beelzebub> <048001bfdcef$0735e410$4500a8c0@thomasnb> <20000623220341.A1145@beelzebub> <026401bfdf8b$19fef250$4500a8c0@thomasnb> Message-ID: <20000626214534.C1096@beelzebub> On 26 June 2000, Thomas Heller said: > but this is of course nonsense. Swig is used to build > python-extensions, not exe-files. Sorry for that. Yeah, but I'd still like to know if 'link_executable()' works on Windows! I think it'd be really cool if part of building Distutils on Windows was (optionally!) to compile your wininst stub, all using the Distutils compiler interface... (Yeah, I know, the Distutils shouldn't require a compiler or anything funky. Still...) > Appended is a patch for your swig patches (;-) which adds an --swig-cpp > command line option to build_ext, so that I can build the win32 stuff again. > There should probably better be an option for the Extension() class, but > (hopefully) someone else can do this. > This is in chunks 1, 2, 4, 5. OK, the SWIG stuff is fine -- checked it in. > Chunks 3 and 6 contain a change for building extensions on NT: > MSVC generates .lib and .exp files when building shared libraries. > The .exp files are usually unneeded, the .lib files are import libraries, > which may be needed for (other) dlls linking to the first one. > Up to now these files were created in the > build/lib.win32/Release or build/lib.win32/Debug directories. > Sometimes python extensions are dependend on each other. > One example is the ODBC stuff included in Marks code: > The odbc extension links dynamically to the dbi extension. > So I changed build_ext to create the .lib (and .exp) files > in the build/lib.win32 directory. Since they have different > names for debug and release builds, no conficts occur: dbi.lib, dbi_d.lib. OK, that's in too, although it took a while to sink in through my thick skull -- so the checkin messages are a bit confused. Hey, waitasec: you're referring to "build/lib.win32/Release" -- but the code in front me of says self.implib_dir = self.build_temp which to me eyes (scanning build_ext.py and build.py) resolves to "build/temp.win32", hence the Debug and Release directories are under build/temp.win32, not build/lib.win32. What's going on here? I'm confused... can someone explain my code to me? ;-) (Well, let's face it, the Windows stuff in build_ext.py really isn't my code...) Greg -- Greg Ward - Linux weenie gward@python.net http://starship.python.net/~gward/ Very few profundities can be expressed in less than 80 characters. From gward@python.net Tue Jun 27 03:00:04 2000 From: gward@python.net (Greg Ward) Date: Mon, 26 Jun 2000 22:00:04 -0400 Subject: [Distutils] building extensions with AIX In-Reply-To: <39572513.81DAB641@gmx.de>; from R.Liebscher@gmx.de on Mon, Jun 26, 2000 at 11:40:35AM +0200 References: <395394CD.9401FB61@gmx.de> <20000623223257.E1145@beelzebub> <39572513.81DAB641@gmx.de> Message-ID: <20000626220004.A1129@beelzebub> On 26 June 2000, Rene Liebscher said: > > * extend the default compiler table, as you suggested, to respect > > sys.platform > It is also done, even if we don't need anymore a seperate compiler class > for AIX. But I included some comments how it would look if we had one. OK, I've squirrelled this away in my "patches" directory for a rainy day. If it's not needed for the AIX hack, it's not needed (yet). Your fix to sysconfig.py looked right in spirit, but I totally rewrote it. Give it a whirl and let me know if I broke anything. Greg -- Greg Ward - just another /P(erl|ython)/ hacker gward@python.net http://starship.python.net/~gward/ I once decorated my apartment entirely in ten foot salad forks!! From gward@python.net Tue Jun 27 03:07:12 2000 From: gward@python.net (Greg Ward) Date: Mon, 26 Jun 2000 22:07:12 -0400 Subject: [Distutils] Behaviour of "install_data" changed In-Reply-To: <395740C9.59CF156D@gmx.de>; from R.Liebscher@gmx.de on Mon, Jun 26, 2000 at 01:38:49PM +0200 References: <20000624133426.A2283@beelzebub> <395740C9.59CF156D@gmx.de> Message-ID: <20000626220712.B1129@beelzebub> On 26 June 2000, Rene Liebscher said: > Would you like to have a complete new concept, which could solve all > your > problems? Here it is. Aiieeee! "Complete" or "complicated"?!? > I would like to introduce a class 'Data_Files' similar to the > 'Extension' > class. Conceptual problem here: Python extensions are fairly complicated beasts, with lots of knobs to twiddle. Data files are not: they have a source filename, a destination directory, and that's about it. I kinda like the ability to specify an "abstract base directory" ie. one of the keys to the installation scheme dictionary. But that's not compelling enough. I think the use of the manifest template machinery is complete overkill. What's wrong with os.glob()? Even in a really complex case, where the manifest machinery would be useful, I think it would be better just to expose it as one of the "utility classes" that Distutils makes available to authors of setup scripts, rather than working it intimately into the specification of data files, which ought to be fairly simple. > I think this can solve all our problems. Except for code bloat. >smirk< Sorry, that was low. Oh well, sometimes I just have to be mean, and tonight is one of those times. Final excuse: it's getting to close to Distutils 0.9/Python 1.6b1 to do major renovations. Bug fixes only, please. Greg -- Greg Ward - programmer-at-large gward@python.net http://starship.python.net/~gward/ A man without religion is like a fish without a bicycle. From calvin@cs.uni-sb.de Tue Jun 27 10:01:16 2000 From: calvin@cs.uni-sb.de (Bastian Kleineidam) Date: Tue, 27 Jun 2000 11:01:16 +0200 (CEST) Subject: [Distutils] bdist_win misses reinitialization In-Reply-To: <3950725F.98723A7B@lemburg.com> Message-ID: Hello, the bdist_win command did not call self.reinitialize_command. Patch follows. Bastian Kleineidam diff -BurN --minimal --exclude=*.pyc distutils.orig/distutils/command/bdist_wininst.py distutils/distutils/command/bdist_wininst.py --- distutils.orig/distutils/command/bdist_wininst.py Tue Jun 27 03:24:38 2000 +++ distutils/distutils/command/bdist_wininst.py Tue Jun 27 10:22:09 2000 @@ -70,9 +70,11 @@ # options on it! (The option we set, 'root', is so that we can do # a proper "fake install" using this install command object.) install = self.distribution.get_command_obj('install') + self.reinitialize_command(install) install.root = self.bdist_dir install_lib = self.distribution.get_command_obj('install_lib') + self.reinitialize_command(install_lib) install_lib.compile = 0 install_lib.optimize = 0 From thomas.heller@ion-tof.com Tue Jun 27 12:01:05 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Tue, 27 Jun 2000 13:01:05 +0200 Subject: [Distutils] Duelling SWIG patches References: <20000621213908.A792@beelzebub> <048001bfdcef$0735e410$4500a8c0@thomasnb> <20000623220341.A1145@beelzebub> <026401bfdf8b$19fef250$4500a8c0@thomasnb> <20000626214534.C1096@beelzebub> Message-ID: <017e01bfe026$fddc3730$4500a8c0@thomasnb> > On 26 June 2000, Thomas Heller said: > > but this is of course nonsense. Swig is used to build > > python-extensions, not exe-files. Sorry for that. > > Yeah, but I'd still like to know if 'link_executable()' works on > Windows! I think it'd be really cool if part of building Distutils on > Windows was (optionally!) to compile your wininst stub, all using the > Distutils compiler interface... Yes, it works. To illustrate: this is an excerpt of my setup.py for win32all (building wininst.exe inside Distutils is reserved for later): class my_build_ext (build_ext): def run (self): build_ext.run (self) self.build_dlls() self.build_exes() def build_dlls (self): for target in dll_files: sources = target.sources ext_filename = os.path.join (self.build_lib, target.name + '.dll') if not (self.force or newer_group(sources, ext_filename, 'newer')): self.announce ("skipping '%s' (up-to-date)" % target.name) return else: self.announce ("building '%s'" % target.name) objects = self.compiler.compile (target.sources, output_dir=self.build_temp, include_dirs=target.include_dirs, debug=self.debug, extra_postargs=target.extra_compile_args) self.compiler.link_shared_object( objects, ext_filename, libraries=target.libraries, library_dirs=target.library_dirs, extra_postargs=target.extra_args, debug=self.debug) def build_exes (self): for target in exe_files: sources = target.sources ext_filename = os.path.join (self.build_lib, target.name) if not (self.force or newer_group(sources, ext_filename + '.exe', 'newer')): self.announce ("skipping '%s' (up-to-date)" % target.name) return else: self.announce ("building '%s'" % target.name) extra_args = target.extra_compile_args objects = self.compiler.compile (sources, output_dir=self.build_temp, include_dirs=target.include_dirs, debug=self.debug, extra_postargs=extra_args) extra_args = target.extra_link_args self.compiler.link_executable( objects, ext_filename, libraries=target.libraries, library_dirs=target.library_dirs, extra_postargs=extra_args, debug=self.debug) > [about the MSVC compiler patches] > Hey, waitasec: you're referring to "build/lib.win32/Release" -- but the > code in front me of says > > self.implib_dir = self.build_temp > > which to me eyes (scanning build_ext.py and build.py) resolves to > "build/temp.win32", hence the Debug and Release directories are under > build/temp.win32, not build/lib.win32. > Sorry, a simple typo. You are correct: What I meant is build/temp.win32. Thomas From gward@python.net Wed Jun 28 01:54:19 2000 From: gward@python.net (Greg Ward) Date: Tue, 27 Jun 2000 20:54:19 -0400 Subject: [Distutils] Comments on bdist_wininst Message-ID: <20000627205419.A1576@beelzebub> Howdy -- OK, I'm looking through bdist_wininst.py right now. About all I've fixed so far are typos in comments, and changed it to use 'reinitialize_command()' -- thanks to Bastian for spotting that one (and prodding me into reviewing the code). Some thoughts... these are mostly idle speculation, because I really can't see anything wrong with the code! * should we change ImportError on zlib to DistutilsPlatformError (or something) that generates a friendlier error message... or is this being silly because zlib is absolutely positively always available for Python on Windows? * is "foo-1.0.win32.exe" the right filename for the installer? this is consistent with "dumb" build distributions (simple tarballs and ZIP files) as well as RPMs, so that's a good enough argument for me. * "win32" is hard-coded in a few spots: should that be 'get_platform()' (which now just returns sys.platform)? (I don't remember what the decision on sys.platform for 64-bit Windows was: is it going to return "win32"?) Other than it looks good. I'll see if I can't produce an installer for the Distutils tonight -- that would be, as they say, THE BOMB. ;-) Greg -- Greg Ward - maladjusted nerd gward@python.net http://starship.python.net/~gward/ If it can't be expressed in figures, it is not science--it is opinion. From gward@python.net Wed Jun 28 01:58:43 2000 From: gward@python.net (Greg Ward) Date: Tue, 27 Jun 2000 20:58:43 -0400 Subject: [Distutils] DOS text files and CVS Message-ID: <20000627205843.A1607@beelzebub> Hi all -- can anyone enlighten me on the right way to check in DOS text files to a CVS repository? I have Thomas Heller's C source for his simple graphical installer for Python modules, and it should definitely be in the Distutils CVS tree. But I don't want to check it in if it'll screw up line-endings for anyone. Is there a Right Way to do this? Thanks -- Greg -- Greg Ward - Linux nerd gward@python.net http://starship.python.net/~gward/ Just because you're paranoid doesn't mean they *aren't* out to get you. From gward@python.net Wed Jun 28 02:14:16 2000 From: gward@python.net (Greg Ward) Date: Tue, 27 Jun 2000 21:14:16 -0400 Subject: [Distutils] Better support for compiler temp dirs Message-ID: <20000627211416.A1669@beelzebub> I just got the Lyle Johnson's current patch for supporting Borland C++. One thing he added is a 'build_temp' parameter to the 'link_*()' methods of the CCompiler interface. This seems reasonable to me, so I'm going to check it in as-is. However, BCPPCompiler is the only compiler class to do anything with 'build_temp'. Strikes me as irrelevant for UnixCCompiler, but could very well be useful for MSVCCompiler: the issue of linker turds has been hacked around in the 'msvc_prelink_hack()' method, but is there a nicer way to do it? Possibly. This change might reduce the amount of code in that hack method, which would be a good thing. Anyone want to take a look at this and see if we can lighten the load of 'msvc_prelink_hack()' by using the 'build_temp' parameter to 'link_*()'? Thanks in advance! Greg -- Greg Ward - Unix geek gward@python.net http://starship.python.net/~gward/ Never put off till tomorrow what you can put off till the day after tomorrow. From tpeters@beopen.com Wed Jun 28 02:39:31 2000 From: tpeters@beopen.com (Tim Peters) Date: Tue, 27 Jun 2000 21:39:31 -0400 Subject: [Distutils] DOS text files and CVS In-Reply-To: <20000627205843.A1607@beelzebub> Message-ID: [Greg Ward] > can anyone enlighten me on the right way to check in DOS text files to a > CVS repository? Aargh, I haven't used CVS in about 6 years ... somehow or other, I believe you need to convince CVS that it's a binary (not text) file. Then it will skip line-end conversions. not-a-solution-but-maybe-a-clue-ly y'rs - tim From gmcm@hypernet.com Wed Jun 28 02:47:30 2000 From: gmcm@hypernet.com (Gordon McMillan) Date: Tue, 27 Jun 2000 21:47:30 -0400 Subject: [Distutils] Re: [Python-Dev] DOS text files and CVS In-Reply-To: <20000627205843.A1607@beelzebub> Message-ID: <1249965584-36289880@hypernet.com> Greg Ward asks: > can anyone enlighten me on the right way to check in DOS text > files to a CVS repository? I have Thomas Heller's C source for > his simple graphical installer for Python modules, and it should > definitely be in the Distutils CVS tree. But I don't want to > check it in if it'll screw up line-endings for anyone. Is there > a Right Way to do this? Well, if you checked it in from a Windows box, CVS would translate line endings to native, then a Windows checkout would translate back to Windows endings. So assuming you don't want to get your fingers dirty, give it *n*x line endings and check it in. CVS does understand text, you know :-). (And about the only Windows editor that barfs on *n*x line endings is Notepad.) - Gordon From davida@pobox.com Wed Jun 28 02:50:24 2000 From: davida@pobox.com (David Arnold) Date: Wed, 28 Jun 2000 11:50:24 +1000 Subject: [Distutils] DOS text files and CVS In-Reply-To: Your message of "Tue, 27 Jun 2000 21:39:31 -0400." Message-ID: <200006280150.LAA17759@xevious.dstc.monash.edu.au> -->"Tim" == Tim Peters writes: Tim> Aargh, I haven't used CVS in about 6 years ... somehow or Tim> other, I believe you need to convince CVS that it's a binary Tim> (not text) file. Then it will skip line-end conversions. cvs add -kb file should work to add a binary file. not sure that this is the best way to deal with DOS files, but it should work ... d From gward@python.net Wed Jun 28 02:54:20 2000 From: gward@python.net (Greg Ward) Date: Tue, 27 Jun 2000 21:54:20 -0400 Subject: [Distutils] Another code snapshot Message-ID: <20000627215420.A1886@beelzebub> OK, tonight's changes were worth another code snapshot. You'll find it on my Starship page, at: http://starship.python.net/~gward/python/distutils.html Distutils code snapshots will be distributed from there until further notice (ie., until I get back write access to python.org!). Changes: * minor tweakage to bdist_wininst.py: please try it out and make sure I didn't make any stupid typos * added C source for Thomas' installer in "misc" -- note that this is *not* yet in CVS, as I was (and am) unsure of the right way to handle DOS text files -- have to check the CVS book tomorrow * added Lyle Johnson's bcppcompiler.py to support Borland C++ Note that bcppcompiler.py doesn't actually work: Lyle reports a very odd problem when spawning the linker. I'm sure he'd gladly welcome debugging help, and I'd really like to see support for Borland's compiler working too. See the comment I added to the source for details. Please, everyone bash this code mercilessly. I'm planning to release Distutils 0.9 tomorrow or Thursday night, so that there's a real release out there a few days before Guido release Python 1.6b1 -- that way, if any real bone-headed mistakes have slipped in, we have a chance to fix 'em. Greg -- Greg Ward - maladjusted nerd gward@python.net http://starship.python.net/~gward/ The NSA. We care: we listen to our customers. From ians@amc.com Wed Jun 28 02:51:45 2000 From: ians@amc.com (Ian Searle) Date: Tue, 27 Jun 2000 18:51:45 -0700 Subject: [Distutils] DOS text files and CVS References: Message-ID: <39595A31.6462CA42@amc.com> The best way to check DOS text files into CVS is from a Windows/DOS machine using the CVS client/pserver route. Using this method, the files are stored in canonical format. When someone checks them out from a Unix client they get /n only. And, when someone checks them out from a Windows/DOS client, they get /r/n. And, everyone is happy (well, as much as can be expected :-) If you do a 'cvs add -kb foo.dos-txt' then CVS will treat the file as binary and forego the keyword substitutions and end of line translations. But, folks checking them out will always get the /r/n regardless of platform. -Ian Tim Peters wrote: > > [Greg Ward] > > can anyone enlighten me on the right way to check in DOS text files to a > > CVS repository? > > Aargh, I haven't used CVS in about 6 years ... somehow or other, I believe > you need to convince CVS that it's a binary (not text) file. Then it will > skip line-end conversions. > > not-a-solution-but-maybe-a-clue-ly y'rs - tim > > _______________________________________________ > Distutils-SIG maillist - Distutils-SIG@python.org > http://www.python.org/mailman/listinfo/distutils-sig From gward@python.net Wed Jun 28 03:10:48 2000 From: gward@python.net (Greg Ward) Date: Tue, 27 Jun 2000 22:10:48 -0400 Subject: [Distutils] DOS text files and CVS In-Reply-To: <39595A31.6462CA42@amc.com>; from ians@amc.com on Tue, Jun 27, 2000 at 06:51:45PM -0700 References: <39595A31.6462CA42@amc.com> Message-ID: <20000627221048.E1512@beelzebub> Let's see: three votes for "cvs add -kb", two of whom said they didn't think that was the right way, and the third who hadn't used CVS in 6 years. Two votes for "just check it in, ya coward", one of whom advised me to strip LF's before doing so. And one who told me not to worry about Unix line-endings, because Notepad is the only Windows editor that can't deal with them. Well, guess what folks: Notepad is the only Windows editor I've ever used. D'you wonder why I run screaming in terror? ;-) So I stripped the LF's and just checked the damn things in. Guess I'll find out if I screwed up soon enough. Thanks for your help! escape-meta-alt-control-shift-till-the-day-I-die... Greg (PS. I recently learned that there's an Emacs command -- M-C-% -- that uses all three standard shift keys on a PC keyboard -- awesome! My life is now complete...) -- Greg Ward - Linux geek gward@python.net http://starship.python.net/~gward/ I want you to MEMORIZE the collected poems of EDNA ST VINCENT MILLAY ... BACKWARDS!! From bwarsaw@beopen.com Wed Jun 28 03:25:47 2000 From: bwarsaw@beopen.com (Barry A. Warsaw) Date: Tue, 27 Jun 2000 22:25:47 -0400 (EDT) Subject: [Distutils] Re: [Python-Dev] DOS text files and CVS References: <20000627205843.A1607@beelzebub> Message-ID: <14681.25131.166235.152210@anthem.concentric.net> >>>>> "GW" == Greg Ward writes: GW> can anyone enlighten me on the right way to check in DOS text GW> files to a CVS repository? I have Thomas Heller's C source GW> for his simple graphical installer for Python modules, and it GW> should definitely be in the Distutils CVS tree. But I don't GW> want to check it in if it'll screw up line-endings for anyone. GW> Is there a Right Way to do this? If there's no reason why it /has/ to be DOS text, convert it to Unix line endings first. XEmacs will even do the conversion for you! That is, if the other suggestions people have made don't help. -Barry From calvin@cs.uni-sb.de Wed Jun 28 10:30:29 2000 From: calvin@cs.uni-sb.de (Bastian Kleineidam) Date: Wed, 28 Jun 2000 11:30:29 +0200 (CEST) Subject: [Distutils] Comments on bdist_wininst In-Reply-To: <20000627205419.A1576@beelzebub> Message-ID: >Some thoughts... these are mostly idle speculation, because I really >can't see anything wrong with the code! Hmm, why dont I have my data files in the installer? I can not see them. Is bdist_wininst only for modules because you run the zip tool only in the site-packages dir: changing into 'build/bdist.linux2/wininst/usr/lib/python1.5/site-packages/' zip -rq /home/calvin/projects/linkchecker/linkchecker-1.2.4.win32.zip . Another thing: the "..." directory browse button of the installer does not work for me under Win98 SE2. > * should we change ImportError on zlib to DistutilsPlatformError (or > something) that generates a friendlier error message... or is > this being silly because zlib is absolutely positively always > available for Python on Windows? If it should be there and it is not then this is an ImportError. > * is "foo-1.0.win32.exe" the right filename for the installer? this > is consistent with "dumb" build distributions (simple tarballs and > ZIP files) as well as RPMs, so that's a good enough argument for > me. Its ok. Bastian From hgebel@inet.net Wed Jun 28 12:14:05 2000 From: hgebel@inet.net (Harry Henry Gebel) Date: Wed, 28 Jun 2000 07:14:05 -0400 Subject: [Distutils] Some patches Message-ID: <20000628071405.A13691@inet.net> I have put a few patches up on the SourceForge patch manager. The first patch prunes CVS files and directories from source distributions. (Making a source distribution of the Distutils was failing because it kept putting 'misc/CVS' into MANIFEST. Of course, this wouldn't effect somebody who wasn't using the CVS Distutils.) The second patch fixes a problem that you could not build source distributions for packages that use the old-style way of specifying extensions. The third patch is for the examples directory. It updates the pil and xml setup scripts to use new-style extensions and fixes a bug in the mxDateTime setup script (which uses new-style extensions but did not import the Extension class.) -- Harry Henry Gebel, Senior Developer, Landon House SBS ICQ# 76308382 West Dover Hundred, Delaware From davida@pobox.com Wed Jun 28 02:50:24 2000 From: davida@pobox.com (David Arnold) Date: Wed, 28 Jun 2000 11:50:24 +1000 Subject: [Python-Dev] Re: [Distutils] DOS text files and CVS In-Reply-To: Your message of "Tue, 27 Jun 2000 21:39:31 -0400." Message-ID: <200006280150.LAA17759@xevious.dstc.monash.edu.au> -->"Tim" == Tim Peters writes: Tim> Aargh, I haven't used CVS in about 6 years ... somehow or Tim> other, I believe you need to convince CVS that it's a binary Tim> (not text) file. Then it will skip line-end conversions. cvs add -kb file should work to add a binary file. not sure that this is the best way to deal with DOS files, but it should work ... d _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://www.python.org/mailman/listinfo/python-dev From ians@amc.com Wed Jun 28 02:51:45 2000 From: ians@amc.com (Ian Searle) Date: Tue, 27 Jun 2000 18:51:45 -0700 Subject: [Python-Dev] Re: [Distutils] DOS text files and CVS References: Message-ID: <39595A31.6462CA42@amc.com> The best way to check DOS text files into CVS is from a Windows/DOS machine using the CVS client/pserver route. Using this method, the files are stored in canonical format. When someone checks them out from a Unix client they get /n only. And, when someone checks them out from a Windows/DOS client, they get /r/n. And, everyone is happy (well, as much as can be expected :-) If you do a 'cvs add -kb foo.dos-txt' then CVS will treat the file as binary and forego the keyword substitutions and end of line translations. But, folks checking them out will always get the /r/n regardless of platform. -Ian Tim Peters wrote: > > [Greg Ward] > > can anyone enlighten me on the right way to check in DOS text files to a > > CVS repository? > > Aargh, I haven't used CVS in about 6 years ... somehow or other, I believe > you need to convince CVS that it's a binary (not text) file. Then it will > skip line-end conversions. > > not-a-solution-but-maybe-a-clue-ly y'rs - tim > > _______________________________________________ > Distutils-SIG maillist - Distutils-SIG@python.org > http://www.python.org/mailman/listinfo/distutils-sig _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://www.python.org/mailman/listinfo/python-dev From tpeters@beopen.com Wed Jun 28 02:39:31 2000 From: tpeters@beopen.com (Tim Peters) Date: Tue, 27 Jun 2000 21:39:31 -0400 Subject: [Python-Dev] RE: [Distutils] DOS text files and CVS In-Reply-To: <20000627205843.A1607@beelzebub> Message-ID: [Greg Ward] > can anyone enlighten me on the right way to check in DOS text files to a > CVS repository? Aargh, I haven't used CVS in about 6 years ... somehow or other, I believe you need to convince CVS that it's a binary (not text) file. Then it will skip line-end conversions. not-a-solution-but-maybe-a-clue-ly y'rs - tim _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://www.python.org/mailman/listinfo/python-dev From gward@python.net Wed Jun 28 01:58:43 2000 From: gward@python.net (Greg Ward) Date: Tue, 27 Jun 2000 20:58:43 -0400 Subject: [Distutils] [Python-Dev] DOS text files and CVS Message-ID: <20000627205843.A1607@beelzebub> Hi all -- can anyone enlighten me on the right way to check in DOS text files to a CVS repository? I have Thomas Heller's C source for his simple graphical installer for Python modules, and it should definitely be in the Distutils CVS tree. But I don't want to check it in if it'll screw up line-endings for anyone. Is there a Right Way to do this? Thanks -- Greg -- Greg Ward - Linux nerd gward@python.net http://starship.python.net/~gward/ Just because you're paranoid doesn't mean they *aren't* out to get you. _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://www.python.org/mailman/listinfo/python-dev From gmcm@hypernet.com Wed Jun 28 02:47:30 2000 From: gmcm@hypernet.com (Gordon McMillan) Date: Tue, 27 Jun 2000 21:47:30 -0400 Subject: [Distutils] Re: [Python-Dev] DOS text files and CVS In-Reply-To: <20000627205843.A1607@beelzebub> Message-ID: <1249965584-36289880@hypernet.com> Greg Ward asks: > can anyone enlighten me on the right way to check in DOS text > files to a CVS repository? I have Thomas Heller's C source for > his simple graphical installer for Python modules, and it should > definitely be in the Distutils CVS tree. But I don't want to > check it in if it'll screw up line-endings for anyone. Is there > a Right Way to do this? Well, if you checked it in from a Windows box, CVS would translate line endings to native, then a Windows checkout would translate back to Windows endings. So assuming you don't want to get your fingers dirty, give it *n*x line endings and check it in. CVS does understand text, you know :-). (And about the only Windows editor that barfs on *n*x line endings is Notepad.) - Gordon _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://www.python.org/mailman/listinfo/python-dev From bwarsaw@beopen.com Wed Jun 28 03:25:47 2000 From: bwarsaw@beopen.com (Barry A. Warsaw) Date: Tue, 27 Jun 2000 22:25:47 -0400 (EDT) Subject: [Distutils] Re: [Python-Dev] DOS text files and CVS References: <20000627205843.A1607@beelzebub> Message-ID: <14681.25131.166235.152210@anthem.concentric.net> >>>>> "GW" == Greg Ward writes: GW> can anyone enlighten me on the right way to check in DOS text GW> files to a CVS repository? I have Thomas Heller's C source GW> for his simple graphical installer for Python modules, and it GW> should definitely be in the Distutils CVS tree. But I don't GW> want to check it in if it'll screw up line-endings for anyone. GW> Is there a Right Way to do this? If there's no reason why it /has/ to be DOS text, convert it to Unix line endings first. XEmacs will even do the conversion for you! That is, if the other suggestions people have made don't help. -Barry _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://www.python.org/mailman/listinfo/python-dev From gward@python.net Thu Jun 29 02:19:28 2000 From: gward@python.net (Greg Ward) Date: Wed, 28 Jun 2000 21:19:28 -0400 Subject: [Distutils] Comments on bdist_wininst In-Reply-To: ; from calvin@cs.uni-sb.de on Wed, Jun 28, 2000 at 11:30:29AM +0200 References: <20000627205419.A1576@beelzebub> Message-ID: <20000628211928.A906@beelzebub> On 28 June 2000, Bastian Kleineidam said: > >Some thoughts... these are mostly idle speculation, because I really > >can't see anything wrong with the code! > Hmm, why dont I have my data files in the installer? I can not see them. > Is bdist_wininst only for modules because you run the zip tool only in the > site-packages dir: > changing into > 'build/bdist.linux2/wininst/usr/lib/python1.5/site-packages/' > zip -rq /home/calvin/projects/linkchecker/linkchecker-1.2.4.win32.zip . I think that's a known bug -- there're some comments in the code about it: # XXX hack! Our archive MUST be relative to sys.prefix # XXX What about .install_data, .install_scripts, ...? # [Perhaps require that all installation dirs be under sys.prefix # on Windows? this will be acceptable until we start dealing # with Python applications, at which point we should zip up # the application directory -- and again everything can be # under one dir --GPW] (The first two are Thomas', the third is mine.) > Another thing: the "..." directory browse button of the installer does not > work for me under Win98 SE2. Hmm, I'll have to let the Windows experts deal with that. Thomas' C code (and other project files) is now in CVS, so you can have at it. Greg -- Greg Ward - nerd gward@python.net http://starship.python.net/~gward/ It has just been discovered that research causes cancer in rats. From gward@python.net Thu Jun 29 03:24:06 2000 From: gward@python.net (Greg Ward) Date: Wed, 28 Jun 2000 22:24:06 -0400 Subject: [Distutils] Some patches In-Reply-To: <20000628071405.A13691@inet.net>; from hgebel@inet.net on Wed, Jun 28, 2000 at 07:14:05AM -0400 References: <20000628071405.A13691@inet.net> Message-ID: <20000628222406.B906@beelzebub> On 28 June 2000, Harry Henry Gebel said: > I have put a few patches up on the SourceForge patch manager. Cool! This is slightly more awkward than email, but the tracking/accountability is nice. > The first patch prunes CVS files and directories from source distributions. > (Making a source distribution of the Distutils was failing because it kept > putting 'misc/CVS' into MANIFEST. Of course, this wouldn't effect somebody > who wasn't using the CVS Distutils.) Oops. There were actually several other bugs lurking in that module, and I fixed the CVS problem in a nicer way. So don't feel bad that I rejected your patch. ;-) See the checkin message for details. Thanks for prodding me into finding those other, long-hidden bugs! > The second patch fixes a problem that you could not build source > distributions for packages that use the old-style way of specifying extensions. Also fixed in a different (shorter and more general) way. Thanks for spotting the bug! > The third patch is for the examples directory. It updates the pil and xml > setup scripts to use new-style extensions and fixes a bug in the mxDateTime > setup script (which uses new-style extensions but did not import the > Extension class.) Great, checked it in verbatim. Thanks! Greg -- Greg Ward - maladjusted computer geek gward@python.net http://starship.python.net/~gward/ Disclaimer: All rights reserved. Void where prohibited. Limit 1 per customer. From gward@python.net Thu Jun 29 03:50:01 2000 From: gward@python.net (Greg Ward) Date: Wed, 28 Jun 2000 22:50:01 -0400 Subject: [Distutils] New code snapshot Message-ID: <20000628225000.A1269@beelzebub> Title says it all. Fixes the bugs Harry spotted. The URL is http://starship.python.net/~gward/python/distutils.html OK, 0.9 release tomorrow night fer shure... (famous last words...) Greg -- Greg Ward - geek-on-the-loose gward@python.net http://starship.python.net/~gward/ Could I have a drug overdose? From R.Liebscher@gmx.de Thu Jun 29 17:39:02 2000 From: R.Liebscher@gmx.de (Rene Liebscher) Date: Thu, 29 Jun 2000 18:39:02 +0200 Subject: [Distutils] Re: CygwinCCompiler, msvc hack, BCPPCompiler References: <20000624123159.A2203@beelzebub> Message-ID: <395B7BA6.F65C24FA@gmx.de> This is a multi-part message in MIME format. --------------CEAF3E0844BC03C09B03A5C1 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit ---- CygwinCCompiler ------------ OK, it should now be better to read. I also included your other changes (set_executables, build_temp.) ----- msvc hack ----------- I also had a look at this msvc hack in build_ext. I think it is now possible to get rid of it. It does several things which could be done in an other way or shouldn't be done at all. First, it tries to find a def-file in the source directory if none is given. I think one should specify this explicitely, who knows if it is really the right file and moreover it overwrites any export_symbols given to Extension(). Then it uses the module_name to create an export directive for the procedure 'init{modulename}'. It is possible to extract this name from the output filename (see (bcpp|cygwin)compiler.py ) I think this export parameter should be only used if neither a def file nor a list of symbols is given. (Then you could use your compiler classes also for non python dll's by specifying [] as export_symbols list.) And finally it uses the build_temp path for it implib directive. We have now this new extra parameter to link_shared_library, so this is also not a problem. When I looked at the code of build_ext I found you are not using export_symbols as parameter to link_shared_object. Also you are not using any of this export_* values from the Extension class. This should be changed. But there is one point which is not clear. There is no parameter at link_shared_object for export_symbols_file. Either we add this or we change the semantics of the existing export_symbols a bit. * export_symbols == None : no export symbols given => add init{module} * type(export_symbols) == ListType : export all symbols from this list * type(export_symbols) == StringType : take this as a filename of a def file ------ bcppcompiler ------------- Which version of Borland C you need to use it? I tried BC5. It doesn't have a linker named ilink32 (?) and it doesn't accept some of your parameters /q for bcc32 and /Gn /q for the linker (tlink32). Also it is using mypylib, which probably the stub library for python15.dll . Is this library somewhere to download or how can I create it? My BC version doesn't include files if they are in the source directory ( src/foo.c includes "foo.h" which is really src/foo.h ) so I had to specify this as an include_dir (-Isrc). If all versions of BC do the same, the directories of the source files should append to include_dir in the bcppcompiler class. Kind regards Rene Liebscher --------------CEAF3E0844BC03C09B03A5C1 Content-Type: text/plain; charset=us-ascii; name="cygwinccompiler.py" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="cygwinccompiler.py" """distutils.cygwinccompiler Contains the CygwinCCompiler class, a subclass of UnixCCompiler that handles the Gnu Win32 C compiler. It also contains the Mingw32CCompiler class which handles the mingw32 compiler (same as cygwin in no-cygwin mode.) """ # created 2000/05/05, Rene Liebscher __revision__ = "$Id: cygwinccompiler.py,v 1.1 2000/06/21 03:33:03 gward Exp $" import os,sys,string from distutils import sysconfig from distutils.unixccompiler import UnixCCompiler # Because these compilers aren't configured in Python's config.h file by default # we should at least warn the user if he is using a unmodified version. def check_config_h(): """ checks, if the gcc-compiler is mentioned in config.h if it is not, compiling probably doesn't work """ from distutils import sysconfig import string,sys try: # It would probably better to read single lines to search. # But we do this only once, and it is fast enough f=open(sysconfig.get_config_h_filename()) s=f.read() f.close() try: # is somewhere a #ifdef __GNUC__ or something similar string.index(s,"__GNUC__") except ValueError: sys.stderr.write ("warning: "+ "Python's config.h doesn't seem to support your compiler.\n") except IOError: # if we can't read this file, we cannot say it is wrong # the compiler will complain later about this file as missing pass # This is called when the module is imported, so we make this check only once check_config_h() # XXX Things not currently handled: # * see UnixCCompiler class CygwinCCompiler (UnixCCompiler): compiler_type = 'cygwin' def __init__ (self, verbose=0, dry_run=0, force=0): UnixCCompiler.__init__ (self, verbose, dry_run, force) # our compiler uses other names # dllwrap: specification of entry point is not necessary self.set_executables(compiler='gcc -O -Wall', compiler_so='gcc -O -Wall', linker_exe='gcc', linker_so='dllwrap --target=i386-cygwin32') # cygwin and mingw32 need different sets of libraries self.dll_libraries=[ # cygwin shouldn't need msvcrt, # but without the dll's will crash # ( gcc version 2.91.57 ) # perhaps something about initialization # mingw32 needs it in all cases "msvcrt" ] # __init__ () def link_shared_object (self, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None): if libraries == None: libraries = [] # additional libraries # the python library is always needed on Windows # we need the python version without the dot, eg. '15' libraries = libraries + [ "python%d%d" % ( sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff) ] + self.dll_libraries # name of extension if not debug: ext_name = os.path.basename(output_filename)[:-len(".pyd")] else: ext_name = os.path.basename(output_filename)[:-len("_d.pyd")] def_file = os.path.join(build_temp, ext_name + ".def") #exp_file = os.path.join(build_temp, ext_name + ".exp") #lib_file = os.path.join(build_temp, 'lib' + ext_name + ".a") # Make .def file # (It would probably better to check if we really need this, # but for this we had to insert some unchanged parts of # UnixCCompiler, and this is not what we want.) f = open(def_file,"w") f.write("EXPORTS\n") # intro if export_symbols == None: # export a function "init" + ext_name f.write("init" + ext_name + "\n") else: # if there are more symbols to export write them into f for sym in export_symbols: f.write(sym+"\n") f.close() if extra_preargs == None: extra_preargs = [] extra_preargs = extra_preargs + [ #"--verbose", #"--output-exp",exp_file, #"--output-lib",lib_file, "--def",def_file ] # who wants symbols and a many times larger output file # should explicitely switch the debug mode on # otherwise we let dllwrap strip the output file # (On my machine unstripped_file = stripped_file + 254KB # 10KB < stripped_file < ??100KB ) if not debug: extra_preargs = extra_preargs + ["-s"] UnixCCompiler.link_shared_object(self, objects, output_filename, output_dir, libraries, library_dirs, runtime_library_dirs, None, # export_symbols, we do this with our def-file debug, extra_preargs, extra_postargs, build_temp) # link_shared_object () # class CygwinCCompiler # the same as cygwin plus some additional parameters class Mingw32CCompiler (CygwinCCompiler): compiler_type = 'mingw32' def __init__ (self, verbose=0, dry_run=0, force=0): CygwinCCompiler.__init__ (self, verbose, dry_run, force) self.set_executables(compiler='gcc -mno-cygwin -O -Wall', compiler_so='gcc -mno-cygwin -O -Wall', linker_exe='gcc -mno-cygwin', linker_so='dllwrap' + ' --target=i386-mingw32' + ' --entry _DllMain@12') # mingw32 doesn't really need 'target' and cygwin too (it seems, # it is enough to specify a different entry point) # no additional libraries need # (only msvcrt, which is already added by CygwinCCompiler) # __init__ () # class Mingw32CCompiler --------------CEAF3E0844BC03C09B03A5C1-- From fdrake@beopen.com Thu Jun 29 17:56:43 2000 From: fdrake@beopen.com (Fred L. Drake, Jr.) Date: Thu, 29 Jun 2000 12:56:43 -0400 (EDT) Subject: [Distutils] winreg module changes Message-ID: <14683.32715.992699.157514@cj42289-a.reston1.va.home.com> Greg, Windows users, etc.: I just checked in the changes for winreg so that an object-oriented interface is presented to the user. This affects the distutils on Windows; if someone who knows about this stuff can update the winreg use, it would be really good to get that in tonight or first thing tomorrow morning! -Fred -- Fred L. Drake, Jr. BeOpen PythonLabs Team Member From nhv@cape.com Thu Jun 29 18:11:14 2000 From: nhv@cape.com (Norman Vine) Date: Thu, 29 Jun 2000 13:11:14 -0400 Subject: [Distutils] Re: CygwinCCompiler, msvc hack, BCPPCompiler In-Reply-To: <395B7BA6.F65C24FA@gmx.de> Message-ID: <000401bfe1ed$0d778a60$2937ba8c@nhv> Rene Liebscher writes: > >---- CygwinCCompiler ------------ > >OK, it should now be better to read. I also included your other changes >(set_executables, build_temp.) > I just noticed that cygwinccompiler has been added to distutils :-)) One minor nitpick from cygwinccompiler.py # Because these compilers aren't configured in Python's config.h file by default # we should at least warn the user if he is using a unmodified version. def check_config_h(): """ checks, if the gcc-compiler is mentioned in config.h if it is not, compiling probably doesn't work """ FWIW I compile Python with Cygwin routinely and I do not have "__GNUC__" anywhere in my config.h file however given NHV:/f/jnk2> python Python 1.6a2 (#12, Jun 22 2000, 08:18:57) [GCC 2.95.2 19991024 (release-2)] on cygwin_98-4.101 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam Copyright 1995-2000 Corporation for National Research Initiatives (CNRI) >>> import sys >>> sys.version '1.6a2 (#12, Jun 22 2000, 08:18:57) [GCC 2.95.2 19991024 (release-2)]' perhaps checking for "GCC" in sys.version will do what we want :-)) Norman Vine From gward@python.net Thu Jun 29 23:30:46 2000 From: gward@python.net (Greg Ward) Date: Thu, 29 Jun 2000 18:30:46 -0400 Subject: [Distutils] winreg module changes In-Reply-To: <14683.32715.992699.157514@cj42289-a.reston1.va.home.com>; from fdrake@beopen.com on Thu, Jun 29, 2000 at 12:56:43PM -0400 References: <14683.32715.992699.157514@cj42289-a.reston1.va.home.com> Message-ID: <20000629183046.A682@beelzebub> On 29 June 2000, Fred L. Drake, Jr. said: > I just checked in the changes for winreg so that an object-oriented > interface is presented to the user. > This affects the distutils on Windows; if someone who knows about > this stuff can update the winreg use, it would be really good to get > that in tonight or first thing tomorrow morning! Yipes! Is it enough to "import _winreg" instead of "winreg" and continue to use the low-level interface? Or was it not implemented like that in the end? Greg -- Greg Ward - nerd gward@python.net http://starship.python.net/~gward/ Paranoia is simply an optimistic outlook on life. From fdrake@beopen.com Thu Jun 29 23:54:06 2000 From: fdrake@beopen.com (Fred L. Drake, Jr.) Date: Thu, 29 Jun 2000 18:54:06 -0400 (EDT) Subject: [Distutils] winreg module changes In-Reply-To: <20000629183046.A682@beelzebub> References: <14683.32715.992699.157514@cj42289-a.reston1.va.home.com> <20000629183046.A682@beelzebub> Message-ID: <14683.54158.770418.789248@cj42289-a.reston1.va.home.com> Greg Ward writes: > Yipes! Is it enough to "import _winreg" instead of "winreg" and > continue to use the low-level interface? Or was it not implemented like > that in the end? _winreg is exactly yesterday's (even this morning's) winreg, aside from the name. It passes the old regression test, so it should work fine for distutils. Is there a reason not to switch to the new winreg, or is just a matter of time availability? -Fred -- Fred L. Drake, Jr. BeOpen PythonLabs Team Member From gward@python.net Fri Jun 30 00:01:21 2000 From: gward@python.net (Greg Ward) Date: Thu, 29 Jun 2000 19:01:21 -0400 Subject: [Distutils] winreg module changes In-Reply-To: <14683.54158.770418.789248@cj42289-a.reston1.va.home.com>; from fdrake@beopen.com on Thu, Jun 29, 2000 at 06:54:06PM -0400 References: <14683.32715.992699.157514@cj42289-a.reston1.va.home.com> <20000629183046.A682@beelzebub> <14683.54158.770418.789248@cj42289-a.reston1.va.home.com> Message-ID: <20000629190121.B682@beelzebub> On 29 June 2000, Fred L. Drake, Jr. said: > _winreg is exactly yesterday's (even this morning's) winreg, aside > from the name. It passes the old regression test, so it should work > fine for distutils. Good. > Is there a reason not to switch to the new winreg, or is just a > matter of time availability? Two reasons: 1) time availability, 2) I don't know the new API and can't test it in any case, and 3) -- no, THREE reasons! -- msvccompiler.py can either use the API provided by win32api and win32con or that provided by the-module-formerly-known-as-winreg, because they are quite similar interfaces. If we switch to the (presumably nice and OO) interface provided by winreg (not _winreg!), then compatibility with win32api/win32con for Python 1.5.2 would go away. No wait, FOUR reasons: it ain't broken. Greg -- Greg Ward - Unix nerd gward@python.net http://starship.python.net/~gward/ No problem is so formidable that you can't just walk away from it. From gward@python.net Fri Jun 30 00:13:45 2000 From: gward@python.net (Greg Ward) Date: Thu, 29 Jun 2000 19:13:45 -0400 Subject: [Distutils] Re: CygwinCCompiler, msvc hack, BCPPCompiler In-Reply-To: <395B7BA6.F65C24FA@gmx.de>; from R.Liebscher@gmx.de on Thu, Jun 29, 2000 at 06:39:02PM +0200 References: <20000624123159.A2203@beelzebub> <395B7BA6.F65C24FA@gmx.de> Message-ID: <20000629191345.C682@beelzebub> On 29 June 2000, Rene Liebscher said: > ---- CygwinCCompiler ------------ > > OK, it should now be better to read. I also included your other changes > (set_executables, build_temp.) Looking better. Still some problems, which I will address below. > ----- msvc hack ----------- > > I also had a look at this msvc hack in build_ext. I think it is now > possible > to get rid of it. It does several things which could be done in an other > way or shouldn't be done at all. > > First, it tries to find a def-file in the source directory if > none is given. I think one should specify this explicitely, who > knows if it is really the right file and moreover it overwrites > any export_symbols given to Extension(). I have never been fond of this bit of code. I have always considered it unnecessary, given that 1) there is always exactly one symbol to be exported from a Python extension, and it is trivially derived from the extension name, and 2) we can generate an "/export:" option for that exported file. Somehow Thomas Heller (I think I can blame him ;-) talked me into leaving it in. But Thomas is on vacation now. (Hee hee hee.) I think I'll take a page from Guido's book and remove what I consider to be a broken feature. If nobody howls, it stays out. *poof!* it's gone. > Then it uses the module_name to create an export directive > for the procedure 'init{modulename}'. It is possible to extract > this name from the output filename (see (bcpp|cygwin)compiler.py ) > I think this export parameter should be only used if neither a def > file nor a list of symbols is given. (Then you could use your compiler > classes also for non python dll's by specifying [] as export_symbols > list.) No: that would involve putting knowledge about Python extensions into a CCompiler class, which I strive to avoid. (Went to a lot of trouble this weekend to get knowledge of the sysconfig module out of UnixCCompiler, and I don't want to have to go through that again!) It is acceptable, but definitely to be avoided, to add platform- and compiler-specific hacks to build_ext.py. But I want to keep Python-extension-building hacks out of the CCompiler classes, because they can and should be useful for more than just building Python extensions. This, of course, is the remaining problem (that I see) with cygwinccompiler.py: it figures out symbols-to-export by looking at the output filename, which is flagrantly wrong (ie. totally specific to building Python extensions). *Please* fix this! > When I looked at the code of build_ext I found you are not using > export_symbols as parameter to link_shared_object. Also you are not > using any of this export_* values from the Extension class. > This should be changed. But there is one point which is not clear. > There is no parameter at link_shared_object for export_symbols_file. > Either we add this or we change the semantics of the existing > export_symbols a bit. Yeah, those features were added so we could reduce (if not completely eliminate) the MSVC-specific hackery in build_ext.py. Looks like I never finished the job; kinda hard for me to do since I can't test it. I'd love to see a patch that does this, thought! > And finally it uses the build_temp path for it implib directive. > We have now this new extra parameter to link_shared_library, so > this is also not a problem. Hey, good point. Can you submit a patch for that too? Greg -- Greg Ward - programmer-at-big gward@python.net http://starship.python.net/~gward/ It has just been discovered that research causes cancer in rats. From gward@python.net Fri Jun 30 00:16:50 2000 From: gward@python.net (Greg Ward) Date: Thu, 29 Jun 2000 19:16:50 -0400 Subject: [Distutils] Re: CygwinCCompiler, msvc hack, BCPPCompiler In-Reply-To: <000401bfe1ed$0d778a60$2937ba8c@nhv>; from nhv@cape.com on Thu, Jun 29, 2000 at 01:11:14PM -0400 References: <395B7BA6.F65C24FA@gmx.de> <000401bfe1ed$0d778a60$2937ba8c@nhv> Message-ID: <20000629191650.D682@beelzebub> On 29 June 2000, Norman Vine said: > FWIW > I compile Python with Cygwin routinely and I do not have "__GNUC__" > anywhere in my config.h file [...] > >>> sys.version > '1.6a2 (#12, Jun 22 2000, 08:18:57) [GCC 2.95.2 19991024 (release-2)]' > > perhaps checking for "GCC" in sys.version will do what we want :-)) No; as I understand it, the CygwinCCompiler class will allow you to build extensions using GCC (Cygwin or MingW32!) with the stock Python binary, as long as you have a libpython.a around. (It also requires changes to Python's config.h, but I believe Fred checked those in a few days ago.) This is a big win: let Guido's employer shell out for MSVC++, but you can use a free compiler to build extensions for Windows without having to build Python yourself. Greg -- Greg Ward - geek-on-the-loose gward@python.net http://starship.python.net/~gward/ A closed mouth gathers no foot. From fdrake@beopen.com Fri Jun 30 00:22:19 2000 From: fdrake@beopen.com (Fred L. Drake, Jr.) Date: Thu, 29 Jun 2000 19:22:19 -0400 (EDT) Subject: [Distutils] winreg module changes In-Reply-To: <20000629190121.B682@beelzebub> References: <14683.32715.992699.157514@cj42289-a.reston1.va.home.com> <20000629183046.A682@beelzebub> <14683.54158.770418.789248@cj42289-a.reston1.va.home.com> <20000629190121.B682@beelzebub> Message-ID: <14683.55851.749001.729710@cj42289-a.reston1.va.home.com> Greg Ward writes: > Two reasons: 1) time availability, 2) I don't know the new API and can't > test it in any case, and 3) -- no, THREE reasons! -- msvccompiler.py can I sent the note to the list so that people who can would be aware of it and could make the changes -- I really didn't expect you to make the changes. ;) > either use the API provided by win32api and win32con or that provided by > the-module-formerly-known-as-winreg, because they are quite similar > interfaces. If we switch to the (presumably nice and OO) interface > provided by winreg (not _winreg!), then compatibility with > win32api/win32con for Python 1.5.2 would go away. This is a more substantial reason. > No wait, FOUR reasons: it ain't broken. Counter: The old winreg has never been part of a stable release. -Fred -- Fred L. Drake, Jr. BeOpen PythonLabs Team Member From gward@python.net Fri Jun 30 00:47:01 2000 From: gward@python.net (Greg Ward) Date: Thu, 29 Jun 2000 19:47:01 -0400 Subject: [Distutils] winreg module changes In-Reply-To: <14683.55851.749001.729710@cj42289-a.reston1.va.home.com>; from fdrake@beopen.com on Thu, Jun 29, 2000 at 07:22:19PM -0400 References: <14683.32715.992699.157514@cj42289-a.reston1.va.home.com> <20000629183046.A682@beelzebub> <14683.54158.770418.789248@cj42289-a.reston1.va.home.com> <20000629190121.B682@beelzebub> <14683.55851.749001.729710@cj42289-a.reston1.va.home.com> Message-ID: <20000629194701.E682@beelzebub> On 29 June 2000, Fred L. Drake, Jr. said: > > No wait, FOUR reasons: it ain't broken. > > Counter: The old winreg has never been part of a stable release. Then I will remove support for it *after* the next Python release, with winreg and _winreg. Greg -- Greg Ward - Linux weenie gward@python.net http://starship.python.net/~gward/ Very few profundities can be expressed in less than 80 characters. From gward@python.net Fri Jun 30 00:53:26 2000 From: gward@python.net (Greg Ward) Date: Thu, 29 Jun 2000 19:53:26 -0400 Subject: [Distutils] One last code snapshot... Message-ID: <20000629195326.F682@beelzebub> ...before I throw together Distutils 0.9. I expect the code will be identical, unless I find bugs in the process of putting 0.9 together. So this is really a formality. Still, give it a pounding -- I don't imagine 0.9 will be really out for several hours. Greg PS. http://starship.python.net/~gward/python/distutils.html -- Greg Ward - Unix bigot gward@python.net http://starship.python.net/~gward/ I'd like some JUNK FOOD ... and then I want to be ALONE -- From gward@python.net Fri Jun 30 05:34:15 2000 From: gward@python.net (Greg Ward) Date: Fri, 30 Jun 2000 00:34:15 -0400 Subject: [Distutils] ANNOUNCE: Distutils 0.9 Message-ID: <20000630003415.A2365@beelzebub> Python Distribution Utilities release 0.9 June 29, 2000 The Python Distribution Utilities, or Distutils for short, are a collection of modules that aid in the development, distribution, and installation of Python modules. (It is intended that ultimately the Distutils will grow up into a system for distributing and installing whole Python applications, but for now their scope is limited to module distributions.) The Distutils are a standard part of Python 2.0; if you are running 2.0 (or one of the 1.6 alpha releases that preceded it), you don't need to install the Distutils separately. This release is primarily so that you can add the Distutils to a Python 1.5.2 installation -- you will then be able to install modules that require the Distutils, or use the Distutils to distribute your own modules. More information is available at the Distutils web page: http://www.python.org/sigs/distutils-sig/ and in the README.txt included in the Distutils source distribution. You can download the Distutils from http://www.python.org/sigs/distutils-sig/download.html Trivial patches can be sent to me (Greg Ward) at gward@python.net. Larger patches should be discussed on the Distutils mailing list: distutils-sig@python.org. From gward@python.net Fri Jun 30 05:39:29 2000 From: gward@python.net (Greg Ward) Date: Fri, 30 Jun 2000 00:39:29 -0400 Subject: [Distutils] Distutils 0.9 Message-ID: <20000630003929.G682@beelzebub> ...just a note of self-congratulatory gloating that I didn't put in the official announcement: the Distutils 0.9 release is available as: * source tarball * source ZIP file * source RPM * RPM * Windows installer ... all of them generated by the Distutils in three easy commands. Probably could have done it with one command, but I didn't want to push my luck. Wow-ee! That is, to be blunt, TOTALLY ****ING COOL!! Couldn't have done it without ya, folks. This thing is working like a *charm*. Special thanks to Harry Gebel and Thomas Heller, who actually brought it all together with the RPM and Windows installer support. Now, I will sleep soundly, put in one perfunctory day of work, and then completely forget about computers for two whole days... ahhhh... Greg -- Greg Ward - Linux geek gward@python.net http://starship.python.net/~gward/ I had pancake makeup for brunch! From fdrake@beopen.com Fri Jun 30 07:18:09 2000 From: fdrake@beopen.com (Fred L. Drake, Jr.) Date: Fri, 30 Jun 2000 02:18:09 -0400 (EDT) Subject: [Distutils] Heads up! Message-ID: <14684.15265.67298.3426@cj42289-a.reston1.va.home.com> I said: > I'll try to get this deal with tonight, but it may well be tomorrow > morning before I can get to it all. :( Greg Ward replied: > Well, I took a chance and sent the announcement out... in just an hour > or two, people will be waking up in Europe, eagerly banging on > python.org, wondering where Distutils 0.9 is... ;-) Ok, everyone, heads up: I didn't get this done, so it's not there yet! Greg has sent specific information I need to get this updated on python.org, but I'm too tired to follow it. I'll do this first thing in the morning. Sorry! This is my fault, not Greg's! -Fred -- Fred L. Drake, Jr. BeOpen PythonLabs Team Member From jerome@IDEALX.com Fri Jun 30 08:13:48 2000 From: jerome@IDEALX.com (Jérôme Marant) Date: 30 Jun 2000 09:13:48 +0200 Subject: [Distutils] ANNOUNCE: Distutils 0.9 In-Reply-To: "Greg Ward"'s message of "Fri, 30 Jun 2000 00:34:15 -0400" References: <20000630003415.A2365@beelzebub> Message-ID: <648zvnod3n.fsf@amboise.ird.idealx.com> "Greg Ward" writes: =20 > The Distutils are a standard part of Python 2.0; if you are running 2= .0 > (or one of the 1.6 alpha releases that preceded it), you don't need to Sorry my question is out of topic, but I've never heard of a 2.0 vers= ion of Python, but a 1.6 version. Has the devel team decided to call it 2.0 rather than 1.6 ? --=20 J=E9r=F4me Marant ----------------------------------------------------------- | IDEALX - Open Source Engineering / Ing=E9nierie Open Source | | http://IDEALX.com | ----------------------------------------------------------- From gregor@hoffleit.de Fri Jun 30 10:42:27 2000 From: gregor@hoffleit.de (Gregor Hoffleit) Date: Fri, 30 Jun 2000 11:42:27 +0200 Subject: [Distutils] ANNOUNCE: Distutils 0.9 In-Reply-To: <20000630003415.A2365@beelzebub>; from gward@python.net on Fri, Jun 30, 2000 at 12:34:15AM -0400 References: <20000630003415.A2365@beelzebub> Message-ID: <20000630114227.A14603@53b.hoffleit.de> Sorry, but 0.9 is not there... Gregor On Fri, Jun 30, 2000 at 12:34:15AM -0400, Greg Ward wrote: > You can download the Distutils from > > http://www.python.org/sigs/distutils-sig/download.html From fdrake@beopen.com Fri Jun 30 15:19:04 2000 From: fdrake@beopen.com (Fred L. Drake, Jr.) Date: Fri, 30 Jun 2000 10:19:04 -0400 (EDT) Subject: [Distutils] ANNOUNCE: Distutils 0.9 In-Reply-To: <20000630114227.A14603@53b.hoffleit.de> References: <20000630003415.A2365@beelzebub> <20000630114227.A14603@53b.hoffleit.de> Message-ID: <14684.44120.981666.853555@cj42289-a.reston1.va.home.com> Gregor Hoffleit writes: > Sorry, but 0.9 is not there... Gregor, This was my fault; Greg sent his material to be added to the Web site, but I was too tired to follow through after a long day of checking in patches. ;) Everything should be in place now. -Fred -- Fred L. Drake, Jr. BeOpen PythonLabs Team Member From R.Liebscher@gmx.de Fri Jun 30 16:08:50 2000 From: R.Liebscher@gmx.de (Rene Liebscher) Date: Fri, 30 Jun 2000 17:08:50 +0200 Subject: [Distutils] Re: CygwinCCompiler, msvc hack, BCPPCompiler References: <395B7BA6.F65C24FA@gmx.de> <000401bfe1ed$0d778a60$2937ba8c@nhv> <20000629191650.D682@beelzebub> Message-ID: <395CB802.7CE487C@gmx.de> Greg Ward wrote: > > On 29 June 2000, Norman Vine said: > > FWIW > > I compile Python with Cygwin routinely and I do not have "__GNUC__" > > anywhere in my config.h file > [...] > > >>> sys.version > > '1.6a2 (#12, Jun 22 2000, 08:18:57) [GCC 2.95.2 19991024 (release-2)]' > > > > perhaps checking for "GCC" in sys.version will do what we want :-)) > > No; as I understand it, the CygwinCCompiler class will allow you to > build extensions using GCC (Cygwin or MingW32!) with the stock Python > binary, as long as you have a libpython.a around. (It also requires > changes to Python's config.h, but I believe Fred checked those in a few > days ago.) > You are both right. I think Norman compiles it in the UNIX way using configure. In this case it builds its own config.h and this is definitively able to be used for extension building with GNU C. But if you compile it with MSVC or use the downloaded binary version, then you have this special PC config.h file. And in this file you need a special section for GNU C. (probably using #ifdef __GNUC__ somewhere.) So I will change my code, if it finds GCC in sys.version, then it doesn't need to check the config.h file. (Norman, have you already tried to build an extension? It seems you are only one out there who is also using GNU C. I'm using currently the mingw32 port, so I need someone which uses an up-to-date Cygwin. My Cygwin was an old version (2.91.67)) Kind regards Rene Liebscher