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
---- 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
"""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
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(a)python.net
http://starship.python.net/~gward/
Just because you're paranoid doesn't mean they *aren't* out to get you.
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(a)python.net.
Larger patches should be discussed on the Distutils mailing list:
distutils-sig(a)python.org.
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. <fdrake at beopen.com>
BeOpen PythonLabs Team Member
...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(a)python.net
http://starship.python.net/~gward/
I had pancake makeup for brunch!