summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMatthew LeGendre <legendre1@llnl.gov>2017-11-12 19:09:12 -0800
committerTodd Gamblin <tgamblin@llnl.gov>2017-11-12 20:09:12 -0700
commit265c30b943798b71d1a312ffa4f940d48f8f1ef7 (patch)
tree6df2c44a0aeb0a3024add85bdbf5693007c65e4c /lib
parentb09341d861f90c4d3745d25d44d76ff90b3c4967 (diff)
downloadspack-265c30b943798b71d1a312ffa4f940d48f8f1ef7.tar.gz
spack-265c30b943798b71d1a312ffa4f940d48f8f1ef7.tar.bz2
spack-265c30b943798b71d1a312ffa4f940d48f8f1ef7.tar.xz
spack-265c30b943798b71d1a312ffa4f940d48f8f1ef7.zip
Update packaging tutorial (#6270)
* Allow types and 'any' in variant definitions. - Previously variant values had to be a tuple or a callable predicate. - This allows 'any' as shorthand for `lambda x: True` and type objects as shorthand for "any value of this type". - Makes variant definitions more readable, keeps lambdas out of packages for common cases. * Update packaging tutorial * Fix bad file reference in packaging tutorial
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/docs/tutorial/examples/0.package.py15
-rw-r--r--lib/spack/docs/tutorial/examples/1.package.py15
-rw-r--r--lib/spack/docs/tutorial/examples/2.package.py11
-rw-r--r--lib/spack/docs/tutorial/examples/3.package.py11
-rw-r--r--lib/spack/docs/tutorial/examples/4.package.py18
-rw-r--r--lib/spack/docs/tutorial/examples/5.package.py53
-rw-r--r--lib/spack/docs/tutorial_packaging.rst232
-rw-r--r--lib/spack/spack/variant.py19
8 files changed, 232 insertions, 142 deletions
diff --git a/lib/spack/docs/tutorial/examples/0.package.py b/lib/spack/docs/tutorial/examples/0.package.py
index d44e06dd6c..0a42cdc802 100644
--- a/lib/spack/docs/tutorial/examples/0.package.py
+++ b/lib/spack/docs/tutorial/examples/0.package.py
@@ -40,7 +40,7 @@
from spack import *
-class Mpileaks(AutotoolsPackage):
+class Mpileaks(Package):
"""FIXME: Put a proper description of your package here."""
# FIXME: Add a proper url for your package's homepage here.
@@ -50,14 +50,9 @@ class Mpileaks(AutotoolsPackage):
version('1.0', '8838c574b39202a57d7c2d68692718aa')
# 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')
- def configure_args(self):
- # FIXME: Add arguments other than --prefix
- # FIXME: If not needed delete the function
- args = []
- return args
+ def install(self, spec, prefix):
+ # FIXME: Unknown build system
+ make()
+ make('install')
diff --git a/lib/spack/docs/tutorial/examples/1.package.py b/lib/spack/docs/tutorial/examples/1.package.py
index 30f708be2f..359a457567 100644
--- a/lib/spack/docs/tutorial/examples/1.package.py
+++ b/lib/spack/docs/tutorial/examples/1.package.py
@@ -25,7 +25,7 @@
from spack import *
-class Mpileaks(AutotoolsPackage):
+class Mpileaks(Package):
"""Tool to detect and report MPI objects like MPI_Requests and
MPI_Datatypes."""
@@ -35,14 +35,9 @@ class Mpileaks(AutotoolsPackage):
version('1.0', '8838c574b39202a57d7c2d68692718aa')
# 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')
- def configure_args(self):
- # FIXME: Add arguments other than --prefix
- # FIXME: If not needed delete the function
- args = []
- return args
+ def install(self, spec, prefix):
+ # FIXME: Unknown build system
+ make()
+ make('install')
diff --git a/lib/spack/docs/tutorial/examples/2.package.py b/lib/spack/docs/tutorial/examples/2.package.py
index 5f706d1ff6..7980768e06 100644
--- a/lib/spack/docs/tutorial/examples/2.package.py
+++ b/lib/spack/docs/tutorial/examples/2.package.py
@@ -25,7 +25,7 @@
from spack import *
-class Mpileaks(AutotoolsPackage):
+class Mpileaks(Package):
"""Tool to detect and report MPI objects like MPI_Requests and
MPI_Datatypes."""
@@ -38,8 +38,7 @@ class Mpileaks(AutotoolsPackage):
depends_on('adept-utils')
depends_on('callpath')
- def configure_args(self):
- # FIXME: Add arguments other than --prefix
- # FIXME: If not needed delete the function
- args = []
- return args
+ def install(self, spec, prefix):
+ # FIXME: Unknown build system
+ make()
+ make('install')
diff --git a/lib/spack/docs/tutorial/examples/3.package.py b/lib/spack/docs/tutorial/examples/3.package.py
index b34d1545b4..b30dd900ae 100644
--- a/lib/spack/docs/tutorial/examples/3.package.py
+++ b/lib/spack/docs/tutorial/examples/3.package.py
@@ -25,9 +25,10 @@
from spack import *
-class Mpileaks(AutotoolsPackage):
+class Mpileaks(Package):
"""Tool to detect and report MPI objects like MPI_Requests and
MPI_Datatypes."""
+
homepage = "https://github.com/hpc/mpileaks"
url = "https://github.com/hpc/mpileaks/releases/download/v1.0/mpileaks-1.0.tar.gz"
@@ -37,7 +38,7 @@ class Mpileaks(AutotoolsPackage):
depends_on('adept-utils')
depends_on('callpath')
- def configure_args(self):
- args = ['--with-adept-utils=%s' % self.spec['adept-utils'].prefix,
- '--with-callpath=%s' % self.spec['callpath'].prefix]
- return args
+ def install(self, spec, prefix):
+ configure()
+ make()
+ make('install')
diff --git a/lib/spack/docs/tutorial/examples/4.package.py b/lib/spack/docs/tutorial/examples/4.package.py
index 74f9d2e527..116a11a0fa 100644
--- a/lib/spack/docs/tutorial/examples/4.package.py
+++ b/lib/spack/docs/tutorial/examples/4.package.py
@@ -25,7 +25,7 @@
from spack import *
-class Mpileaks(AutotoolsPackage):
+class Mpileaks(Package):
"""Tool to detect and report MPI objects like MPI_Requests and
MPI_Datatypes."""
@@ -34,17 +34,13 @@ class Mpileaks(AutotoolsPackage):
version('1.0', '8838c574b39202a57d7c2d68692718aa')
- variant('stackstart', default=0, description='Specify the number of stack frames to truncate.')
-
depends_on('mpi')
depends_on('adept-utils')
depends_on('callpath')
- def configure_args(self):
- args = ['--with-adept-utils=%s' % self.spec['adept-utils'].prefix,
- '--with-callpath=%s' % self.spec['callpath'].prefix]
- stackstart = int(self.spec.variants['stackstart'].value)
- if stackstart:
- args.extend(['--with-stack-start-c=%s' % stackstart,
- '--with-stack-start-fortran=%s' % stackstart])
- return args
+ def install(self, spec, prefix):
+ configure('--with-adept-utils=%s' % self.spec['adept-utils'].prefix,
+ '--with-callpath=%s' % self.spec['callpath'].prefix,
+ '--prefix=%s' % self.spec.prefix)
+ make()
+ make('install')
diff --git a/lib/spack/docs/tutorial/examples/5.package.py b/lib/spack/docs/tutorial/examples/5.package.py
new file mode 100644
index 0000000000..3e7a1f83cb
--- /dev/null
+++ b/lib/spack/docs/tutorial/examples/5.package.py
@@ -0,0 +1,53 @@
+##############################################################################
+# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/spack/spack
+# Please also see the NOTICE and LICENSE files for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+from spack import *
+
+
+class Mpileaks(Package):
+ """Tool to detect and report MPI objects like MPI_Requests and
+ MPI_Datatypes."""
+
+ homepage = "https://github.com/hpc/mpileaks"
+ url = "https://github.com/hpc/mpileaks/releases/download/v1.0/mpileaks-1.0.tar.gz"
+
+ version('1.0', '8838c574b39202a57d7c2d68692718aa')
+
+ variant('stackstart', values=int, default=0, description='Specify the number of stack frames to truncate.')
+
+ depends_on('mpi')
+ depends_on('adept-utils')
+ depends_on('callpath')
+
+ def install(self, spec, prefix):
+ stackstart = int(self.spec.variants['stackstart'].value)
+ confargs = ['--with-adept-utils=%s' % self.spec['adept-utils'].prefix,
+ '--with-callpath=%s' % self.spec['callpath'].prefix,
+ '--prefix=%s' % self.spec.prefix]
+ if stackstart:
+ confargs.extend(['--with-stack-start-c=%s' % stackstart,
+ '--with-stack-start-fortran=%s' % stackstart])
+ configure(*confargs)
+ make()
+ make('install')
diff --git a/lib/spack/docs/tutorial_packaging.rst b/lib/spack/docs/tutorial_packaging.rst
index e250ab835e..e85be7c637 100644
--- a/lib/spack/docs/tutorial_packaging.rst
+++ b/lib/spack/docs/tutorial_packaging.rst
@@ -43,7 +43,7 @@ A few things before we get started:
Creating the Package File
-------------------------
-Spack comes with a handy command to create a new package: ``spack create``
+Spack comes with a handy command to create a new package: ``spack create``.
This command is given the location of a package's source code, downloads
the code, and sets up some basic packaging infrastructure for you. The
@@ -52,12 +52,20 @@ we run ``spack create`` on it:
.. code-block:: console
- $ spack create -f https://github.com/hpc/mpileaks/releases/download/v1.0/mpileaks-1.0.tar.gz
- ==> This looks like a URL for mpileaks version 1.0
- ==> Creating template for package mpileaks
+ $ spack create -t generic -f https://github.com/hpc/mpileaks/releases/download/v1.0/mpileaks-1.0.tar.gz
+ ==> This looks like a URL for mpileaks
+ ==> Found 1 version of mpileaks:
+
+ 1.0 https://github.com/LLNL/mpileaks/releases/download/v1.0/mpileaks-1.0.tar.gz
+
+ ==> How many would you like to checksum? (default is 1, q to abort) 1
==> Downloading...
- ==> Fetching https://github.com/hpc/mpileaks/releases/download/v1.0/mpileaks-1.0.tar.gz
- ###################################################################################### 100.0%
+ ==> Fetching https://github.com/LLNL/mpileaks/releases/download/v1.0/mpileaks-1.0.tar.gz
+ ############################################################################# 100.0%
+ ==> Checksummed 1 version of mpileaks
+ ==> Using specified package template: 'generic'
+ ==> Created template for mpileaks package
+ ==> Created package file: $SPACK_ROOT/var/spack/repos/builtin/packages/mpileaks/package.py
And Spack should spawn a text editor with this file:
@@ -192,29 +200,27 @@ Now when we try to install this package a lot more happens:
.. code-block:: console
$ spack install mpileaks
+ ...
+ ==> libdwarf is already installed in SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/libdwarf-20160507-er4jrjynul6uba7wiu5tasuj35roxw6m
+ ==> dyninst is already installed in SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/dyninst-9.3.2-t7mau34jv3e76mpspdzhf2p2a6k7qubg
+ ==> callpath is already installed in SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/callpath-1.0.4-ikbbkvfmsfmqzo624nvvrbooovf7egoc
==> Installing mpileaks
- ==> openmpi is already installed in /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/openmpi-2.0.1-5ee5j34c2y4kb5c3joygrgahidqnwhnz
- ==> callpath is already installed in /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/callpath-1.0.2-zm4pf3gasgxeibyu2y262suktvaazube
- ==> adept-utils is already installed in /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/adept-utils-1.0.1-7p7ezxwtajdglj6cmojy2vybjct4j4jz
- ==> Using cached archive: /usr/workspace/wsa/legendre/spack/var/spack/cache/mpileaks/mpileaks-1.0.tar.gz
- ==> Already staged mpileaks-1.0-eum4hmnlt6ovalwjnciaygfb3beja4gk in /usr/workspace/wsa/legendre/spack/var/spack/stage/mpileaks-1.0-eum4hmnlt6ovalwjnciaygfb3beja4gk
- ==> Already patched mpileaks
- ==> Building mpileaks [AutotoolsPackage]
- ==> Executing phase : 'autoreconf'
- ==> Executing phase : 'configure'
- ==> Error: ProcessError: Command exited with status 1:
- './configure' '--prefix=/usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/mpileaks-1.0-eum4hmnlt6ovalwjnciaygfb3beja4gk'
- /usr/workspace/wsa/legendre/spack/lib/spack/spack/build_systems/autotools.py:150, in configure:
- 145 def configure(self, spec, prefix):
- 146 """Runs configure with the arguments specified in `configure_args`
- 147 and an appropriately set prefix
- 148 """
- 149 options = ['--prefix={0}'.format(prefix)] + self.configure_args()
- >> 150 inspect.getmodule(self).configure(*options)
-
+ ==> Using cached archive: SPACK_ROOT/var/spack/cache/mpileaks/mpileaks-1.0.tar.gz
+ ==> Already staged mpileaks-1.0-lfgf53rns5mswq25rxckzgvmjc6ywam7 in SPACK_ROOT/var/spack/stage/mpileaks-1.0-lfgf53rns5mswq25rxckzgvmjc6ywam7
+ ==> No patches needed for mpileaks
+ ==> Building mpileaks [Package]
+ ==> Executing phase: 'install'
+ ==> Error: ProcessError: Command exited with status 2:
+ 'make' '-j36'
+
+ 1 error found in build log:
+ 1 ==> Executing phase: 'install'
+ 2 ==> 'make' '-j36'
+ >> 3 make: *** No targets specified and no makefile found. Stop.
+
See build log for details:
- /tmp/legendre/spack-stage/spack-stage-7V5yyk/mpileaks-1.0/spack-build.out
-
+ SPACK_ROOT/var/spack/stage/mpileaks-1.0-lfgf53rns5mswq25rxckzgvmjc6ywam7/mpileaks-1.0/spack-build.out
+
Note that this command may take a while to run and produce more output if
you don't have an MPI already installed or configured in Spack.
@@ -228,44 +234,79 @@ Debugging Package Builds
------------------------
Our ``mpileaks`` package is still not building. It may be obvious to
-many of you that we're still missing the configure options. But let's
-pretend we're not all intelligent developers and use this opportunity
-spend some time debugging. We a few options that can tell us about
+many of you that we never ran the configure script. Let's add a
+call to ``configure()`` to the top of the install routine. The resulting
+package.py is in ``$SPACK_ROOT/lib/spack/docs/tutorial/examples/3.package.py``:
+
+.. literalinclude:: tutorial/examples/3.package.py
+ :lines: 25-
+ :language: python
+
+If we re-run we still get errors:
+
+.. code-block:: console
+
+ ==> Installing mpileaks
+ ==> Using cached archive: SPACK_ROOT/var/spack/cache/mpileaks/mpileaks-1.0.tar.gz
+ ==> Already staged mpileaks-1.0-lfgf53rns5mswq25rxckzgvmjc6ywam7 in SPACK_ROOT/var/spack/stage/mpileaks-1.0-lfgf53rns5mswq25rxckzgvmjc6ywam7
+ ==> No patches needed for mpileaks
+ ==> Building mpileaks [Package]
+ ==> Executing phase: 'install'
+ ==> Error: ProcessError: Command exited with status 1:
+ './configure'
+
+ 1 error found in build log:
+ [ ... ]
+ 21 checking whether SPACK_ROOT/lib/spack/env/gcc/gcc and cc understand -c and -o together... yes
+ 22 checking whether we are using the GNU C++ compiler... yes
+ 23 checking whether SPACK_ROOT/lib/spack/env/gcc/g++ accepts -g... yes
+ 24 checking dependency style of SPACK_ROOT/lib/spack/env/gcc/g++... gcc3
+ 25 checking for SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/openmpi-3.0.0-yo5qkfvumpmgmvlbalqcadu46j5bd52f/bin/mpicc... SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/openmpi-3.0.0-yo5qkfvumpmgmvlbalqcadu46j5bd52f/bin/mpicc
+ 26 Checking whether SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/openmpi-3.0.0-yo5qkfvumpmgmvlbalqcadu46j5bd52f/bin/mpicc responds to '-showme:compile'... yes
+ >> 27 configure: error: unable to locate adept-utils installation
+
+ See build log for details:
+ SPACK_ROOT/var/spack/stage/mpileaks-1.0-lfgf53rns5mswq25rxckzgvmjc6ywam7/mpileaks-1.0/spack-build.out
+
+Again, the problem may be obvious. But let's pretend we're not
+all intelligent developers and use this opportunity spend some
+time debugging. We have a few options that can tell us about
what's going wrong:
As per the error message, Spack has given us a ``spack-build.out`` debug log:
.. code-block:: console
-
- ==> './configure' '--prefix=/usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/mpileaks-1.0-eum4hmnlt6ovalwjnciaygfb3beja4gk'
+
+ ==> Executing phase: 'install'
+ ==> './configure'
checking metadata... no
checking installation directory variables... yes
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
- checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
+ checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
- checking for gcc... /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/gcc
+ checking for gcc... SPACK_ROOT/lib/spack/env/gcc/gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
- checking for suffix of executables...
+ checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
- checking whether /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/gcc accepts -g... yes
- checking for /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/gcc option to accept ISO C89... none needed
+ checking whether SPACK_ROOT/lib/spack/env/gcc/gcc accepts -g... yes
+ checking for SPACK_ROOT/lib/spack/env/gcc/gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
- checking dependency style of /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/gcc... gcc3
- checking whether /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/gcc and cc understand -c and -o together... yes
+ checking dependency style of SPACK_ROOT/lib/spack/env/gcc/gcc... gcc3
+ checking whether SPACK_ROOT/lib/spack/env/gcc/gcc and cc understand -c and -o together... yes
checking whether we are using the GNU C++ compiler... yes
- checking whether /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/g++ accepts -g... yes
- checking dependency style of /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/g++... gcc3
- checking for /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/openmpi-2.0.1-5ee5j34c2y4kb5c3joygrgahidqnwhnz/bin/mpicc... /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/openmpi-2.0.1-5ee5j34c2y4kb5c3joygrgahidqnwhnz/bin/mpicc
- Checking whether /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/openmpi-2.0.1-5ee5j34c2y4kb5c3joygrgahidqnwhnz/bin/mpicc responds to '-showme:compile'... yes
- configure: error: unable to locate ``adept-utils`` installation
-
-This gives us the output from the build, and it's fairly obvious that
-mpileaks isn't finding its ``adept-utils`` package. Spack has
+ checking whether SPACK_ROOT/lib/spack/env/gcc/g++ accepts -g... yes
+ checking dependency style of SPACK_ROOT/lib/spack/env/gcc/g++... gcc3
+ checking for SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/openmpi-3.0.0-yo5qkfvumpmgmvlbalqcadu46j5bd52f/bin/mpicc... SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/openmpi-3.0.0-yo5qkfvumpmgmvlbalqcadu46j5bd52f/bin/mpicc
+ Checking whether SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/openmpi-3.0.0-yo5qkfvumpmgmvlbalqcadu46j5bd52f/bin/mpicc responds to '-showme:compile'... yes
+ configure: error: unable to locate adept-utils installation
+
+This gives us the output from the build, and mpileaks isn't
+finding its ``adept-utils`` package. Spack has
automatically added the include and library directories of
``adept-utils`` to the compiler's search path, but some packages like
mpileaks can sometimes be picky and still want things spelled out on
@@ -292,26 +333,26 @@ From here we can manually re-run the build:
checking installation directory variables... yes
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
- checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
+ checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
- checking for gcc... /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/gcc
+ checking for gcc... SPACK_ROOT/lib/spack/env/gcc/gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
- checking for suffix of executables...
+ checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
- checking whether /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/gcc accepts -g... yes
- checking for /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/gcc option to accept ISO C89... none needed
+ checking whether SPACK_ROOT/lib/spack/env/gcc/gcc accepts -g... yes
+ checking for SPACK_ROOT/lib/spack/env/gcc/gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
- checking dependency style of /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/gcc... gcc3
- checking whether /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/gcc and cc understand -c and -o together... yes
+ checking dependency style of SPACK_ROOT/lib/spack/env/gcc/gcc... gcc3
+ checking whether SPACK_ROOT/lib/spack/env/gcc/gcc and cc understand -c and -o together... yes
checking whether we are using the GNU C++ compiler... yes
- checking whether /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/g++ accepts -g... yes
- checking dependency style of /usr/workspace/wsa/legendre/spack/lib/spack/env/gcc/g++... gcc3
- checking for /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/openmpi-2.0.1-5ee5j34c2y4kb5c3joygrgahidqnwhnz/bin/mpicc... /usr/workspace/wsa /legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/openmpi-2.0.1-5ee5j34c2y4kb5c3joygrgahidqnwhnz/bin/mpicc
- Checking whether /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/openmpi-2.0.1-5ee5j34c2y4kb5c3joygrgahidqnwhnz/bin/mpicc responds to '-showme:compile'... yes
+ checking whether SPACK_ROOT/lib/spack/env/gcc/g++ accepts -g... yes
+ checking dependency style of SPACK_ROOT/lib/spack/env/gcc/g++... gcc3
+ checking for SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/openmpi-3.0.0-yo5qkfvumpmgmvlbalqcadu46j5bd52f/bin/mpicc... SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/openmpi-3.0.0-yo5qkfvumpmgmvlbalqcadu46j5bd52f/bin/mpicc
+ Checking whether SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/openmpi-3.0.0-yo5qkfvumpmgmvlbalqcadu46j5bd52f/bin/mpicc responds to '-showme:compile'... yes
configure: error: unable to locate adept-utils installation
We're seeing the same error, but now we're in a shell where we can run
@@ -328,9 +369,9 @@ Specifying Configure Arguments
Let's add the configure arguments to the mpileaks' ``package.py``. This
version can be found in
-``$SPACK_ROOT/lib/spack/docs/tutorial/examples/3.package.py``:
+``$SPACK_ROOT/lib/spack/docs/tutorial/examples/4.package.py``:
-.. literalinclude:: tutorial/examples/3.package.py
+.. literalinclude:: tutorial/examples/4.package.py
:lines: 25-
:language: python
@@ -339,37 +380,35 @@ This is all we need for working mpileaks! If we install now we'll see:
.. code-block:: console
$ spack install mpileaks
- spack install mpileaks
+ ...
==> Installing mpileaks
- ==> openmpi is already installed in /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/openmpi-2.0.1-5ee5j34c2y4kb5c3joygrgahidqnwhnz
- ==> callpath is already installed in /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/callpath-1.0.2-zm4pf3gasgxeibyu2y262suktvaazube
- ==> adept-utils is already installed in /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/adept-utils-1.0.1-7p7ezxwtajdglj6cmojy2vybjct4j4jz
- ==> Using cached archive: /usr/workspace/wsa/legendre/spack/var/spack/cache/mpileaks/mpileaks-1.0.tar.gz
- ==> Already staged mpileaks-1.0-eum4hmnlt6ovalwjnciaygfb3beja4gk in /usr/workspace/wsa/legendre/spack/var/spack/stage/mpileaks-1.0-eum4hmnlt6ovalwjnciaygfb3beja4gk
- ==> Already patched mpileaks
- ==> Building mpileaks [AutotoolsPackage]
- ==> Executing phase : 'autoreconf'
- ==> Executing phase : 'configure'
- ==> Executing phase : 'build'
- ==> Executing phase : 'install'
+ ==> Using cached archive: SPACK_ROOT/var/spack/cache/mpileaks/mpileaks-1.0.tar.gz
+ ==> Staging archive: SPACK_ROOT/var/spack/stage/mpileaks-1.0-lfgf53rns5mswq25rxckzgvmjc6ywam7/mpileaks-1.0.tar.gz
+ ==> Created stage in SPACK_ROOT/var/spack/stage/mpileaks-1.0-lfgf53rns5mswq25rxckzgvmjc6ywam7
+ ==> No patches needed for mpileaks
+ ==> Building mpileaks [Package]
+ ==> Executing phase: 'install'
==> Successfully installed mpileaks
- Fetch: 0.00s. Build: 14.08s. Total: 14.08s.
- [+] /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/mpileaks-1.0-eum4hmnlt6ovalwjnciaygfb3beja4gk
+ Fetch: 0.00s. Build: 9.01s. Total: 9.01s.
+ [+] SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/mpileaks-1.0-lfgf53rns5mswq25rxckzgvmjc6ywam7
-We took a few shortcuts for this package that are worth highlighting.
-Spack automatically detected that mpileaks was an Autotools-based package
-when we ran ``spack create``. If this had been a CMake-based package we
-would have been filling in a ``cmake_args`` function instead of
-``configure_args``. If Spack hadn't been able to detect the build
-system, we'd be filling in a generic install method that would manually
-be calling build commands, such as is found in the ``zlib`` package:
+
+There are some special circumstances in package that are worth highlighting.
+Normally spack would have automatically detected that mpileaks was an
+Autotools-based package when we ran ``spack create`` and made it an ``AutoToolsPackage`` class (except we added the ``-t generic`` option to skip this). Instead of
+a full install routine we would have just written:
.. code-block:: python
- def install(self, spec, prefix):
- configure('--prefix={0}'.format(prefix))
- make()
- make('install')
+ def configure_args(self):
+ args = ['--with-adept-utils=%s' % self.spec['adept-utils'].prefix,
+ '--with-callpath=%s' % self.spec['callpath'].prefix]
+ return args
+
+Similarly, if this had been a CMake-based package we
+would have been filling in a ``cmake_args`` function instead of
+``configure_args``. There are similar default package types for
+many build environments.
--------
Variants
@@ -381,9 +420,9 @@ that it walks. Let's add a variant to allow users to set this when they
build in Spack.
To do this, we'll add a variant to our package, as per the following (see
-``$SPACK_ROOT/lib/spack/docs/tutorial/examples/4.package.py``):
+``$SPACK_ROOT/lib/spack/docs/tutorial/examples/5.package.py``):
-.. literalinclude:: tutorial/examples/4.package.py
+.. literalinclude:: tutorial/examples/5.package.py
:lines: 25-
:language: python
@@ -394,18 +433,15 @@ configure line (output truncated for length):
.. code-block:: console
$ spack install --verbose mpileaks stackstart=4
+ ...
==> Installing mpileaks
- ==> openmpi is already installed in /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/openmpi-2.0.1-5ee5j34c2y4kb5c3joygrgahidqnwhnz
- ==> callpath is already installed in /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/callpath-1.0.2-zm4pf3gasgxeibyu2y262suktvaazube
- ==> adept-utils is already installed in /usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/adept-utils-1.0.1-7p7ezxwtajdglj6cmojy2vybjct4j4jz
- ==> Using cached archive: /usr/workspace/wsa/legendre/spack/var/spack/cache/mpileaks/mpileaks-1.0.tar.gz
- ==> Staging archive: /usr/workspace/wsa/legendre/spack/var/spack/stage/mpileaks-1.0-otqo2opkhan5ksujt6tpmdftydrieig7/mpileaks-1.0.tar.gz
- ==> Created stage in /usr/workspace/wsa/legendre/spack/var/spack/stage/mpileaks-1.0-otqo2opkhan5ksujt6tpmdftydrieig7
- ==> Ran patch() for mpileaks
- ==> Building mpileaks [AutotoolsPackage]
- ==> Executing phase : 'autoreconf'
- ==> Executing phase : 'configure'
- ==> './configure' '--prefix=/usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/mpileaks-1.0-otqo2opkhan5ksujt6tpmdftydrieig7' '--with-adept-utils=/usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/adept-utils-1.0.1-7p7ezxwtajdglj6cmojy2vybjct4j4jz' '--with-callpath=/usr/workspace/wsa/legendre/spack/opt/spack/linux-rhel7-x86_64/gcc-4.9.3/callpath-1.0.2-zm4pf3gasgxeibyu2y262suktvaazube' '--with-stack-start-c=4' '--with-stack-start-fortran=4'
+ ==> Using cached archive: SPACK_ROOT/var/spack/cache/mpileaks/mpileaks-1.0.tar.gz
+ ==> Staging archive: SPACK_ROOT/var/spack/stage/mpileaks-1.0-gxxi4fp57b4j6xalra5t65hyx5rj25t7/mpileaks-1.0.tar.gz
+ ==> Created stage in SPACK_ROOT/var/spack/stage/mpileaks-1.0-gxxi4fp57b4j6xalra5t65hyx5rj25t7
+ ==> No patches needed for mpileaks
+ ==> Building mpileaks [Package]
+ ==> Executing phase: 'install'
+ ==> './configure' '--with-adept-utils=SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/adept-utils-1.0.1-pm3gffhrnwsdtqthtvsfvs2tny4r65wb' '--with-callpath=SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/callpath-1.0.4-ikbbkvfmsfmqzo624nvvrbooovf7egoc' '--prefix=SPACK_ROOT/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/mpileaks-1.0-gxxi4fp57b4j6xalra5t65hyx5rj25t7' '--with-stack-start-c=4' '--with-stack-start-fortran=4'
---------------
The Spec Object
diff --git a/lib/spack/spack/variant.py b/lib/spack/spack/variant.py
index 54b0abbab5..43a1ab4ae6 100644
--- a/lib/spack/spack/variant.py
+++ b/lib/spack/spack/variant.py
@@ -67,11 +67,26 @@ class Variant(object):
self.default = default
self.description = str(description)
+ self.values = None
+ if values is any:
+ # 'any' is a special case to make it easy to say any value is ok
+ self.single_value_validator = lambda x: True
+
+ elif isinstance(values, type):
+ # supplying a type means any value *of that type*
+ def isa_type(v):
+ try:
+ values(v)
+ return True
+ except ValueError:
+ return False
+ self.single_value_validator = isa_type
+
if callable(values):
# If 'values' is a callable, assume it is a single value
# validator and reset the values to be explicit during debug
self.single_value_validator = values
- self.values = None
+
else:
# Otherwise assume values is the set of allowed explicit values
self.values = tuple(values)
@@ -114,7 +129,7 @@ class Variant(object):
# Check and record the values that are not allowed
not_allowed_values = [
- x for x in value if not self.single_value_validator(x)
+ x for x in value if self.single_value_validator(x) is False
]
if not_allowed_values:
raise InvalidVariantValueError(self, not_allowed_values, pkg)