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
|