Hi again --
[cc'd to Paul Dubois: you said you weren't following the distutils sig
anymore, but this directly concerns NumPy and I'd like to get your
input!]
here's that sample setup.py for NumPy. See below for discussion (and
questions!).
------------------------------------------------------------------------
#!/usr/bin/env python
# Setup script example for building the Numeric extension to Python.
# This does sucessfully compile all the .dlls. Nothing happens
# with the .py files currently.
# Move this file to the Numerical directory of the LLNL numpy
# distribution and run as:
# python numpysetup.py --verbose build_ext
#
# created 1999/08 Perry Stoll
__rcsid__ = "$Id: numpysetup.py,v 1.1 1999/09/12 20:42:48 gward Exp $"
from distutils.core import setup
setup (name = "numerical",
version = "0.01",
description = "Numerical Extension to Python",
url = "http://www.python.org/sigs/matrix-sig/",
ext_modules = [ ( '_numpy', { 'sources' : [ 'Src/_numpymodule.c',
'Src/arrayobject.c',
'Src/ufuncobject.c'
],
'include_dirs' : ['./Include'],
'def_file' : 'Src/numpy.def' }
),
( 'multiarray', { 'sources' : ['Src/multiarraymodule.c'],
'include_dirs' : ['./Include'],
'def_file': 'Src/multiarray.def'
}
),
( 'umath', { 'sources': ['Src/umathmodule.c'],
'include_dirs' : ['./Include'],
'def_file' : 'Src/umath.def' }
),
( 'fftpack', { 'sources': ['Src/fftpackmodule.c', 'Src/fftpack.c'],
'include_dirs' : ['./Include'],
'def_file' : 'Src/fftpack.def' }
),
( 'lapack_lite', { 'sources' : [ 'Src/lapack_litemodule.c',
'Src/dlapack_lite.c',
'Src/zlapack_lite.c',
'Src/blas_lite.c',
'Src/f2c_lite.c'
],
'include_dirs' : ['./Include'],
'def_file' : 'Src/lapack_lite.def' }
),
( 'ranlib', { 'sources': ['Src/ranlibmodule.c',
'Src/ranlib.c',
'Src/com.c',
'Src/linpack.c',
],
'include_dirs' : ['./Include'],
'def_file' : 'Src/ranlib.def' }
),
]
)
------------------------------------------------------------------------
First, what d'you think? Too clunky and verbose? Too much information
for each extension? I kind of think so, but I'm not sure how to reduce
it elegantly. Right now, the internal data structures needed to compile
a module are pretty obviously exposed: is this a good thing? Or should
there be some more compact form for setup.py that will be expanded later
into the full glory we see above?
I've already made one small step towards reducing the amount of cruft by
factoring 'include_dirs' out and supplying it directly as a parameter to
'setup()'. (But that needs code not in the CVS archive yet, so I've
left the sample setup.py the same for now.)
The next thing I'd like to do is get that damn "def_file" out of there.
To support it in MSVCCompiler, there's already an ugly hack that
unnecessarily affects both the UnixCCompiler and CCompiler classes, and
I want to get rid of that. (I refer to passing the 'build_info'
dictionary into the compiler classes, if you're familiar with the code
-- that dictionary is part of the Distutils extension-building system,
and should not propagate into the more general compiler classes.)
But I don't want to give these weird "def file" things standing on the
order of source files, object files, libraries, etc., because they seem
to me to be a bizarre artifact of one particular compiler, rather than
something present in a wide range of C/C++ compilers.
Based on the NumPy model, it seems like there's a not-too-kludgy way to
handle this problem. Namely:
if building extension "foo":
if file "foo.def" found in same directory as "foo.c"
add "/def:foo.def" to MSVC command line
this will of course require some platform-specific code in the build_ext
command class, but I figured that was coming eventually, so why put it
off? ;-)
To make this hack work with NumPy, one change would be necessary: rename
Src/numpy.def to Src/_numpy.def to match Src/_numpy.c, which implements
the _numpy module. Would this be too much to ask of NumPy? (Paul?)
What about other module distributions that support MSVC++ and thus ship
with "def" files? Could they be made to accomodate this scheme?
Thanks for your feedback --
Greg
--
Greg Ward - software developer gward(a)cnri.reston.va.us
Corporation for National Research Initiatives
1895 Preston White Drive voice: +1-703-620-8990
Reston, Virginia, USA 20191-5434 fax: +1-703-620-0913
Hi all --
at long last, I found the time to hack in the ability to compile
extension modules to the Distutils. Mainly, this meant adding a
'build_ext' command which uses a CCompiler instance for all its dirty
work. I also had to add a few methods to CCompiler (and, of course,
UnixCCompiler) to make this work.
And I added a new module, 'spawn', which takes care of running
sub-programs more efficiently and robustly (no shell involved) than
os.system. That's needed, obviously, so we can run the compiler!
If you're in the mood for grubbing over raw source code, then get the
latest from CVS or download a current snapshot. See
http://www.python.org/sigs/distutils-sig/implementation.html
for a link to the code snapshot.
I'm still waiting for more subclasses of CCompiler to appear. At the
very least, we're going to need MSVCCompiler to build extensions on
Windows. Any takers? Also, someone who knows the Mac, and how to run
compilers programmatically there, will have to figure out how to write a
Mac-specific concrete CCompiler subclass.
The spawn module also needs a bit of work to be portable. I suspect
that _win32_spawn() (the intended analog to my _posix_spawn()) will be
easy to implement, if it even needs to go in a separate function at all.
It looks from the Python Library documentation for 1.5.2 that the
os.spawnv() function is all we need, but it's a bit hard to figure out
just what's needed. Windows wizards, please take a look at the
'spawn()' function and see if you can make it work on Windows.
As for actually compiling extensions: well, if you can figure out the
build_ext command, go ahead and give it a whirl. It's a bit cryptic
right now, since there's no documentation and no example setup.py. (I
have a working example at home, but it's not available online.) If you
feel up to it, though, see if you can read the code and figure out
what's going on. I'm just hoping *I'll* be able to figure out what's
going on when I get back from the O'Reilly conference next week... ;-)
Enjoy --
Greg
--
Greg Ward - software developer gward(a)cnri.reston.va.us
Corporation for National Research Initiatives
1895 Preston White Drive voice: +1-703-620-8990
Reston, Virginia, USA 20191-5434 fax: +1-703-620-0913
Hi all --
at long last, I have fixed two problems that a couple people noticed a
while ago:
* I folded in Amos Latteier's NT patches almost verbatim -- just
changed an `os.path.sep == "/"' to `os.name == "posix"' and added
some comments bitching about the inadequacy of the current library
installation model (I think this is Python's fault, but for now
Distutils is slavishly aping the situation in Python 1.5.x)
* I fixed the problem whereby running "setup.py install" without
doing anything else caused a crash (because 'build' hadn't yet
been run). Now, the 'install' command automatically runs 'build'
before doing anything; to make this bearable, I added a 'have_run'
dictionary to the Distribution class to keep track of which commands
have been run. So now not only are command classes singletons,
but their 'run' method can only be invoked once -- both restrictions
enforced by Distribution.
The code is checked into CVS, or you can download a snapshot at
http://www.python.org/sigs/distutils-sig/distutils-19990607.tar.gz
Hope someone (Amos?) can try the new version under NT. Any takers for
Mac OS?
BTW, all parties involved in the Great "Where Do We Install Stuff?"
Debate should take a good, hard look at the 'set_final_options()' method
of the Install class in distutils/install.py; this is where all the
policy decisions about where to install files are made. Currently it
apes the Python 1.5 situation as closely as I could figure it out.
Obviously, this is subject to change -- I just don't know to *what* it
will change!
Greg
--
Greg Ward - software developer gward(a)cnri.reston.va.us
Corporation for National Research Initiatives
1895 Preston White Drive voice: +1-703-620-8990
Reston, Virginia, USA 20191-5434 fax: +1-703-620-0913
Hi all,
I've been aware that the distutils sig has been simmerring away, but
until recently it has not been directly relevant to what I do.
I like the look of the proposed api, but have one question. Will this
support an installed system that has multiple versions of the same
package installed simultaneously? If not, then this would seem to be a
significant limitation, especially when dependencies between packages
are considered.
Assuming it does, then how will this be achieved? I am presently
managing this with a messy arrangement of symlinks. A package is
installed with its version number in it's name, and a separate
directory is created for an application with links from the
unversioned package name to the versioned one. Then I just set the
pythonpath to this directory.
A sample of what the directory looks like is shown below.
I'm sure there is a better solution that this, and I'm not sure that
this would work under windows anyway (does windows have symlinks?).
So, has this SIG considered such versioning issues yet?
Cheers,
Tim
--------------------------------------------------------------
Tim Docker timd(a)macquarie.com.au
Quantative Applications Division
Macquarie Bank
--------------------------------------------------------------
qad16:qad $ ls -l lib/python/
total 110
drwxr-xr-x 2 mts mts 512 Nov 11 11:23 1.1
-r--r----- 1 root mts 45172 Sep 1 1998 cdrmodule_0_7_1.so
drwxr-xr-x 2 mts mts 512 Sep 1 1998 chart_1_1
drwxr-xr-x 3 mts mts 512 Sep 1 1998 Fnorb_0_7_1
dr-xr-x--- 3 mts mts 512 Nov 11 11:21 Fnorb_0_8
drwxr-xr-x 3 mts mts 1536 Mar 3 12:45 mts_1_1
dr-xr-x--- 7 mts mts 512 Nov 11 11:22 OpenGL_1_5_1
dr-xr-x--- 2 mts mts 1024 Nov 11 11:23 PIL_0_3
drwxr-xr-x 3 mts mts 512 Sep 1 1998 Pmw_0_7
dr-xr-x--- 2 mts mts 512 Nov 11 11:21 v3d_1_1
qad16:qad $ ls -l lib/python/1.1
total 30
lrwxrwxrwx 1 root other 29 Apr 10 10:43 _glumodule.so -> ../OpenGL_1_5_1/_glumodule.so
lrwxrwxrwx 1 root other 30 Apr 10 10:43 _glutmodule.so -> ../OpenGL_1_5_1/_glutmodule.so
lrwxrwxrwx 1 root other 22 Apr 10 10:43 _imaging.so -> ../PIL_0_3/_imaging.so
lrwxrwxrwx 1 root other 36 Apr 10 10:43 _opengl_nummodule.so -> ../OpenGL_1_5_1/_opengl_nummodule.so
lrwxrwxrwx 1 root other 27 Apr 10 10:43 _tkinter.so -> ../OpenGL_1_5_1/_tkinter.so
lrwxrwxrwx 1 mts mts 21 Apr 10 10:43 cdrmodule.so -> ../cdrmodule_0_7_1.so
lrwxrwxrwx 1 mts mts 12 Apr 10 10:43 chart -> ../chart_1_1
lrwxrwxrwx 1 root other 12 Apr 10 10:43 Fnorb -> ../Fnorb_0_8
lrwxrwxrwx 1 mts mts 12 Apr 10 10:43 mts -> ../mts_1_1
lrwxrwxrwx 1 root other 15 Apr 10 10:43 OpenGL -> ../OpenGL_1_5_1
lrwxrwxrwx 1 root other 33 Apr 10 10:43 opengltrmodule.so -> ../OpenGL_1_5_1/opengltrmodule.so
lrwxrwxrwx 1 root other 33 Apr 10 10:43 openglutil_num.so -> ../OpenGL_1_5_1/openglutil_num.so
lrwxrwxrwx 1 root other 10 Apr 10 10:43 PIL -> ../PIL_0_3
lrwxrwxrwx 1 mts mts 10 Apr 10 10:43 Pmw -> ../Pmw_0_7
lrwxrwxrwx 1 root other 10 Apr 10 10:43 v3d -> ../v3d_1_1
I saw the announcement a few days back about the Distutils CVS tree being
merged back into the Python 1.6 CVS tree. I was wondering if the plans for
"Distutils-1.0" include:
(1) it being available as a separate package, and,
(2) compatibility with Python 1.5.2.
I'm still testing against the Distutils-0.1.3 drop, which of course meets
both of the above requirements. But I wasn't sure how to proceed with
regards to looking at the more recent snapshot(s) and/or the CVS version of
Distutils. I am anticipating that *some* of my end-users will not
immediately upgrade to Python 1.6 when it is released, and I don't want to
make that a requirement since the extension code itself (i.e. my stuff)
doesn't require Python 1.6.
I'm trying to port stuff from Win32 to FreeBSD. Distutils is fine with
win32, but can I use it with freebsd? I notice that earlier methods used
a universal makefile and Setup.in and involved a lot of technology ie
libtool etc etc
--
Robin Becker
This patch changes msvccompiler.py so that the new winreg module
is used if available. Otherwise, win32reg and win32con is used.
*** msvccompiler.py Fri Mar 31 18:01:20 2000
--- msvccompiler.new.py Fri Mar 31 17:55:02 2000
***************
*** 16,21 ****
--- 16,47 ----
from distutils.ccompiler import \
CCompiler, gen_preprocess_options, gen_lib_options
+ try:
+ import winreg
+ _HKEY_CLASSES_ROOT = winreg.HKEY_CLASSES_ROOT
+ _HKEY_LOCAL_MACHINE = winreg.HKEY_LOCAL_MACHINE
+ _HKEY_CURRENT_USER = winreg.HKEY_CURRENT_USER
+ _HKEY_USERS = winreg.HKEY_USERS
+ _RegOpenKeyEx = winreg.OpenKeyEx
+ _RegEnumKey = winreg.EnumKey
+ _RegEnumValue = winreg.EnumValue
+ _RegError = winreg.error
+ _can_read_reg = 1
+ except ImportError:
+ try:
+ import win32api
+ import win32con
+ _HKEY_CLASSES_ROOT = win32con.HKEY_CLASSES_ROOT
+ _HKEY_LOCAL_MACHINE = win32con.HKEY_LOCAL_MACHINE
+ _HKEY_CURRENT_USER = win32con.HKEY_CURRENT_USER
+ _HKEY_USERS = win32con.HKEY_USERS
+ _RegOpenKeyEx = win32api.RegOpenKeyEx
+ _RegEnumKey = win32api.RegEnumKey
+ _RegEnumValue = win32api.RegEnumValue
+ _RegError = win32api.error
+ _can_read_reg = 1
+ except ImportError:
+ _can_read_reg = 0
def get_devstudio_versions ():
"""Get list of devstudio versions from the Windows registry. Return a
***************
*** 24,53 ****
a registry-access module) or the appropriate registry keys weren't
found."""
! try:
! import win32api
! import win32con
! except ImportError:
return []
K = 'Software\\Microsoft\\Devstudio'
L = []
! for base in (win32con.HKEY_CLASSES_ROOT,
! win32con.HKEY_LOCAL_MACHINE,
! win32con.HKEY_CURRENT_USER,
! win32con.HKEY_USERS):
try:
! k = win32api.RegOpenKeyEx(base,K)
i = 0
while 1:
try:
! p = win32api.RegEnumKey(k,i)
if p[0] in '123456789' and p not in L:
L.append(p)
! except win32api.error:
break
i = i + 1
! except win32api.error:
pass
L.sort()
L.reverse()
--- 50,76 ----
a registry-access module) or the appropriate registry keys weren't
found."""
! if not _can_read_reg:
return []
K = 'Software\\Microsoft\\Devstudio'
L = []
! for base in (_HKEY_CLASSES_ROOT,
! _HKEY_LOCAL_MACHINE,
! _HKEY_CURRENT_USER,
! _HKEY_USERS):
try:
! k = _RegOpenKeyEx(base,K)
i = 0
while 1:
try:
! p = _RegEnumKey(k,i)
if p[0] in '123456789' and p not in L:
L.append(p)
! except _RegError:
break
i = i + 1
! except _RegError:
pass
L.sort()
L.reverse()
***************
*** 61,70 ****
a list of strings; will be empty list if unable to access the
registry or appropriate registry keys not found."""
! try:
! import win32api
! import win32con
! except ImportError:
return []
L = []
--- 84,90 ----
a list of strings; will be empty list if unable to access the
registry or appropriate registry keys not found."""
! if not _can_read_reg:
return []
L = []
***************
*** 74,89 ****
K = ('Software\\Microsoft\\Devstudio\\%s\\' +
'Build System\\Components\\Platforms\\Win32 (%s)\\Directories') % \
(version,platform)
! for base in (win32con.HKEY_CLASSES_ROOT,
! win32con.HKEY_LOCAL_MACHINE,
! win32con.HKEY_CURRENT_USER,
! win32con.HKEY_USERS):
try:
! k = win32api.RegOpenKeyEx(base,K)
i = 0
while 1:
try:
! (p,v,t) = win32api.RegEnumValue(k,i)
if string.upper(p) == path:
V = string.split(v,';')
for v in V:
--- 94,109 ----
K = ('Software\\Microsoft\\Devstudio\\%s\\' +
'Build System\\Components\\Platforms\\Win32 (%s)\\Directories') % \
(version,platform)
! for base in (_HKEY_CLASSES_ROOT,
! _HKEY_LOCAL_MACHINE,
! _HKEY_CURRENT_USER,
! _HKEY_USERS):
try:
! k = _RegOpenKeyEx(base,K)
i = 0
while 1:
try:
! (p,v,t) = _RegEnumValue(k,i)
if string.upper(p) == path:
V = string.split(v,';')
for v in V:
***************
*** 91,99 ****
L.append(v)
break
i = i + 1
! except win32api.error:
break
! except win32api.error:
pass
return L
--- 111,119 ----
L.append(v)
break
i = i + 1
! except _RegError:
break
! except _RegError:
pass
return L
Disclaimer:
I confirm that, to the best of my knowledge and belief, this
contribution is free of any claims of third parties under
copyright, patent or other rights or interests ("claims"). To
the extent that I have any such claims, I hereby grant to CNRI a
nonexclusive, irrevocable, royalty-free, worldwide license to
reproduce, distribute, perform and/or display publicly, prepare
derivative versions, and otherwise use this contribution as part
of the Python software and its related documentation, or any
derivative versions thereof, at no cost to CNRI or its licensed
users, and to authorize others to do so.
I acknowledge that CNRI may, at its sole discretion, decide
whether or not to incorporate this contribution in the Python
software and its related documentation. I further grant CNRI
permission to use my name and other identifying information
provided to CNRI by me for use in connection with the Python
software and its related documentation.
Thomas Heller
The attached patch fixes the followoing problems:
1. self.build_extensions - (which I reported already)
2. The python library directory is now again used (also already reported by me)
3. Debug and Release versions of python extensions under windows are now
compiled in different directories (as it should be!).
4. Unneeded junk from the MSVC linker (.lib and .exp files) are now created in the
temporary build directory.
diff -cr distutils/command/build_ext.py distutils.new/command/build_ext.py
*** distutils/command/build_ext.py Wed Mar 29 10:33:48 2000
--- distutils.new/command/build_ext.py Wed Mar 29 21:16:16 2000
***************
*** 125,130 ****
--- 125,141 ----
# XXX how the heck are 'self.define' and 'self.undef' supposed to
# be set?
+ if self.library_dirs is None:
+ self.library_dirs = []
+ # for extensions under windows use different directories
+ # for Release and Debug builds.
+ # also Python's library directory must be appended to library_dirs
+ if os.name == 'nt':
+ self.library_dirs.append (os.path.join(sys.exec_prefix, 'libs'))
+ if self.debug:
+ self.build_temp = os.path.join (self.build_temp, "Debug")
+ else:
+ self.build_temp = os.path.join (self.build_temp, "Release")
# finalize_options ()
***************
*** 189,195 ****
self.compiler.set_link_objects (self.link_objects)
# Now actually compile and link everything.
! self.build_extensions ()
# run ()
--- 200,206 ----
self.compiler.set_link_objects (self.link_objects)
# Now actually compile and link everything.
! self.build_extensions (self.extensions)
# run ()
***************
*** 313,318 ****
--- 324,336 ----
else:
modname = string.split (extension_name, '.')[-1]
extra_args.append('/export:init%s'%modname)
+ # 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_dir = os.path.join(self.build_temp,\
+ self.get_ext_libname(extension_name))
+ extra_args.append ('/IMPLIB:' + implib_dir)
# if MSVC
fullname = self.get_ext_fullname (extension_name)
***************
*** 351,356 ****
--- 369,385 ----
def get_ext_filename (self, ext_name):
from distutils import sysconfig
ext_path = string.split (ext_name, '.')
+ # extensions in debug_mode are named 'module_d.pyd' under windows
+ if os.name == 'nt' and self.debug:
+ return apply (os.path.join, ext_path) + '_d' + sysconfig.SO
return apply (os.path.join, ext_path) + sysconfig.SO
+
+ def get_ext_libname (self, ext_name):
+ # create a filename for the (unneeded) lib-file.
+ # extensions in debug_mode are named 'module_d.pyd' under windows
+ ext_path = string.split (ext_name, '.')
+ if os.name == 'nt' and self.debug:
+ return apply (os.path.join, ext_path) + '_d.lib'
+ return apply (os.path.join, ext_path) + '.lib'
# class BuildExt
diff -cr distutils/msvccompiler.py distutils.new/msvccompiler.py
*** distutils/msvccompiler.py Wed Mar 29 09:01:40 2000
--- distutils.new/msvccompiler.py Wed Mar 29 20:58:54 2000
***************
*** 319,333 ****
raise TypeError, "'output_dir' must be a string or None"
if output_dir is not None:
output_filename = os.path.join (output_dir, output_filename)
if self._need_link (objects, output_filename):
if debug:
ldflags = self.ldflags_shared_debug
- # XXX not sure this belongs here
- # extensions in debug_mode are named 'module_d.pyd'
- basename, ext = os.path.splitext (output_filename)
- output_filename = basename + '_d' + ext
else:
ldflags = self.ldflags_shared
--- 319,331 ----
raise TypeError, "'output_dir' must be a string or None"
if output_dir is not None:
output_filename = os.path.join (output_dir, output_filename)
+ else:
+ output_dir = os.path.dirname (output_filename)
if self._need_link (objects, output_filename):
if debug:
ldflags = self.ldflags_shared_debug
else:
ldflags = self.ldflags_shared
Thomas Heller
ION-TOF GmbH
Hi all --
I've just checked in the beginnings of support for creating "built
distributions" (aka binary distributions, but of course they aren't
necessarily binary -- you might want to distribute something that is
immediately installable but contains only Python code).
This consists of two commands so far, 'bdist' and 'bdist_dumb'. These
follow the model of the 'build' and 'install' families, where there is
one high-level coordinator, and "sub-commands" that do the real work.
So far, obviously, there's only one bdist sub-command, and all it
creates are "dumb" built distributions -- tarballs and zip files that
you unpack from <prefix> or <exec-prefix>.
There are a number of obvious weaknesses to this, but this was intended
more as a warm-up exercise than the real thing. First of all, the end
user has to somehow know to chdir to Python's <prefix> or <exec-prefix>
and unpack the dumb distribution there. Worse, they have to know to
sometimes chdir to to <prefix>, and sometimes <exec-prefix> -- assuming
there's even a difference on their system. Anyways, as I said, this is
*not* the be-all, end-all to creating built Python module distributions!
However, it's all that I could whip up in three evenings.
If you'd like to try it out, please do! Here's the basic idea:
python setup.py bdist
or:
python setup.py bdist --formats=gztar # or zip, tar, or ztar
The default format is currently gztar for Unix, zip for Windows.
Obviously, that will have to get a bit more complicated: we'll want to
create an RPM on RPM-based systems, a Debian package on Debian systems,
a BSD package on BSD systems, some sort of executable installer
(probably Wise) on Windows systems, etc. But for now, you get either a
tarball or a zipfile, and if you don't specify --formats, you get
whatever is sensible on your current OS.
For example, if I go to my NumPy 15.2 directory (which is identical to
the NumPy 15.2 distribution, *except* I use the example NumPy setup
script included with the Distutils!) and run this:
$ python setup.py bdist
then I get (roughly) this output:
[...build output omitted...]
creating build/bdist
creating build/bdist/lib
creating build/bdist/lib/python1.5
creating build/bdist/lib/python1.5/site-packages
creating build/bdist/lib/python1.5/site-packages/Numeric
hard linking build/lib.linux-i586/ArrayPrinter.py -> build/bdist/lib/python1.5/site-packages/Numeric
hard linking build/lib.linux-i586/FFT.py -> build/bdist/lib/python1.5/site-packages/Numeric
[...and so on, for all modules that NumPy would install...]
changing into 'build/bdist'
tar -cf /scratch/python/Numerical-15.2/Numerical-15.2.linux-i586.tar .
gzip /scratch/python/Numerical-15.2/Numerical-15.2.linux-i586.tar
changing back to '/scratch/python/Numerical-15.2'
and the resulting tarball, Numerical-15.2.linux-i586.tar.gz, looks like
this:
$ tar tzf Numerical-15.2.linux-i586.tar.gz
./
lib/
lib/python1.5/
lib/python1.5/site-packages/
lib/python1.5/site-packages/Numeric/
lib/python1.5/site-packages/Numeric/ArrayPrinter.py
lib/python1.5/site-packages/Numeric/FFT.py
lib/python1.5/site-packages/Numeric/LinearAlgebra.py
[...]
lib/python1.5/site-packages/Numeric/ranlib.so
lib/python1.5/site-packages/Numeric/arrayfns.so
which reduces installing Numerical Python to a mere
$ cd `python -c "import sys; print sys.exec_prefix"`
$ tar xzvf /scratch/python/Numerical-15.2/Numerical-15.2.linux-i586.tar.gz
OK, OK, so it's not immediately obvious that this is better than a
simple "python setup.py install". ;-) But think of the possibilities!
Known bugs:
* if a distribution needs a .pth file, it is neither created nor
included in the built distribution
Feel free to add to this list...
Greg
--
Greg Ward - just another /P(erl|ython)/ hacker gward(a)python.net
http://starship.python.net/~gward/
If it can't be expressed in figures, it is not science--it is opinion.