summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatteo Bertozzi <theo.bertozzi@gmail.com>2011-08-24 19:50:13 +0200
committerMatteo Bertozzi <theo.bertozzi@gmail.com>2011-08-24 19:50:13 +0200
commit486113ca8aed244ad5468f0e0da932ffcc243e66 (patch)
treefc3044691c0169d69226e97f4af7e40327110f28
parent443e5b307b1ceca0790e42f527db4c570e8ed7a8 (diff)
downloadpython-lxml-486113ca8aed244ad5468f0e0da932ffcc243e66.tar.gz
patch that copies headers only if --static is
specified, also works with python 2.3. Tested with: LINUX: python setup.py build --static --static-deps install WINDOWS: python setup.py bdist_wininst --static
-rw-r--r--buildlibxml.py18
-rw-r--r--setup.py147
-rw-r--r--src/lxml/__init__.py15
3 files changed, 162 insertions, 18 deletions
diff --git a/buildlibxml.py b/buildlibxml.py
index bfcf3e41..acef12f3 100644
--- a/buildlibxml.py
+++ b/buildlibxml.py
@@ -115,7 +115,7 @@ def download_libiconv(dest_dir, version=None):
return download_library(dest_dir, LIBICONV_LOCATION, 'libiconv',
version_re, filename, version=version)
-def download_library(dest_dir, location, name, version_re, filename,
+def download_library(dest_dir, location, name, version_re, filename,
version=None):
if version is None:
try:
@@ -227,11 +227,23 @@ def unpack_tarball(tar_filename, dest):
return os.path.join(dest, base_dir)
def call_subprocess(cmd, **kw):
- import subprocess
+ try:
+ from subprocess import proc_call
+ except ImportError:
+ # no subprocess for Python 2.3
+ def proc_call(cmd, **kwargs):
+ cwd = kwargs.get('cwd', '.')
+ old_cwd = os.getcwd()
+ try:
+ os.chdir(cwd)
+ return os.system(' '.join(cmd))
+ finally:
+ os.chdir(old_cwd)
+
cwd = kw.get('cwd', '.')
cmd_desc = ' '.join(cmd)
log.info('Running "%s" in %s' % (cmd_desc, cwd))
- returncode = subprocess.call(cmd, **kw)
+ returncode = proc_call(cmd, **kw)
if returncode:
raise Exception('Command "%s" returned code %s' % (cmd_desc, returncode))
diff --git a/setup.py b/setup.py
index 378391f6..17f3c6ba 100644
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,6 @@
import sys, os
+import fnmatch
+import glob
# for command line options and supported environment variables, please
# see the end of 'setupinfo.py'
@@ -62,14 +64,6 @@ if versioninfo.is_pre_release():
extra_options.update(setupinfo.extra_setup_args())
-# FIXME: make this work with Py2.3
-## if sys.version_info < (2,4):
-## extra_options['data_files'] = [
-## (os.path.dirname(os.path.join(install_base_dir, pattern)),
-## [ f for f in glob.glob(pattern) ])
-## for pattern in patterns
-## ]
-## else:
extra_options['package_data'] = {
'lxml': [
'etreepublic.pxd',
@@ -78,12 +72,140 @@ extra_options['package_data'] = {
],
'lxml.isoschematron': [
'resources/rng/iso-schematron.rng',
- 'resources/xsl/*.xsl',
+ 'resources/xsl/*.xsl',
'resources/xsl/iso-schematron-xslt1/*.xsl',
'resources/xsl/iso-schematron-xslt1/readme.txt'
],
}
+extra_options['package_dir'] = {
+ '': 'src'
+ }
+
+extra_options['packages'] = [
+ 'lxml', 'lxml.html', 'lxml.isoschematron'
+ ]
+
+extra_options['package_dir'] = {
+ '': 'src'
+ }
+
+extra_options['packages'] = [
+ 'lxml', 'lxml.html', 'lxml.isoschematron'
+ ]
+
+
+def setup_extra_options():
+ try:
+ set
+ except NameError:
+ from sets import Set as set
+
+ def basePath(paths):
+ if not len(paths):
+ return ''
+
+ base_path = paths[0]
+ while base_path:
+ base_path = os.path.dirname(base_path)
+ for p in paths:
+ if not p.startswith(base_path):
+ break
+ else:
+ return base_path
+ return base_path
+
+ def removeBaseDirs(directories):
+ filtered_dirs = []
+ for dir_path in directories:
+ for p in directories:
+ if dir_path is not p and p.startswith(dir_path):
+ break
+ else:
+ filtered_dirs.append(dir_path)
+ return filtered_dirs
+
+ def extractFiles(directories, pattern='*'):
+ get_files = lambda root, files: [os.path.join(root, f) for f in files]
+
+ file_list = []
+ for dir_path in directories:
+ for root, dirs, files in os.walk(dir_path):
+ file_list.extend(get_files(root, fnmatch.filter(files, pattern)))
+ file_list.extend(extractFiles(get_files(root, dirs), pattern))
+ return file_list
+
+ # Copy Global Extra Options
+ extra_opts = dict(extra_options)
+
+ # Build ext modules
+ ext_modules = setupinfo.ext_modules(
+ STATIC_INCLUDE_DIRS, STATIC_LIBRARY_DIRS,
+ STATIC_CFLAGS, STATIC_BINARIES)
+ extra_opts['ext_modules'] = ext_modules
+
+ packages = extra_opts.get('packages', list())
+ package_dir = extra_opts.get('package_dir', dict())
+ package_data = extra_opts.get('package_data', dict())
+
+ if sys.version_info < (2, 4):
+ # Python 2.3 hasn't package_data:
+ # Migrate from package_data to data_files
+ def _packageDataToDataFiles(key, values):
+ key_path = key.replace('.', '/')
+ dst_path = os.path.join(install_base_dir, key_path)
+ src = 'src/' + key_path
+ files = [f for v in values for f in glob.glob(os.path.join(src, v))]
+ return (dst_path, files)
+
+ from distutils.sysconfig import get_python_lib
+ install_base_dir = get_python_lib(prefix='')
+ data_files = extra_opts.setdefault('data_files', [])
+ package_data = extra_opts.pop('package_data')
+ for key, values in package_data.iteritems():
+ data_files.append(_packageDataToDataFiles(key, values))
+
+ # Add lxml.include with (lxml, libxslt headers...)
+ # python setup.py build --static --static-deps install
+ # python setup.py bdist_wininst --static
+ if setupinfo.OPTION_STATIC:
+ include_dirs = set()
+ for extension in ext_modules:
+ include_dirs |= set(extension.include_dirs)
+ include_dirs = removeBaseDirs(include_dirs)
+
+ include_base = basePath(include_dirs)
+ headers = [path for path in extractFiles(include_dirs)]
+
+ if sys.version_info < (2, 4):
+ def _headersToDataFiles(key, fheaders):
+ key_path = key.replace('.', '/')
+ dst_path = os.path.join(install_base_dir, key_path)
+ headers = {}
+ for full_path in fheaders:
+ fpath, fhead = os.path.split(full_path)
+ fpath, fdir = os.path.split(fpath)
+ dst_dir = os.path.join(dst_path, fdir)
+ headers.setdefault(dst_dir, []).append(full_path)
+ return headers.items()
+
+ data_files.extend(_headersToDataFiles('lxml.include', headers))
+ else:
+ files = {}
+ for full_path in headers:
+ fpath, fhead = os.path.split(full_path)
+ _, fdir = os.path.split(fpath)
+ files.setdefault((fpath, fdir), []).append(fhead)
+
+ package_dir['lxml.include'] = include_base
+ packages.append('lxml.include')
+ for (fpath, fdir), fhs in files.iteritems():
+ kdir = 'lxml.include.' + fdir
+ package_data[kdir] = fhs
+ package_dir[kdir] = fpath
+ packages.append(kdir)
+
+ return extra_opts
setup(
name = "lxml",
@@ -143,12 +265,7 @@ an appropriate version of Cython installed.
'Topic :: Software Development :: Libraries :: Python Modules'
],
- package_dir = {'': 'src'},
- packages = ['lxml', 'lxml.html', 'lxml.isoschematron'],
- ext_modules = setupinfo.ext_modules(
- STATIC_INCLUDE_DIRS, STATIC_LIBRARY_DIRS,
- STATIC_CFLAGS, STATIC_BINARIES),
- **extra_options
+ **setup_extra_options()
)
if OPTION_RUN_TESTS:
diff --git a/src/lxml/__init__.py b/src/lxml/__init__.py
index 32802e23..ca9e6434 100644
--- a/src/lxml/__init__.py
+++ b/src/lxml/__init__.py
@@ -1,2 +1,17 @@
# this is a package
+import os
+
+def get_include():
+ """
+ Returns a list of include path (libxml2, libxslt) needed to lxml.
+ """
+ lxml_path = __path__[0]
+ include_path = os.path.join(lxml_path, 'include')
+ includes = [lxml_path]
+
+ for name in os.listdir(include_path):
+ includes.append(os.path.join(include_path, name))
+
+ return includes
+