|
David Fraser
davidf at sjsoft.com
Fri Mar 5 18:21:20 EST 2004
Hi
I've been working on the mod_python dist/setup.py.in (mostly to make it
work for win32) and have added some important functionality...
1) it no longer requires configure (so it could just be setup.py) - it
either scans config.status or calculates the information itself (e.g. it
scans through the source file to find the mod_python version number). On
Windows it uses the APACHESRC environment variables to find the apache
include and lib directories (just like the VC++ project does)
2) it is now able to build mod_psp on Windows as well as Linux
3) most importantly, it is now able to build mod_python directly from
the setup.py (on Windows)
this should be possible on non-Windows system too but will require
some work (we may have to make a distutils compiler class for apxs)
There are a few notes:
- the build of the mod_python extension produces a mod_python_so.pyd
file, instead of the mod_python.so file we want. But at least on
Windows, I have modified win32_postinstall to install this one instead
of the other... (I call it mod_python_so.pyd instead of mod_python.pyd
so that when it is put in the site-packages directory it does not
confuse importing packages from mod_python)
- I have also added code to win32_postinstall to automatically detect
the currently installed versions of Apache from the registry. It would
be nice to let the user choose one of these. As a start, it just selects
the latest version as the starting point for the tkinter file selection
dialog (the win32 shell classes don't seem to let you do this...)
I have attached the modified setup.py.in (easier than a patch as almost
everything has changed) and win32_postinstall.py
Any comments appreciated
David
-------------- next part --------------
# $Id: setup.py.in,v 1.5 2003/07/24 17:46:09 grisha Exp $
from distutils.core import setup, Extension
import sys
import re
import os.path
def getmp_rootdir():
"""gets the root directory of the mod_python source tree..."""
return os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
def getmp_srcdir():
"""gets the src subdirectory of the mod_python source tree..."""
return os.path.join(getmp_rootdir(), 'src')
def getmp_includedir():
"""gets the src subdirectory of the mod_python source tree..."""
return os.path.join(getmp_rootdir(), 'src', 'include')
def getconfigure_option(option_name):
"""gets an option from the config.status file"""
config_status_file = os.path.join(getmp_rootdir(), 'config.status')
if not os.path.exists(config_status_file):
raise AssertionError("config.status not found in expected location (%s)" % config_status_file)
header = open(config_status_file,'r')
r = re.compile('s,@%s@,(?P<OPTION_STRING>[^,]+),' % (option_name))
for line in header.readlines():
m = r.search(line)
if m is not None:
return m.group('OPTION_STRING')
raise AssertionError("unable to find @%s@ definition in %s", (option_name, config_status_file))
def getmp_version():
"""finds out the version of mod_python"""
# if that fails, read it from the source file ourselves...
mpversion_file = os.path.join(getmp_includedir(), 'mpversion.h')
if not os.path.exists(mpversion_file):
raise AssertionError("mpversion.h not found in expected location (%s)" % mpversion_file)
header = open(mpversion_file,'r')
r = re.compile('#define\s+MPV_STRING\s+"(?P<MPV_STRING>[^"]+)"')
for line in header.readlines():
m = r.search(line)
if m is not None:
return m.group('MPV_STRING')
raise AssertionError("unable to find MPV_STRING in %s", mpversion_file)
def getapxs_location():
"""finds the location of apxs from the config.status file"""
return getconfigure_option("APXS")
def getapxs_option(option):
APXS = getapxs_location()
import commands
return commands.getoutput("%s -q %s" % (APXS, option))
def getapache_srcdir():
"""returns apache src directory"""
return os.getenv("APACHESRC")
def getapache_includedir():
"""returns apache include directory"""
apache_srcdir = getapache_srcdir()
if apache_srcdir is None:
return getapxs_option("INCLUDEDIR")
else:
return os.path.join(getapache_srcdir(), "include")
def getapache_libdir():
"""returns apache lib directory"""
apache_srcdir = getapache_srcdir()
if apache_srcdir is None:
return ""
else:
return os.path.join(apache_srcdir, "lib")
VER = getmp_version()
# TODO: improve the intelligence here...
winbuild = (len(sys.argv) > 1 and sys.argv[1] == "bdist_wininst") or (os.name == "nt")
class PSPExtension(Extension):
"""a class that helps build the PSP extension"""
def __init__(self, source_dir, include_dirs):
Extension.__init__(self, "mod_python._psp",
[os.path.join(source_dir, source_file) for source_file in
("psp_string.c", "psp_parser.c", "_pspmodule.c")],
include_dirs=include_dirs
)
PSPModule = PSPExtension(getmp_srcdir(), [getmp_includedir()])
modpy_src_files = ("mod_python.c", "_apachemodule.c", "connobject.c", "filterobject.c",
"hlist.c", "hlistobject.c", "requestobject.c", "serverobject.c", "tableobject.c",
"util.c")
class finallist(list):
"""this represents a list that cannot be appended to..."""
def append(self, object):
return
class ModPyExtension(Extension):
"""a class that actually builds the mod_python.so extension for Apache (yikes)"""
def __init__(self, source_dir, include_dirs, library_dirs):
Extension.__init__(self, "mod_python_so",
sources = [os.path.join(source_dir, source_file) for source_file in modpy_src_files],
include_dirs=include_dirs,
libraries = ['libhttpd','libapr','libaprutil','ws2_32'],
library_dirs=library_dirs
)
if winbuild:
self.define_macros.extend([('WIN32',None),('NDEBUG',None),('_WINDOWS',None)])
self.sources.append(os.path.join(source_dir, "Version.rc"))
else:
# TODO: fix this to autodetect if required...
self.include_dirs.append("/usr/include/apr-0")
# this is a hack to prevent build_ext from trying to append "initmod_python" to the export symbols
self.export_symbols = finallist(self.export_symbols)
ModPyModule = ModPyExtension(getmp_srcdir(), [getmp_includedir(), getapache_includedir()], [getapache_libdir()])
if winbuild:
scripts = ["win32_postinstall.py"]
# put the mod_python.so file in the Python root ...
# win32_postinstall.py will pick it up from there...
# data_files = [("", [(os.path.join(getmp_srcdir(), 'Release', 'mod_python.so'))])]
data_files = []
else:
# mpso = "../src/mod_python.so"
scripts = []
data_files = []
setup(name="mod_python",
version=VER,
description="Apache/Python Integration",
author="Gregory Trubetskoy et al",
author_email="mod_python at modpython.org",
url="http://www.modpython.org/",
packages=["mod_python"],
package_dir={'mod_python': os.path.join(getmp_rootdir(), 'lib', 'python', 'mod_python')},
scripts=scripts,
data_files=data_files,
ext_modules=[ModPyModule, PSPModule])
# makes emacs go into python mode
### Local Variables:
### mode:python
### End:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: win32_postinstall.py
Type: text/x-python
Size: 4908 bytes
Desc: not available
Url : http://mailman.modpython.org/pipermail/mod_python/attachments/20040305/b415eb65/win32_postinstall.py
|