[Lxml-checkins] r34860 - in lxml/trunk: . doc

faassen at codespeak.net faassen at codespeak.net
Wed Nov 22 15:20:58 CET 2006


Author: faassen
Date: Wed Nov 22 15:20:56 2006
New Revision: 34860

Added:
   lxml/trunk/setupinfo.py
   lxml/trunk/versioninfo.py
Modified:
   lxml/trunk/doc/build.txt
   lxml/trunk/setup.py
Log:
Refactored setup.py into multiple files to be more readable and hackable.


Modified: lxml/trunk/doc/build.txt
==============================================================================
--- lxml/trunk/doc/build.txt	(original)
+++ lxml/trunk/doc/build.txt	Wed Nov 22 15:20:56 2006
@@ -186,38 +186,29 @@
   zlib-1.2.3.win32/
   zlib-1.2.3.win32.zip
 
-Go to the lxml-1.0.0 directory and edit the file ``setup.py``.  There should
+Go to the lxml directory and edit the file ``setup.py``.  There should
 be a section near the top that looks like this::
 
-  def setupStaticBuild():
-      cflags = [
-          ]
-      xslt_libs = [
-          ]
-      result = (cflags, xslt_libs)
-      # return result
-      raise NotImplementedError, \
-            "Static build not configured, see doc/build.txt"
+  STATIC_LIBS = []
+  STATIC_CFLAGS = []
 
 Change this section to something like this, but take care to use the correct
 version numbers::
 
-  def setupStaticBuild():
-      cflags = [
-         "-I..\\libxml2-2.6.23.win32\\include ",
-         "-I..\\libxslt-1.1.15.win32\\include",
-         "-I..\\zlib-1.2.3.win32\\include",
-         "-I..\\iconv-1.9.1.win32\\include"
-         ]
-      xslt_libs = [
+  STATIC_LIBS = [
          "..\\libxml2-2.6.23.win32\\lib\\libxml2_a.lib",
          "..\\libxslt-1.1.15.win32\\lib\\libxslt_a.lib",
          "..\\libxslt-1.1.15.win32\\lib\\libexslt_a.lib",
          "..\\zlib-1.2.3.win32\\lib\\zlib.lib",
          "..\\iconv-1.9.1.win32\\lib\\iconv_a.lib"
          ]
-      result = (cflags, xslt_libs)
-      return result
+
+  STATIC_CFLAGS = [
+         "-I..\\libxml2-2.6.23.win32\\include ",
+         "-I..\\libxslt-1.1.15.win32\\include",
+         "-I..\\zlib-1.2.3.win32\\include",
+         "-I..\\iconv-1.9.1.win32\\include"
+         ]
 
 The ``_a`` part of the library names means that we are linking statically
 against the named library files.  If you want to use dynamic libraries, you

Modified: lxml/trunk/setup.py
==============================================================================
--- lxml/trunk/setup.py	(original)
+++ lxml/trunk/setup.py	Wed Nov 22 15:20:56 2006
@@ -1,201 +1,31 @@
-import sys, os, os.path, re
-
-EXT_MODULES = [
-    ("etree",       "lxml.etree"),
-    ("objectify",   "lxml.objectify")
-    ]
-
-setup_args = {}
-ext_args   = {}
-DEFINES = []
-
-try:
-    from setuptools import setup
-    from setuptools.extension import Extension
-    # prevent setuptools from making local etree.so copies:
-    setup_args['zip_safe'] = False
-except ImportError:
-    from distutils.core import setup
-    from distutils.extension import Extension
-
-# This is called if the '--static' option is passed
-def setupStaticBuild():
-    "See doc/build.txt to make this work."
-    cflags = [
-        ]
-    xslt_libs = [
-        ]
-    result = (cflags, xslt_libs)
-    # return result
-    raise NotImplementedError, \
-          "Static build not configured, see doc/build.txt"
-
-# This is called if the '--rpath' option is passed
-def setupRpathBuild(xslt_libs, ext_args):
-    libdirs   = []
-    libs      = []
-    libflags  = []
-    rpathdirs = []
-    for option in xslt_libs:
-        content = option[2:]
-        if option.startswith('-L'):
-            if not content.startswith('/usr'):
-                rpathdirs.append(content)
-            libdirs.append(content)
-        elif option.startswith('-l'):
-            libs.append(content)
-        else:
-            libflags.append(option)
-
-    ext_args['libraries']            = libs
-    ext_args['library_dirs']         = libdirs
-    ext_args['extra_link_args']      = libflags
-    ext_args['runtime_library_dirs'] = rpathdirs
-
-def flags(cmd):
-    wf, rf, ef = os.popen3(cmd)
-    return rf.read().split()
-
-def add_libexslt(lib_flags):
-    if '-lxslt' in lib_flags:
-        xslt, exslt = '-lxslt', '-lexslt'
-    else:
-        xslt, exslt = 'xslt', 'exslt'
-    for i, libname in enumerate(lib_flags):
-        if exslt in libname:
-            return
-        if xslt in libname:
-            lib_flags.insert(i, libname.replace(xslt, exslt))
-            return
-
-def fix_alphabeta(version, alphabeta):
-    if '.'+alphabeta in version:
-        return version
-    return version.replace(alphabeta, '.'+alphabeta)
-
-# determine version number and create lxml-version.h
-
-src_dir = os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]))
-version = open(os.path.join(src_dir, 'version.txt')).read().strip()
-branch_version = version[:3]
-
-try:
-    svn_entries = open(os.path.join(src_dir, '.svn', 'entries')).read()
-except IOError:
-    svn_version = version
-else:
-    revision = re.search('<entry[^>]*name=""[^>]*revision="([^"]+)"',
-                         svn_entries).group(1)
-    svn_version = version + '-' + revision
-
-if 'dev' in version:
-    svn_version = fix_alphabeta(svn_version, 'dev')
-    dev_status = 'Development Status :: 3 - Alpha'
-elif 'alpha' in version:
-    svn_version = fix_alphabeta(svn_version, 'alpha')
-    dev_status = 'Development Status :: 3 - Alpha'
-elif 'beta' in version:
-    svn_version = fix_alphabeta(svn_version, 'beta')
-    dev_status = 'Development Status :: 4 - Beta'
-else:
-    dev_status = 'Development Status :: 5 - Production/Stable'
-
-version_h = open(os.path.join(src_dir, 'src', 'lxml', 'lxml-version.h'), 'w')
-version_h.write('''\
-#ifndef LXML_VERSION_STRING
-#define LXML_VERSION_STRING "%s"
-#endif
-''' % svn_version)
-version_h.close()
-
+from setuptools import setup
+import versioninfo
+import setupinfo
+
+# override these and pass --static for a static build. See
+# doc/build.txt for more information. If you do not pass --static
+# changing this will have no effect.
+STATIC_LIBS = []
+STATIC_CFLAGS = []
+
+# create lxml-version.h file
+svn_version = versioninfo.svn_version()
+versioninfo.create_version_h(svn_version)
 print "Building lxml version", svn_version
 
-# setup etree extension building
-
-try:
-    from Pyrex.Distutils import build_ext as build_pyx
-    source_extension = ".pyx"
-    setup_args['cmdclass'] = {'build_ext' : build_pyx}
-except ImportError:
-    print "*NOTE*: Trying to build without Pyrex, needs pre-generated 'src/lxml/etree.c' !"
-    source_extension = ".c"
-
-if '--static' in sys.argv:
-    # use the static setup as configured in setupStaticBuild
-    sys.argv.remove('--static')
-    cflags, xslt_libs = setupStaticBuild()
-    ext_args['extra_link_args'] = xslt_libs
-else:
-    cflags    = flags('xslt-config --cflags')
-    xslt_libs = flags('xslt-config --libs')
-    add_libexslt(xslt_libs) # compile also against libexslt!
-
-    if '--rpath' in sys.argv:
-        # compile with --rpath under gcc
-        sys.argv.remove('--rpath')
-        setupRpathBuild(xslt_libs, ext_args)
-    else:
-        ext_args['extra_link_args'] = xslt_libs
-
-try:
-    sys.argv.remove('--without-assert')
-    DEFINES.append( ('PYREX_WITHOUT_ASSERTIONS', None) )
-except ValueError:
-    pass
-
-if '--debug-gcc' in sys.argv:
-    sys.argv.remove('--debug-gcc')
-    cflags.append('-g2')
-
-ext_modules = []
-
-for module, package in EXT_MODULES:
-    ext_modules.append(
-	Extension(
-	package,
-	sources = ["src/lxml/" + module + source_extension],
-	extra_compile_args = ['-w'] + cflags,
-	define_macros = DEFINES,
-	**ext_args
-	))
-
-# setup ChangeLog entry
-
-changelog_text = ""
-try:
-    changelog = open(os.path.join(src_dir, "CHANGES.txt"), 'r')
-except:
-    print "*NOTE*: couldn't open CHANGES.txt !"
-else:
-    changelog_lines = []
-    for line in changelog:
-        if line.startswith('====='):
-            if len(changelog_lines) > 1:
-                break
-        if changelog_lines:
-            changelog_lines.append(line)
-        elif line.startswith(version):
-            changelog_lines.append(line)
-
-    if changelog_lines:
-        changelog_text = ''.join(changelog_lines[:-1])
-
-    changelog.close()
-
-
 setup(
     name = "lxml",
-    version = version,
+    version = versioninfo.version(),
     author="lxml dev team",
     author_email="lxml-dev at codespeak.net",
     maintainer="lxml dev team",
     maintainer_email="lxml-dev at codespeak.net",
     url="http://codespeak.net/lxml",
-    download_url="http://cheeseshop.python.org/packages/source/l/lxml/lxml-%s.tar.gz" % version,
+    download_url="http://cheeseshop.python.org/packages/source/l/lxml/lxml-%s.tar.gz" % versioninfo.version(),
 
     description="Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.",
 
-    long_description="""\
+    long_description=(("""\
 lxml is a Pythonic binding for the libxml2 and libxslt libraries.  It provides
 safe and convenient access to these libraries using the ElementTree API.
 
@@ -213,10 +43,10 @@
 version from
 http://codespeak.net/svn/lxml/branch/lxml-%(branch_version)s#egg=lxml-%(branch_version)sbugfix
 
-""" % {"branch_version":branch_version} + changelog_text,
-
+""" % { "branch_version" : versioninfo.branch_version() }) +
+                      versioninfo.changes()),
     classifiers = [
-    dev_status,
+    versioninfo.dev_status(),
     'Intended Audience :: Developers',
     'Intended Audience :: Information Technology',
     'License :: OSI Approved :: BSD License',
@@ -229,6 +59,7 @@
 
     package_dir = {'': 'src'},
     packages = ['lxml'],
-    ext_modules = ext_modules,
-    **setup_args
+    zip_safe = False,
+    ext_modules = setupinfo.ext_modules(STATIC_LIBS, STATIC_CFLAGS),
+    **setupinfo.extra_setup_args()
 )

Added: lxml/trunk/setupinfo.py
==============================================================================
--- (empty file)
+++ lxml/trunk/setupinfo.py	Wed Nov 22 15:20:56 2006
@@ -0,0 +1,123 @@
+import sys, os
+from setuptools.extension import Extension
+
+try:
+    from Pyrex.Distutils import build_ext as build_pyx
+    PYREX_INSTALLED = True
+except ImportError:
+    PYREX_INSTALLED = False
+
+EXT_MODULES = [
+    ("etree",       "lxml.etree"),
+    ("objectify",   "lxml.objectify")
+    ]
+
+def ext_modules(static_libs, static_cflags): 
+    if PYREX_INSTALLED:
+        source_extension = ".pyx"
+    else:
+        print ("NOTE: Trying to build without Pyrex, pre-generated "
+               "'src/lxml/etree.c' needs to be available.")
+        source_extension = ".c"
+    
+    result = []
+    _ext_args = ext_args(static_libs)
+    _cflags = cflags(static_cflags)
+    _define_macros = define_macros()
+    for module, package in EXT_MODULES:
+        result.append(
+            Extension(
+            package,
+            sources = ["src/lxml/" + module + source_extension],
+            extra_compile_args = ['-w'] + _cflags,
+            define_macros = _define_macros,
+            **_ext_args
+            ))
+    return result
+
+def extra_setup_args():
+    result = {}
+    if PYREX_INSTALLED:
+        result['cmdclass'] = {'build_ext': build_pyx}
+    return result
+
+def cflags(static_cflags):
+    if OPTION_STATIC:
+        assert static_cflags, "Static build not configured, see doc/build.txt"
+        result = static_cflags
+    else:
+        result = flags('xslt-config --cflags')
+    if OPTION_DEBUG_GCC:
+        result.append('-g2')
+    return result
+
+def define_macros():
+    if OPTION_WITHOUT_ASSERT:
+        return [('PYREX_WITHOUT_ASSERTIONS', None)]
+    return []
+
+def ext_args(static_libs):
+    if OPTION_STATIC:
+        assert static_libs, "Static build not configured, see doc/build.txt"
+        return {'extra_link_args': static_libs}
+
+    xslt_libs = flags('xslt-config --libs')
+    add_libexslt(xslt_libs)
+    
+    if OPTION_RPATH:
+        return ext_args_rpath(xslt_libs)
+    else:
+        return {'extra_link_args': xslt_libs}
+    
+def flags(cmd):
+    wf, rf, ef = os.popen3(cmd)
+    return rf.read().split()
+
+def add_libexslt(lib_flags):
+    if '-lxslt' in lib_flags:
+        xslt, exslt = '-lxslt', '-lexslt'
+    else:
+        xslt, exslt = 'xslt', 'exslt'
+    for i, libname in enumerate(lib_flags):
+        if exslt in libname:
+            return
+        if xslt in libname:
+            lib_flags.insert(i, libname.replace(xslt, exslt))
+            return
+
+def ext_args_rpath(xslt_libs):
+    library_dirs = []
+    libraries = []
+    extra_link_args = []
+    runtime_library_dirs = []
+    
+    for option in xslt_libs:
+        content = option[2:]
+        if option.startswith('-L'):
+            if not content.startswith('/usr'):
+                runtime_library_dirs.append(content)
+            library_dirs.append(content)
+        elif option.startswith('-l'):
+            libraries.append(content)
+        else:
+            extra_link_args.append(option)
+
+    return {
+        'libraries': libraries,
+        'library_dirs': library_dirs,
+        'extra_link_args': extra_link_args,
+        'runtime_library_dirs': runtime_library_dirs,
+        }
+
+def has_option(name):
+    try:
+        sys.argv.remove('--%s' % name)
+        return True
+    except ValueError:
+        return False
+
+# pick up any commandline options
+OPTION_WITHOUT_ASSERT = has_option('without-assert')
+OPTION_STATIC = has_option('static')
+OPTION_DEBUG_GCC = has_option('debug-gcc')
+OPTION_RPATH = has_option('rpath')

Added: lxml/trunk/versioninfo.py
==============================================================================
--- (empty file)
+++ lxml/trunk/versioninfo.py	Wed Nov 22 15:20:56 2006
@@ -0,0 +1,76 @@
+import os, sys, re
+
+def version():
+    return open(os.path.join(get_src_dir(), 'version.txt')).read().strip()
+
+def branch_version():
+    return version()[:3]
+
+def svn_version():
+    _version = version()
+    try:
+        svn_entries = open(
+            os.path.join(get_src_dir(), '.svn', 'entries')).read()
+        revision = re.search('<entry[^>]*name=""[^>]*revision="([^"]+)"',
+                             svn_entries).group(1)
+        result = _version + '-' + revision
+    except IOError:
+        result = _version
+
+    if 'dev' in _version:
+        result = fix_alphabeta(result, 'dev')
+    elif 'alpha' in _version:
+        result = fix_alphabeta(result, 'alpha')
+    if 'beta' in _version:
+        result = fix_alphabeta(result, 'beta')
+
+    return result
+
+def dev_status():
+    _version = version()
+    if 'dev' in _version:
+        return 'Development Status :: 3 - Alpha'
+    elif 'alpha' in _version:
+        return 'Development Status :: 3 - Alpha'
+    elif 'beta' in _version:
+        return 'Development Status :: 4 - Beta'
+    else:
+        return 'Development Status :: 5 - Production/Stable'
+
+def changes():
+    """Extract part of changelog pertaining to version.
+    """
+    _version = version()
+    f = open(os.path.join(get_src_dir(), "CHANGES.txt"), 'r')
+    lines = []
+    for line in f:
+        if line.startswith('====='):
+            if len(lines) > 1:
+                break
+        if lines:
+            lines.append(line)
+        elif line.startswith(_version):
+            lines.append(line)
+    f.close()
+    return ''.join(lines[:-1])
+
+def create_version_h(svn_version):
+    """Create lxml-version.h
+    """
+    version_h = open(
+        os.path.join(get_src_dir(), 'src', 'lxml', 'lxml-version.h'),
+        'w')
+    version_h.write('''\
+#ifndef LXML_VERSION_STRING
+#define LXML_VERSION_STRING "%s"
+#endif
+''' % svn_version)
+    version_h.close()
+
+def get_src_dir():
+    return os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]))
+
+def fix_alphabeta(version, alphabeta):
+    if ('.' + alphabeta) in version:
+        return version
+    return version.replace(alphabeta, '.' + alphabeta)


More information about the lxml-checkins mailing list