From 04821c7be88a8a8333f5aa4df310f30e92c741a9 Mon Sep 17 00:00:00 2001 From: alalazo Date: Fri, 21 Oct 2016 22:12:21 +0200 Subject: spack create : now creates packages that are derived from AutotoolsPackage and CMakePackage --- lib/spack/spack/cmd/create.py | 243 ++++++++++++++++++++++++++---------------- lib/spack/spack/package.py | 8 +- 2 files changed, 155 insertions(+), 96 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/cmd/create.py b/lib/spack/spack/cmd/create.py index 741a320ea7..7f8cf1aa5c 100644 --- a/lib/spack/spack/cmd/create.py +++ b/lib/spack/spack/cmd/create.py @@ -22,25 +22,24 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## -import string +from __future__ import print_function + import os import re +import string -from ordereddict_backport import OrderedDict import llnl.util.tty as tty -from llnl.util.filesystem import mkdirp - import spack import spack.cmd import spack.cmd.checksum import spack.url import spack.util.web -from spack.spec import Spec -from spack.util.naming import * +from llnl.util.filesystem import mkdirp +from ordereddict_backport import OrderedDict from spack.repository import Repo, RepoError - +from spack.spec import Spec from spack.util.executable import which - +from spack.util.naming import * description = "Create a new package file from an archive URL" @@ -87,7 +86,7 @@ package_template = string.Template("""\ from spack import * -class ${class_name}(Package): +class ${class_name}(${base_class_name}): ""\"FIXME: Put a proper description of your package here.""\" # FIXME: Add a proper url for your package's homepage here. @@ -98,109 +97,158 @@ ${versions} ${dependencies} - def install(self, spec, prefix): -${install} +${body} """) -# Build dependencies and extensions -dependencies_dict = { - 'autotools': """\ - # FIXME: Add dependencies if required. - # depends_on('foo')""", - 'cmake': """\ - # FIXME: Add additional dependencies if required. - depends_on('cmake', type='build')""", +class DefaultGuess(object): - 'scons': """\ - # FIXME: Add additional dependencies if required. - depends_on('scons', type='build')""", + base_class_name = 'Package' - 'bazel': """\ - # FIXME: Add additional dependencies if required. - depends_on('bazel', type='build')""", + dependencies = """\ + # FIXME: Add dependencies if required. + # depends_on('foo')""" - 'python': """\ - extends('python') + body = """\ + def install(self, spec, prefix): + # FIXME: Unknown build system + make() + make('install')""" - # FIXME: Add additional dependencies if required. - # depends_on('py-setuptools', type='build') - # depends_on('py-foo', type=nolink)""", + def __init__(self, name, url, version_hash_tuples): + self.name = name + self.class_name = mod_to_class(name) + self.url = url + self.version_hash_tuples = version_hash_tuples - 'R': """\ - extends('R') + @property + def versions(self): + """Adds a version() call to the package for each version found.""" + max_len = max(len(str(v)) for v, h in self.version_hash_tuples) + format = " version(%%-%ds, '%%s')" % (max_len + 2) + return '\n'.join(format % ("'%s'" % v, h) for v, h in self.version_hash_tuples) - # FIXME: Add additional dependencies if required. - # depends_on('r-foo', type=nolink)""", - 'octave': """\ - extends('octave') +class AutotoolsGuess(DefaultGuess): - # FIXME: Add additional dependencies if required. - # depends_on('octave-foo', type=nolink)""", + base_class_name = 'AutotoolsPackage' - 'unknown': """\ + dependencies = """\ # FIXME: Add dependencies if required. + # depends_on('m4', type='build') + # depends_on('autoconf', type='build') + # depends_on('automake', type='build') + # depends_on('libtool', type='build') # depends_on('foo')""" -} -# Default installation instructions -install_dict = { - 'autotools': """\ - # FIXME: Modify the configure line to suit your build system here. - configure('--prefix={0}'.format(prefix)) + body = """\ + def configure_args(self): + # FIXME : Add arguments other than --prefix + # FIXME : If not needed delete the function + args = [] + return args""" - # FIXME: Add logic to build and install here. - make() - make('install')""", - 'cmake': """\ - with working_dir('spack-build', create=True): - # FIXME: Modify the cmake line to suit your build system here. - cmake('..', *std_cmake_args) +class CMakeGuess(DefaultGuess): + + base_class_name = 'CMakePackage' + + dependencies = """\ + # FIXME: Add additional dependencies if required. + depends_on('cmake', type='build')""" + + body = """\ + def cmake_args(self): + # FIXME : Add arguments other than + # FIXME : CMAKE_INSTALL_PREFIX and CMAKE_BUILD_TYPE + # FIXME : If not needed delete the function + args = [] + return args""" + - # FIXME: Add logic to build and install here. - make() - make('install')""", +class SconsGuess(DefaultGuess): - 'scons': """\ + dependencies = """\ + # FIXME: Add additional dependencies if required. + depends_on('scons', type='build')""" + + body = """\ + def install(self, spec, prefix): # FIXME: Add logic to build and install here. scons('prefix={0}'.format(prefix)) - scons('install')""", + scons('install')""" - 'bazel': """\ + +class BazelGuess(DefaultGuess): + + dependencies = """\ + # FIXME: Add additional dependencies if required. + depends_on('bazel', type='build')""" + + body = """\ + def install(self, spec, prefix): # FIXME: Add logic to build and install here. - bazel()""", + bazel()""" + - 'python': """\ +class PythonGuess(DefaultGuess): + + dependencies = """\ + extends('python') + + # FIXME: Add additional dependencies if required. + # depends_on('py-setuptools', type='build') + # depends_on('py-foo', type=nolink)""" + + body = """\ + def install(self, spec, prefix): # FIXME: Add logic to build and install here. - setup_py('install', '--prefix={0}'.format(prefix))""", + setup_py('install', '--prefix={0}'.format(prefix))""" + + def __init__(self, name, *args): + name = 'py-{0}'.format(name) + super(PythonGuess, self).__init__(name, *args) + + +class RGuess(DefaultGuess): + + dependencies = """\ + extends('R') + + # FIXME: Add additional dependencies if required. + # depends_on('r-foo', type=nolink)""" - 'R': """\ + body = """\ + def install(self, spec, prefix): # FIXME: Add logic to build and install here. R('CMD', 'INSTALL', '--library={0}'.format(self.module.r_lib_dir), - self.stage.source_path)""", + self.stage.source_path)""" + + def __init__(self, name, *args): + name = 'r-{0}'.format(name) + super(RGuess, self).__init__(name, *args) - 'octave': """\ + +class OctaveGuess(DefaultGuess): + + dependencies = """\ + extends('octave') + + # FIXME: Add additional dependencies if required. + # depends_on('octave-foo', type=nolink)""" + + body = """\ + def install(self, spec, prefix): # FIXME: Add logic to build and install here. octave('--quiet', '--norc', '--built-in-docstrings-file=/dev/null', '--texi-macros-file=/dev/null', '--eval', 'pkg prefix {0}; pkg install {1}'.format( - prefix, self.stage.archive_file))""", + prefix, self.stage.archive_file))""" - 'unknown': """\ - # FIXME: Unknown build system - make() - make('install')""" -} - - -def make_version_calls(ver_hash_tuples): - """Adds a version() call to the package for each version found.""" - max_len = max(len(str(v)) for v, h in ver_hash_tuples) - format = " version(%%-%ds, '%%s')" % (max_len + 2) - return '\n'.join(format % ("'%s'" % v, h) for v, h in ver_hash_tuples) + def __init__(self, name, *args): + name = 'octave-{0}'.format(name) + super(OctaveGuess, self).__init__(name, *args) def setup_parser(subparser): @@ -227,6 +275,16 @@ def setup_parser(subparser): class BuildSystemGuesser(object): + _choiches = { + 'autotools': AutotoolsGuess, + 'cmake': CMakeGuess, + 'scons': SconsGuess, + 'bazel': BazelGuess, + 'python': PythonGuess, + 'R': RGuess, + 'octave': OctaveGuess + } + def __call__(self, stage, url): """Try to guess the type of build system used by a project based on the contents of its archive or the URL it was downloaded from.""" @@ -275,6 +333,10 @@ class BuildSystemGuesser(object): self.build_system = build_system + def make_guess(self, name, url, ver_hash_tuples): + cls = self._choiches.get(self.build_system, DefaultGuess) + return cls(name, url, ver_hash_tuples) + def guess_name_and_version(url, args): # Try to deduce name and version of the new package from the URL @@ -348,7 +410,7 @@ def fetch_tarballs(url, name, version): tty.msg("Found %s versions of %s:" % (len(versions), name), *spack.cmd.elide_list( ["%-10s%s" % (v, u) for v, u in versions.iteritems()])) - print + print('') archives_to_fetch = tty.get_number( "Include how many checksums in the package file?", default=5, abort='q') @@ -389,16 +451,10 @@ def create(parser, args): if not ver_hash_tuples: tty.die("Could not fetch any tarballs for %s" % name) - # Add prefix to package name if it is an extension. - if guesser.build_system == 'python': - name = 'py-{0}'.format(name) - if guesser.build_system == 'R': - name = 'r-{0}'.format(name) - if guesser.build_system == 'octave': - name = 'octave-{0}'.format(name) + guess = guesser.make_guess(name, url, ver_hash_tuples) # Create a directory for the new package. - pkg_path = repo.filename_for_package_name(name) + pkg_path = repo.filename_for_package_name(guess.name) if os.path.exists(pkg_path) and not args.force: tty.die("%s already exists." % pkg_path) else: @@ -408,12 +464,15 @@ def create(parser, args): with open(pkg_path, "w") as pkg_file: pkg_file.write( package_template.substitute( - name=name, - class_name=mod_to_class(name), - url=url, - versions=make_version_calls(ver_hash_tuples), - dependencies=dependencies_dict[guesser.build_system], - install=install_dict[guesser.build_system])) + name=guess.name, + class_name=guess.class_name, + base_class_name=guess.base_class_name, + url=guess.url, + versions=guess.versions, + dependencies=guess.dependencies, + body=guess.body + ) + ) # If everything checks out, go ahead and edit. spack.editor(pkg_path) diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index a0cc8e68c8..91e6b74dbd 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -1686,10 +1686,10 @@ class EditableMakefile(PackageBase): return self.stage.source_path def build_args(self): - return list() + return [] def install_args(self): - return list() + return [] def edit(self, spec, prefix): raise NotImplementedError('\'edit\' function not implemented') @@ -1721,7 +1721,7 @@ class AutotoolsPackage(PackageBase): 'configure script not found in {0}'.format(os.getcwd())) def configure_args(self): - return list() + return [] def configure(self, spec, prefix): options = ['--prefix={0}'.format(prefix)] + self.configure_args() @@ -1761,7 +1761,7 @@ class CMakePackage(PackageBase): args = ['-DCMAKE_INSTALL_PREFIX:PATH={0}'.format(pkg.prefix), '-DCMAKE_BUILD_TYPE:STRING={0}'.format(build_type), - '-DCMAKE_VERBOSE_MAKEFILE=ON'] + '-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON'] if platform.mac_ver()[0]: args.append('-DCMAKE_FIND_FRAMEWORK:STRING=LAST') -- cgit v1.2.3-70-g09d2