[Zope-CVS] SVN: zpkgtools/trunk/zpkg - remove the
Dependencies/Includes/ directory from distributions
Fred L. Drake, Jr.
fdrake at gmail.com
Wed Aug 10 14:30:46 EDT 2005
Log message for revision 37846:
- remove the Dependencies/Includes/ directory from distributions
- remember what Python package provided a header, so we can build it
out / install it in the right location
- add a "build_headers" command that runs before "build_ext"; this
makes the headers available in something more like the recommended
structure, and runs as part of distutils.code.setup(), avoiding
dependency on distribution construction artifacts
- extend the "build" and "build_ext" commands so "build_headers" is
run as needed
- fix base directory computation for configuration loading in the case
when no directory component is passed in
Changed:
A zpkgtools/trunk/zpkgsetup/build.py
A zpkgtools/trunk/zpkgsetup/build_ext.py
A zpkgtools/trunk/zpkgsetup/build_headers.py
U zpkgtools/trunk/zpkgsetup/dist.py
U zpkgtools/trunk/zpkgsetup/package.py
U zpkgtools/trunk/zpkgsetup/setup.py
U zpkgtools/trunk/zpkgtools/app.py
U zpkgtools/trunk/zpkgtools/config.py
-=-
Added: zpkgtools/trunk/zpkgsetup/build.py
===================================================================
--- zpkgtools/trunk/zpkgsetup/build.py 2005-08-10 18:20:20 UTC (rev 37845)
+++ zpkgtools/trunk/zpkgsetup/build.py 2005-08-10 18:30:46 UTC (rev 37846)
@@ -0,0 +1,35 @@
+"""Extended 'build' command that adds support for build_headers.
+
+"""
+__docformat__ = "reStructuredText"
+
+import distutils.command.build
+import os.path
+import sys
+
+
+class build(distutils.command.build.build):
+
+ user_options = distutils.command.build.build.user_options + [
+ ('build-headers=', None,
+ "build directory for headers"),
+ ]
+
+ def has_headers(self):
+ return self.distribution.has_headers()
+
+ # add build_headers before build_ext:
+ sub_commands = list(distutils.command.build.build.sub_commands)
+ for i in range(len(sub_commands)):
+ if sub_commands[i][0] == "build_ext":
+ sub_commands.insert(i, ("build_headers", has_headers))
+
+ def initialize_options(self):
+ distutils.command.build.build.initialize_options(self)
+ self.build_headers = None
+
+ def finalize_options(self):
+ distutils.command.build.build.finalize_options(self)
+ if self.build_headers is None:
+ self.build_headers = os.path.join(self.build_base,
+ "include-" + sys.version[0:3])
Property changes on: zpkgtools/trunk/zpkgsetup/build.py
___________________________________________________________________
Name: svn:mime-type
+ text/x-python
Name: svn:eol-style
+ native
Added: zpkgtools/trunk/zpkgsetup/build_ext.py
===================================================================
--- zpkgtools/trunk/zpkgsetup/build_ext.py 2005-08-10 18:20:20 UTC (rev 37845)
+++ zpkgtools/trunk/zpkgsetup/build_ext.py 2005-08-10 18:30:46 UTC (rev 37846)
@@ -0,0 +1,29 @@
+"""Extended build_ext command that adds support for 'built' headers.
+
+If there are any public headers for any of the packages included in
+this distribution, the build/include-X.Y/ directory is added to the
+include path of the extensions being built. This also ensures that
+the build_headers command runs before the build_ext command.
+
+"""
+__docformat__ = "reStructuredText"
+
+import distutils.command.build_ext
+import os.path
+
+
+class build_ext(distutils.command.build_ext.build_ext):
+
+ def run(self):
+ cmd = self.get_finalized_command("build_headers")
+ if cmd.package_headers:
+ self.run_command("build_headers")
+ self._extra_includes = cmd.build_dir
+ else:
+ self._extra_includes = None
+ distutils.command.build_ext.build_ext.run(self)
+
+ def build_extension(self, ext):
+ if self._extra_includes:
+ ext.include_dirs.append(self._extra_includes)
+ distutils.command.build_ext.build_ext.build_extension(self, ext)
Property changes on: zpkgtools/trunk/zpkgsetup/build_ext.py
___________________________________________________________________
Name: svn:mime-type
+ text/x-python
Name: svn:eol-style
+ native
Added: zpkgtools/trunk/zpkgsetup/build_headers.py
===================================================================
--- zpkgtools/trunk/zpkgsetup/build_headers.py 2005-08-10 18:20:20 UTC (rev 37845)
+++ zpkgtools/trunk/zpkgsetup/build_headers.py 2005-08-10 18:30:46 UTC (rev 37846)
@@ -0,0 +1,53 @@
+"""
+"""
+__docformat__ = "reStructuredText"
+
+import distutils.core
+import distutils.util
+import os.path
+
+
+class build_headers(distutils.core.Command):
+ """Command that builds out the headers into build/headers-X.Y/.
+
+ The structure of the build/headers-X.Y/ directory is analogous to
+ that of the $exec_prefix/include/pythonX.Y/ directory: each
+ package gets a corresponding directory to which its public headers
+ are copied. When the extension modules are built, this directory
+ will be added to the include search path before that containing
+ the Python headers.
+
+ """
+
+ description = "build out the public headers"
+
+ user_options = [
+ ('build-dir=', 'd', "directory to \"build\" (copy) to"),
+ ('force', 'f', "forcibly build everything (ignore file timestamps"),
+ ]
+
+ boolean_options = ['force']
+
+ def initialize_options (self):
+ self.build_dir = None
+ self.force = None
+ self.package_headers = None
+ self.outfiles = []
+
+ def finalize_options (self):
+ self.set_undefined_options('build',
+ ('build_headers', 'build_dir'),
+ ('force', 'force'))
+ self.package_headers = self.distribution.package_headers
+
+ def run(self):
+ if not self.package_headers:
+ return
+ for header in self.package_headers:
+ dir = os.path.join(self.build_dir, header.package)
+ self.mkpath(dir)
+ srcfile = distutils.util.convert_path(header.path)
+ outfile = os.path.join(
+ self.build_dir, header.package, os.path.basename(srcfile))
+ self.copy_file(srcfile, outfile)
+ self.outfiles.append(outfile)
Property changes on: zpkgtools/trunk/zpkgsetup/build_headers.py
___________________________________________________________________
Name: svn:mime-type
+ text/x-python
Name: svn:eol-style
+ native
Modified: zpkgtools/trunk/zpkgsetup/dist.py
===================================================================
--- zpkgtools/trunk/zpkgsetup/dist.py 2005-08-10 18:20:20 UTC (rev 37845)
+++ zpkgtools/trunk/zpkgsetup/dist.py 2005-08-10 18:30:46 UTC (rev 37846)
@@ -19,7 +19,11 @@
import distutils.extension
import sys
+import zpkgsetup.build
+import zpkgsetup.build_ext
+import zpkgsetup.build_headers
+
class ZPkgExtension(distutils.extension.Extension):
"""Distutils representation of a compiled extension module."""
@@ -29,9 +33,16 @@
def __init__ (self, attrs=None):
self.package_data = None
+ self.package_headers = attrs.pop("package_headers", ())
distutils.dist.Distribution.__init__(self, attrs)
if self.package_data and sys.version_info < (2, 4):
from zpkgsetup.build_py import build_py
from zpkgsetup.install_lib import install_lib
self.cmdclass.setdefault('build_py', build_py)
self.cmdclass.setdefault('install_lib', install_lib)
+ self.cmdclass.setdefault('build',
+ zpkgsetup.build.build)
+ self.cmdclass.setdefault('build_ext',
+ zpkgsetup.build_ext.build_ext)
+ self.cmdclass.setdefault('build_headers',
+ zpkgsetup.build_headers.build_headers)
Modified: zpkgtools/trunk/zpkgsetup/package.py
===================================================================
--- zpkgtools/trunk/zpkgsetup/package.py 2005-08-10 18:20:20 UTC (rev 37845)
+++ zpkgtools/trunk/zpkgsetup/package.py 2005-08-10 18:30:46 UTC (rev 37846)
@@ -75,6 +75,17 @@
PACKAGE_CONF = "SETUP.cfg"
+class Header(object):
+ """Information about a header file and the package that provides it."""
+
+ def __init__(self, package, path):
+ self.package = package
+ self.path = path
+
+ def __repr__(self):
+ return "<Header(%r, %r)>" % (self.package, self.path)
+
+
def loadPackageInfo(pkgname, directory, reldir):
"""Load package information for a Python package.
@@ -93,6 +104,8 @@
pkginfo = read_package_info(directory, reldir)
pkginfo.extensions = [create_extension(ext, pkgname, reldir)
for ext in pkginfo.extension]
+ pkginfo.package_headers = [Header(pkgname, path)
+ for path in pkginfo.header]
return pkginfo
@@ -112,6 +125,8 @@
if pkginfo.extension:
raise ValueError("extensions cannot be defined in collections")
pkginfo.extensions = []
+ pkginfo.package_headers = [Header(pkgname, path)
+ for path in pkginfo.header]
return pkginfo
Modified: zpkgtools/trunk/zpkgsetup/setup.py
===================================================================
--- zpkgtools/trunk/zpkgsetup/setup.py 2005-08-10 18:20:20 UTC (rev 37845)
+++ zpkgtools/trunk/zpkgsetup/setup.py 2005-08-10 18:30:46 UTC (rev 37846)
@@ -66,6 +66,7 @@
self.packages = []
self.package_data = {}
self.package_dir = {}
+ self.package_headers = []
self.ext_modules = []
self.scripts = []
self.platforms = None
@@ -85,7 +86,7 @@
depnames = os.listdir(depsdir)
suffix = "-%s-%s" % (self._pkgname, self.version)
for name in depnames:
- if name != "Includes" and not name.endswith(suffix):
+ if not name.endswith(suffix):
# an unexpected name; we didn't put this here!
print >>sys.stderr, \
"unexpected name in Dependencies/: %r" % name
@@ -100,10 +101,6 @@
pkgdir = os.path.join(depdir, depname)
reldir = posixpath.join("Dependencies", name, depname)
self.scan(depname, pkgdir, reldir)
- includes_dir = os.path.join(depsdir, "Includes")
- if os.path.isdir(includes_dir):
- for ext in self.ext_modules:
- ext.include_dirs.append(includes_dir)
def setup(self):
kwargs = self.__dict__.copy()
@@ -223,6 +220,7 @@
self.add_package_file(pkgname, posixpath.join(reldir, fn))
def scan_basic(self, pkginfo):
+ self.package_headers.extend(pkginfo.package_headers)
self.scripts.extend(pkginfo.script)
if pkginfo.data_files:
if self.data_files:
Modified: zpkgtools/trunk/zpkgtools/app.py
===================================================================
--- zpkgtools/trunk/zpkgtools/app.py 2005-08-10 18:20:20 UTC (rev 37845)
+++ zpkgtools/trunk/zpkgtools/app.py 2005-08-10 18:30:46 UTC (rev 37846)
@@ -173,7 +173,6 @@
component.write_setup_py(pathparts=["..", ".."],
distclass=distclass)
component.write_setup_cfg()
- self.add_headers(component)
if self.options.application:
top.write_setup_py(filename="install.py",
version=self.options.version,
@@ -190,22 +189,6 @@
except zpkgtools.Error, e:
self.error(str(e), rc=1)
- def add_headers(self, component):
- pkginfo = component.get_package_info()
- if not pkginfo.header:
- return
- includes_dir = os.path.join(self.destination,
- "Dependencies", "Includes")
- if not os.path.isdir(includes_dir):
- os.mkdir(includes_dir)
- for src in pkginfo.header:
- src = os.path.join(component.destination, *src.split("/"))
- name = os.path.basename(src)
- path = os.path.join(includes_dir, name)
- if os.path.exists(path):
- self.error("multiple headers with name %r" % name)
- self.ip.copy_file(src, path)
-
def add_manifest(self, destination):
self.ip.add_manifest(destination)
self.ip.add_output(os.path.join(destination, "MANIFEST"))
Modified: zpkgtools/trunk/zpkgtools/config.py
===================================================================
--- zpkgtools/trunk/zpkgtools/config.py 2005-08-10 18:20:20 UTC (rev 37845)
+++ zpkgtools/trunk/zpkgtools/config.py 2005-08-10 18:30:46 UTC (rev 37846)
@@ -140,9 +140,14 @@
paths found in the configuration file.
"""
- p = cfgparser.Parser(f, path, Schema(path, self.locations))
+ if basedir:
+ basedir = os.path.abspath(basedir)
+ else:
+ basedir = os.getcwd()
+ p = cfgparser.Parser(f, path, Schema(os.path.abspath(path),
+ self.locations))
cf = p.load()
- base = urlutils.file_url(os.path.abspath(basedir)) + "/"
+ base = urlutils.file_url(basedir) + "/"
for value in cf.resource_map:
value = urlparse.urljoin(base, value)
self.location_maps.append(value)
More information about the Zope-CVS
mailing list