Commit 28050f25 authored by Kai Lautaportti's avatar Kai Lautaportti

New feature to facilitate building Perl projects.

parent 0e15e9a9
Change History Change History
************** **************
1.2.0
=====
- Added new ``configure-command`` option to control the command used to
generate the ``Makefile``. This makes it possible to build slightly
different packages, e.g. Perl projects where Makefile.PL replaces the
configure script.
1.1.1 1.1.1
===== =====
......
...@@ -31,6 +31,13 @@ make-targets ...@@ -31,6 +31,13 @@ make-targets
need to use this if you want to build alternate targets. Each need to use this if you want to build alternate targets. Each
target must be given on a separate line. target must be given on a separate line.
configure-command
Name of the configure command that will be run to generate the Makefile.
This defaults to ``./configure`` which is fine for packages that come with
a configure script. You may wish to change this when compiling packages
with a different set up. See the ``Compiling a Perl package`` section for
an example.
configure-options configure-options
Extra options to be given to the ``configure`` script. By default Extra options to be given to the ``configure`` script. By default
only the ``--prefix`` option is passed which is set to the part only the ``--prefix`` option is passed which is set to the part
...@@ -101,6 +108,7 @@ We'll use a simple tarball to demonstrate the recipe. ...@@ -101,6 +108,7 @@ We'll use a simple tarball to demonstrate the recipe.
>>> import os.path >>> import os.path
>>> src = join(os.path.dirname(__file__), 'testdata') >>> src = join(os.path.dirname(__file__), 'testdata')
>>> ls(src) >>> ls(src)
- Foo-Bar-0.0.0.tar.gz
- package-0.0.0.tar.gz - package-0.0.0.tar.gz
The package contains a dummy ``configure`` script that will simply The package contains a dummy ``configure`` script that will simply
...@@ -133,6 +141,35 @@ default build options. ...@@ -133,6 +141,35 @@ default build options.
As we can see the configure script was called with the ``--prefix`` As we can see the configure script was called with the ``--prefix``
option by default followed by calls to ``make`` and ``make install``. option by default followed by calls to ``make`` and ``make install``.
Installing a Perl package
=========================
The recipe can be used to install packages that use a slightly different build
process. Perl packages often come with a ``Makefile.PL`` scripts that performs
the same task as a ``configure`` script and generates a ``Makefile``.
We can build and install such a package by overriding the ``configure-command``
option. The following example builds a Foo::Bar perl module and installs it in
a custom location within the buildout::
>>> write('buildout.cfg',
... """
... [buildout]
... parts = foobar
... perl_lib = ${buildout:directory}/perl_lib
...
... [foobar]
... recipe = hexagonit.recipe.cmmi
... configure-command = perl -I${buildout:perl_lib}/lib/perl5 Makefile.PL INSTALL_BASE=${buildout:perl_lib}
... url = file://%s/Foo-Bar-0.0.0.tar.gz
... """ % src)
>>> print system(buildout)
Uninstalling package.
Installing foobar.
foobar: Extracting package to /sample_buildout/parts/foobar__compile__
building package
installing package
Installing checkouts Installing checkouts
==================== ====================
...@@ -165,7 +202,7 @@ filesystem and building that. ...@@ -165,7 +202,7 @@ filesystem and building that.
... """ % checkout_dir) ... """ % checkout_dir)
>>> print system(buildout) >>> print system(buildout)
Uninstalling package. Uninstalling foobar.
Installing package. Installing package.
package: Using local source directory: /checkout/package-0.0.0 package: Using local source directory: /checkout/package-0.0.0
configure --prefix=/sample_buildout/parts/package configure --prefix=/sample_buildout/parts/package
......
import zc.buildout import hexagonit.recipe.download
import urlparse
import tempfile
import logging
import urllib
import shutil
import md5
import imp import imp
import logging
import os import os
import shutil
import hexagonit.recipe.download import zc.buildout
class Recipe: class Recipe:
"""zc.buildout recipe for compiling and installing software""" """zc.buildout recipe for compiling and installing software"""
...@@ -64,7 +59,12 @@ class Recipe: ...@@ -64,7 +59,12 @@ class Recipe:
make_cmd = self.options.get('make-binary', 'make').strip() make_cmd = self.options.get('make-binary', 'make').strip()
make_targets = ' '.join(self.options.get('make-targets', 'install').split()) make_targets = ' '.join(self.options.get('make-targets', 'install').split())
configure_options = ' '.join(self.options.get('configure-options','').split()) configure_cmd = self.options.get('configure-command', './configure')
configure_options = self.options.get('configure-options','').split()
# Add the prefix only if we're using a configure script
if 'configure' in configure_cmd:
configure_options.insert(0, '--prefix=%s' % self.options['prefix'])
patch_cmd = self.options.get('patch-binary', 'patch').strip() patch_cmd = self.options.get('patch-binary', 'patch').strip()
patch_options = ' '.join(self.options.get('patch-options', '-p0').split()) patch_options = ' '.join(self.options.get('patch-options', '-p0').split())
...@@ -90,14 +90,20 @@ class Recipe: ...@@ -90,14 +90,20 @@ class Recipe:
os.mkdir(self.options['location']) os.mkdir(self.options['location'])
os.chdir(compile_dir) os.chdir(compile_dir)
def is_build_dir():
return os.path.isfile('configure') or os.path.isfile('Makefile.PL')
try: try:
if not os.path.isfile('configure'): if not is_build_dir():
contents = os.listdir(compile_dir) contents = os.listdir(compile_dir)
if len(contents) == 1: if len(contents) == 1:
os.chdir(contents[0]) os.chdir(contents[0])
if not os.path.isfile('configure'): if not is_build_dir():
log.error('Unable to find the configure script') log.error('Unable to find the configure script')
raise zc.buildout.UserError('Invalid package contents') raise zc.buildout.UserError('Invalid package contents')
else:
log.error('Unable to find the configure script')
raise zc.buildout.UserError('Invalid package contents')
if patches: if patches:
log.info('Applying patches') log.info('Applying patches')
...@@ -108,7 +114,7 @@ class Recipe: ...@@ -108,7 +114,7 @@ class Recipe:
log.info('Executing pre-configure-hook') log.info('Executing pre-configure-hook')
self.call_script(self.options['pre-configure-hook']) self.call_script(self.options['pre-configure-hook'])
self.run('./configure --prefix=%s %s' % (self.options['prefix'], configure_options)) self.run('%s %s' % (configure_cmd, ' '.join(configure_options)))
if 'pre-make-hook' in self.options and len(self.options['pre-make-hook'].strip()) > 0: if 'pre-make-hook' in self.options and len(self.options['pre-make-hook'].strip()) > 0:
log.info('Executing pre-make-hook') log.info('Executing pre-make-hook')
......
from setuptools import setup, find_packages from setuptools import setup, find_packages
import os import os
version = '1.1.1' version = '1.2.0'
name = 'hexagonit.recipe.cmmi' name = 'hexagonit.recipe.cmmi'
def read(*rnames): def read(*rnames):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment