[Checkins] SVN: zc.buildout/branches/dev/ Added a develop recipe.
Jim Fulton
jim at zope.com
Mon Dec 4 15:01:33 EST 2006
Log message for revision 71394:
Added a develop recipe.
Added support for all reasonable build_ext options to the build and
develop recipes.
The build and develop functions and recipes now return the paths
created.
Changed:
U zc.buildout/branches/dev/src/zc/buildout/easy_install.py
U zc.buildout/branches/dev/src/zc/buildout/easy_install.txt
U zc.buildout/branches/dev/src/zc/buildout/tests.py
U zc.buildout/branches/dev/zc.recipe.egg_/setup.py
U zc.buildout/branches/dev/zc.recipe.egg_/src/zc/recipe/egg/__init__.py
U zc.buildout/branches/dev/zc.recipe.egg_/src/zc/recipe/egg/custom.py
U zc.buildout/branches/dev/zc.recipe.egg_/src/zc/recipe/egg/custom.txt
-=-
Modified: zc.buildout/branches/dev/src/zc/buildout/easy_install.py
===================================================================
--- zc.buildout/branches/dev/src/zc/buildout/easy_install.py 2006-12-04 16:28:38 UTC (rev 71393)
+++ zc.buildout/branches/dev/src/zc/buildout/easy_install.py 2006-12-04 20:01:32 UTC (rev 71394)
@@ -407,12 +407,15 @@
dist = _satisfied(requirement, env, dest, executable, index_url, links)
if dist is not None:
- return dist
+ return [dist.location]
- # Get an editable version of the package to a temporary directory:
- tmp = tempfile.mkdtemp('build')
- tmp2 = tempfile.mkdtemp('build')
+ undo = []
try:
+ tmp = tempfile.mkdtemp('build')
+ undo.append(lambda : shutil.rmtree(tmp))
+ tmp2 = tempfile.mkdtemp('build')
+ undo.append(lambda : shutil.rmtree(tmp2))
+
index = _get_index(executable, index_url, links)
dist = index.fetch_distribution(requirement, tmp2, False, True)
if dist is None:
@@ -445,13 +448,40 @@
setuptools.command.setopt.edit_config(
setup_cfg, dict(build_ext=build_ext))
- # Now run easy_install for real:
+ tmp3 = tempfile.mkdtemp('build', dir=dest)
+ undo.append(lambda : shutil.rmtree(tmp3))
+
_call_easy_install(base, env, pkg_resources.WorkingSet(),
- dest, links, index_url, executable, True)
+ tmp3, links, index_url, executable, True)
+
+ return _copyeggs(tmp3, dest, '.egg', undo)
+
finally:
- shutil.rmtree(tmp)
- shutil.rmtree(tmp2)
+ undo.reverse()
+ [f() for f in undo]
+
+def _rm(*paths):
+ for path in paths:
+ if os.path.isdir(path):
+ shutil.rmtree(path)
+ else:
+ os.remove(path)
+
+def _copyeggs(src, dest, suffix, undo):
+ result = []
+ undo.append(lambda : _rm(*result))
+ for name in os.listdir(src):
+ if name.endswith(suffix):
+ new = os.path.join(dest, name)
+ os.rename(os.path.join(src, name), new)
+ result.append(new)
+
+ assert len(result) == 1
+ undo.pop()
+
+ return result[0]
+
def develop(setup, dest,
build_ext=None,
executable=sys.executable):
@@ -490,10 +520,13 @@
__file__ = setup,
))
+ tmp3 = tempfile.mkdtemp('build', dir=dest)
+ undo.append(lambda : shutil.rmtree(tmp3))
+
args = [
zc.buildout.easy_install._safe_arg(tsetup),
'-q', 'develop', '-mxN',
- '-d', _safe_arg(dest),
+ '-d', _safe_arg(tmp3),
]
log_level = logger.getEffectiveLevel()
@@ -506,6 +539,8 @@
assert os.spawnl(os.P_WAIT, executable, executable, *args) == 0
+ return _copyeggs(tmp3, dest, '.egg-link', undo)
+
finally:
undo.reverse()
[f() for f in undo]
Modified: zc.buildout/branches/dev/src/zc/buildout/easy_install.txt
===================================================================
--- zc.buildout/branches/dev/src/zc/buildout/easy_install.txt 2006-12-04 16:28:38 UTC (rev 71393)
+++ zc.buildout/branches/dev/src/zc/buildout/easy_install.txt 2006-12-04 20:01:32 UTC (rev 71394)
@@ -489,9 +489,10 @@
{
PyObject *m;
m = Py_InitModule3("extdemo", methods, "");
+ #ifdef TWO
+ PyModule_AddObject(m, "val", PyInt_FromLong(2));
+ #else
PyModule_AddObject(m, "val", PyInt_FromLong(EXTDEMO));
- #ifdef VAL2
- PyModule_AddObject(m, "val2", PyInt_FromLong(2));
#endif
}
@@ -514,7 +515,10 @@
... 'extdemo', dest,
... {'include-dirs': os.path.join(sample_buildout, 'include')},
... links=[link_server], index=link_server+'index/')
+ '/sample-install/extdemo-1.4-py2.4-unix-i686.egg'
+The function returns the list of eggs
+
Now if we look in our destination directory, we see we have an extdemo egg:
>>> ls(dest)
@@ -563,7 +567,10 @@
>>> zc.buildout.easy_install.develop(
... extdemo, dest,
... {'include-dirs': os.path.join(sample_buildout, 'include')})
+ '/sample-install/extdemo.egg-link'
+The name of the egg link created is returned.
+
Now if we look in our destination directory, we see we have an extdemo
egg link:
Modified: zc.buildout/branches/dev/src/zc/buildout/tests.py
===================================================================
--- zc.buildout/branches/dev/src/zc/buildout/tests.py 2006-12-04 16:28:38 UTC (rev 71393)
+++ zc.buildout/branches/dev/src/zc/buildout/tests.py 2006-12-04 20:01:32 UTC (rev 71394)
@@ -730,6 +730,7 @@
>>> zc.buildout.easy_install.develop(
... extdemo, dest,
... {'include-dirs': os.path.join(sample_buildout, 'include')})
+ '/tmp/tmp7AFYXv/_TEST_/dest/extdemo.egg-link'
>>> ls(dest)
- extdemo.egg-link
@@ -807,9 +808,10 @@
{
PyObject *m;
m = Py_InitModule3("extdemo", methods, "");
+#ifdef TWO
+ PyModule_AddObject(m, "val", PyInt_FromLong(2));
+#else
PyModule_AddObject(m, "val", PyInt_FromLong(EXTDEMO));
-#ifdef VAL2
- PyModule_AddObject(m, "val2", PyInt_FromLong(2));
#endif
}
"""
Modified: zc.buildout/branches/dev/zc.recipe.egg_/setup.py
===================================================================
--- zc.buildout/branches/dev/zc.recipe.egg_/setup.py 2006-12-04 16:28:38 UTC (rev 71393)
+++ zc.buildout/branches/dev/zc.recipe.egg_/setup.py 2006-12-04 20:01:32 UTC (rev 71394)
@@ -42,7 +42,9 @@
tests_require = ['zope.testing'],
test_suite = name+'.tests.test_suite',
entry_points = {'zc.buildout': ['default = %s:Egg' % name,
+ 'script = %s:Egg' % name,
'custom = %s:Custom' % name,
+ 'develop = %s:Develop' % name,
]
},
zip_safe=False,
Modified: zc.buildout/branches/dev/zc.recipe.egg_/src/zc/recipe/egg/__init__.py
===================================================================
--- zc.buildout/branches/dev/zc.recipe.egg_/src/zc/recipe/egg/__init__.py 2006-12-04 16:28:38 UTC (rev 71393)
+++ zc.buildout/branches/dev/zc.recipe.egg_/src/zc/recipe/egg/__init__.py 2006-12-04 20:01:32 UTC (rev 71394)
@@ -1,2 +1,2 @@
from zc.recipe.egg.egg import Egg
-from zc.recipe.egg.custom import Custom
+from zc.recipe.egg.custom import Custom, Develop
Modified: zc.buildout/branches/dev/zc.recipe.egg_/src/zc/recipe/egg/custom.py
===================================================================
--- zc.buildout/branches/dev/zc.recipe.egg_/src/zc/recipe/egg/custom.py 2006-12-04 16:28:38 UTC (rev 71393)
+++ zc.buildout/branches/dev/zc.recipe.egg_/src/zc/recipe/egg/custom.py 2006-12-04 20:01:32 UTC (rev 71394)
@@ -19,12 +19,27 @@
import os, re, zipfile
import zc.buildout.easy_install
-class Custom:
+class Base:
def __init__(self, buildout, name, options):
- self.buildout = buildout
- self.name = name
- self.options = options
+ self.name, self.options = name, options
+
+ options['_d'] = buildout['buildout']['develop-eggs-directory']
+
+ python = options.get('python', buildout['buildout']['python'])
+ options['executable'] = buildout[python]['executable']
+
+ self.build_ext = build_ext(buildout, options)
+
+
+ def update(self):
+ return self.install()
+
+class Custom(Base):
+
+ def __init__(self, buildout, name, options):
+ Base.__init__(self, buildout, name, options)
+
links = options.get('find-links',
buildout['buildout'].get('find-links'))
if links:
@@ -39,47 +54,66 @@
options['index'] = index
self.index = index
- options['_b'] = buildout['buildout']['bin-directory']
options['_e'] = buildout['buildout']['eggs-directory']
- options['_d'] = buildout['buildout']['develop-eggs-directory']
assert options.get('unzip') in ('true', 'false', None)
- python = options.get('python', buildout['buildout']['python'])
- options['executable'] = buildout[python]['executable']
+ if buildout['buildout'].get('offline') == 'true':
+ self.install = lambda: ()
- build_ext = {}
- for be_option in ('include-dirs', 'library-dirs', 'rpath'):
- value = options.get(be_option)
- if value is None:
- continue
- value = [
- os.path.join(
- buildout['buildout']['directory'],
- v.strip()
- )
- for v in value.strip().split('\n')
- if v.strip()
- ]
- build_ext[be_option] = ':'.join(value)
- options[be_option] = ':'.join(value)
- self.build_ext = build_ext
-
def install(self):
- if self.buildout['buildout'].get('offline') == 'true':
- return ()
options = self.options
distribution = options.get('eggs', self.name).strip()
- build_ext = dict([
- (k, options[k])
- for k in ('include-dirs', 'library-dirs', 'rpath')
- if k in options
- ])
- zc.buildout.easy_install.build(
+ return zc.buildout.easy_install.build(
distribution, options['_d'], self.build_ext,
self.links, self.index, options['executable'], [options['_e']],
)
- return ()
+class Develop(Base):
- update = install
+ def __init__(self, buildout, name, options):
+ Base.__init__(self, buildout, name, options)
+ options['setup'] = os.path.join(buildout['buildout']['directory'],
+ options['setup'])
+
+ def install(self):
+ options = self.options
+ return zc.buildout.easy_install.develop(
+ options['setup'], options['_d'], self.build_ext,
+ options['executable'],
+ )
+
+
+def build_ext(buildout, options):
+ result = {}
+ for be_option in ('include-dirs', 'library-dirs', 'rpath'):
+ value = options.get(be_option)
+ if value is None:
+ continue
+ value = [
+ os.path.join(
+ buildout['buildout']['directory'],
+ v.strip()
+ )
+ for v in value.strip().split('\n')
+ if v.strip()
+ ]
+ result[be_option] = os.pathsep.join(value)
+ options[be_option] = os.pathsep.join(value)
+
+ swig = options.get('swig')
+ if swig:
+ options['swig'] = result['swig'] = os.path.join(
+ buildout['buildout']['directory'],
+ swig,
+ )
+
+ for be_option in ('define', 'undef', 'libraries', 'link-objects',
+ 'debug', 'force', 'compiler', 'swig-cpp', 'swig-opts',
+ ):
+ value = options.get(be_option)
+ if value is None:
+ continue
+ result[be_option] = value
+
+ return result
Modified: zc.buildout/branches/dev/zc.recipe.egg_/src/zc/recipe/egg/custom.txt
===================================================================
--- zc.buildout/branches/dev/zc.recipe.egg_/src/zc/recipe/egg/custom.txt 2006-12-04 16:28:38 UTC (rev 71393)
+++ zc.buildout/branches/dev/zc.recipe.egg_/src/zc/recipe/egg/custom.txt 2006-12-04 20:01:32 UTC (rev 71394)
@@ -1,5 +1,5 @@
-Custon eggs
-===========
+Creating eggs with extensions neededing custom build settings
+=============================================================
Sometimes, It's necessary to provide extra control over how an egg is
created. This is commonly true for eggs with extension modules that
@@ -20,6 +20,42 @@
A new-line separated list of directories to search for dynamic libraries
at run time.
+define
+ A comma-separated list of names of C preprocessor variables to
+ define.
+
+undef
+ A comman separated list of names of C preprocessor variables to
+ undefine.
+
+libraries
+ The name of an additional library to link with. Due to limitations
+ in distutils and desprite the option name, only a single library
+ can be specified.
+
+link-objects
+ The name of an link object to link afainst. Due to limitations
+ in distutils and desprite the option name, only a single link object
+ can be specified.
+
+debug
+ Compile/link with debugging information
+
+force
+ Forcibly build everything (ignore file timestamps)
+
+compiler
+ Specify the compiler type
+
+swig
+ The path to the swig executable
+
+swig-cpp
+ Make SWIG create C++ files (default is C)
+
+swig-opts
+ List of SWIG command line options
+
In addition, the following options can be used to specify the egg:
egg
@@ -59,9 +95,10 @@
{
PyObject *m;
m = Py_InitModule3("extdemo", methods, "");
+ #ifdef TWO
+ PyModule_AddObject(m, "val", PyInt_FromLong(2));
+ #else
PyModule_AddObject(m, "val", PyInt_FromLong(EXTDEMO));
- #ifdef VAL2
- PyModule_AddObject(m, "val2", PyInt_FromLong(2));
#endif
}
@@ -162,3 +199,131 @@
>>> print system(join('bin', 'demo')),
42
+
+Controlling develop-egg generation
+==================================
+
+If you want to provide custom build options for a develop egg, you can
+use the develop recipe. The recipe has the following options:
+
+path
+ The path to a setup script or directory containing a startup
+ script. This is required.
+
+include-dirs
+ A new-line separated list of directories to search for include
+ files.
+
+library-dirs
+ A new-line separated list of directories to search for libraries
+ to link with.
+
+rpath
+ A new-line separated list of directories to search for dynamic libraries
+ at run time.
+
+define
+ A comma-separated list of names of C preprocessor variables to
+ define.
+
+undef
+ A comman separated list of names of C preprocessor variables to
+ undefine.
+
+libraries
+ The name of an additional library to link with. Due to limitations
+ in distutils and desprite the option name, only a single library
+ can be specified.
+
+link-objects
+ The name of an link object to link afainst. Due to limitations
+ in distutils and desprite the option name, only a single link object
+ can be specified.
+
+debug
+ Compile/link with debugging information
+
+force
+ Forcibly build everything (ignore file timestamps)
+
+compiler
+ Specify the compiler type
+
+swig
+ The path to the swig executable
+
+swig-cpp
+ Make SWIG create C++ files (default is C)
+
+swig-opts
+ List of SWIG command line options
+
+python
+ The name of a section to get the Python executable from.
+ If not specified, then the buildout python option is used. The
+ Python executable is found in the executable option of the named
+ section.
+
+To illustrate this, we'll use a directory containing the extdemo
+example from the earlier section:
+
+ >>> ls(extdemo)
+ - MANIFEST
+ - MANIFEST.in
+ - README
+ - extdemo.c
+ - setup.py
+
+ >>> write('buildout.cfg',
+ ... """
+ ... [buildout]
+ ... develop = demo
+ ... parts = extdemo demo
+ ...
+ ... [extdemo]
+ ... setup = %(extdemo)s
+ ... recipe = zc.recipe.egg:develop
+ ... include-dirs = include
+ ... define = TWO
+ ...
+ ... [demo]
+ ... recipe = zc.recipe.egg
+ ... eggs = demo
+ ... extdemo
+ ... entry-points = demo=demo:main
+ ... """ % dict(extdemo=extdemo))
+
+Note that we added a define option to cause the preprocessor variable
+TWO to be defined. This will cause the module-variable, 'val', to be
+set with a value of 2.
+
+ >>> print system(buildout),
+ buildout: Develop: /tmp/tmpCXjRps/_TEST_/sample-buildout/demo
+ buildout: Uninstalling extdemo
+ buildout: Installing extdemo
+ buildout: Updating demo
+
+Our develop-eggs now includes an egg link for extdemo:
+
+ >>> ls('develop-eggs')
+ - demo.egg-link
+ - extdemo.egg-link
+ - zc.recipe.egg.egg-link
+
+and the extdemo now has a built extension:
+
+ >>> ls(extdemo)
+ - MANIFEST
+ - MANIFEST.in
+ - README
+ d build
+ - extdemo.c
+ d extdemo.egg-info
+ - extdemo.so
+ - setup.py
+
+Because develop eggs take precedence over non-develop eggs, the demo
+script will use the new develop egg:
+
+ >>> print system(join('bin', 'demo')),
+ 2
More information about the Checkins
mailing list