[mod_python] Re: problem installing mod_python-3.1.3 with Python 2.4

David Fraser davidf at sjsoft.com
Mon Dec 6 02:12:29 EST 2004

Nicolas Lehuen wrote:

>>The biggest difficulty I hit was that Python 2.4 (the standard 
>>binary) is built with MSVC 7.1, so extensions also have to be built with
>that version (or with mingw, which can build MSVC-7.1 compatible binaries).
>>As I don't have MSVC 7.1, and can't work out how to build Apache, or at
>least enough of it to compile
>>mod_python, with mingw, I'm stuck.
>>I would *really* appreciate a Python 2.4 binary of mod_python... 
>OK, I've managed to rebuild mod_python.so for Win32 with Python 2.4 support,
>and it seems to work properly. If you want the binary version, write me and
>I'll send it to you. Note that I've tried it on Apache 2.0.52 compiled with
>VC 7.1 too, so your mileage may vary if you have the standard build of
>The problem is that I could not rebuild _psp.pyd, so PSP pages are not
>working for now. Until now, I only needed to rebuild mod_python.so since the
>patches I wrote were targeting this module, so I've just noticed that
>building _psp.pyd is not as straightforward as building mod_python.so,
>mainly because there are no project file or setup.py for this. It seems that
>the subversion repository misses something there. Grisha, can you tell us
>how to rebuild _psp.pyd ?
Glad someone has done this. Could you include the details of how you 
built it?

You may also want to try the modifications I did to setup.py.in which 
enables it to build the extensions

It's in the mailing list archives but I've attached my latest version 
here in case.


-------------- next part --------------
 # Copyright 2004 Apache Software Foundation
 #  Licensed under the Apache License, Version 2.0 (the "License");
 #  you may not use this file except in compliance with the License.
 #  You may obtain a copy of the License at
 #      http://www.apache.org/licenses/LICENSE-2.0
 #  Unless required by applicable law or agreed to in writing, software
 #  distributed under the License is distributed on an "AS IS" BASIS,
 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 # $Id: setup.py.in,v 1.6 2004/04/30 19:33:59 grisha Exp $

from distutils.core import setup, Extension

import sys
import re
import os.path

# TODO: improve the intelligence here...
winbuild = (len(sys.argv) > 1 and sys.argv[1] == "bdist_wininst") or (os.name == "nt")

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")
        return os.path.join(getapache_srcdir(), "include")

def getapache_libdir():
    """returns apache lib directory"""
    apache_srcdir = getapache_srcdir()
    if apache_srcdir is None:
        return ""
        return os.path.join(apache_srcdir, "lib")

class PSPExtension(Extension):
    """a class that helps build the PSP extension"""
    def __init__(self, source_dir=None, include_dirs=None):
        if source_dir is None:
            source_dir = getmp_srcdir()
        if include_dirs is None:
            include_dirs = [getmp_includedir()]
        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")],

modpy_src_files = ("mod_python.c", "_apachemodule.c", "connobject.c", "filterobject.c",
                   "hlist.c", "hlistobject.c", "requestobject.c", "serverobject.c", "tableobject.c",

class finallist(list):
  """this represents a list that cannot be appended to..."""
  def append(self, object):

class ModPyExtension(Extension):
    """a class that actually builds the mod_python.so extension for Apache (yikes)"""
    def __init__(self, source_dir=None, include_dirs=None, library_dirs=None):
        if source_dir is None:
            source_dir = getmp_srcdir()
        if include_dirs is None:
            include_dirs = [getmp_includedir(), getapache_includedir()]
        if library_dirs is None:
            if winbuild:
                library_dirs = [getapache_libdir()]
                library_dirs = []
        if winbuild:
            libraries = ['libhttpd', 'libapr', 'libaprutil', 'ws2_32']
            libraries = ['apr-0', 'aprutil-0', 'python2.3']
        sources = [os.path.join(source_dir, source_file) for source_file in modpy_src_files]
        Extension.__init__(self, "mod_python_so",
            sources=sources, include_dirs=include_dirs, libraries=libraries, library_dirs=library_dirs)
        if winbuild:
            self.sources.append(os.path.join(source_dir, "Version.rc"))
            # TODO: fix this to autodetect if required...
        # 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)

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 = []
    # mpso = "../src/mod_python.so"
    scripts = []
    data_files = []

if __name__ == "__main__":
    VER = getmp_version()
    ModPyModule = ModPyExtension()
    PSPModule = PSPExtension()
        description="Apache/Python Integration",
        author="Gregory Trubetskoy et al",
        author_email="mod_python at modpython.org",
        package_dir={'mod_python': os.path.join(getmp_rootdir(), 'lib', 'python', 'mod_python')},
        ext_modules=[ModPyModule, PSPModule],

# makes emacs go into python mode
### Local Variables:
### mode:python
### End:

More information about the Mod_python mailing list