diff --git a/lib/spack/docs/packaging_guide.rst b/lib/spack/docs/packaging_guide.rst index 34d11308f5e7dc58f4d77f513a4637d04ad02205..31c676d4f5ea1b64c22e1289077842c4d4c6cad3 100644 --- a/lib/spack/docs/packaging_guide.rst +++ b/lib/spack/docs/packaging_guide.rst @@ -1831,6 +1831,25 @@ successfully find ``libdwarf.h`` and ``libdwarf.so``, without the packager having to provide ``--with-libdwarf=/path/to/libdwarf`` on the command line. +Compiler flags +~~~~~~~~~~~~~~ +In rare circumstances such as compiling and running small unit tests, a package +developer may need to know what are the appropriate compiler flags to enable +features like ``OpenMP``, ``c++11``, ``c++14`` and alike. To that end the +compiler classes in ``spack`` implement the following _properties_ : +``openmp_flag``, ``cxx11_flag``, ``cxx14_flag``, which can be accessed in a +package by ``self.compiler.cxx11_flag`` and alike. Note that the implementation +is such that if a given compiler version does not support this feature, an +error will be produced. Therefore package developers can also use these properties +to assert that a compiler supports the requested feature. This is handy when a +package supports additional variants like + +.. code-block:: python + + variant('openmp', default=True, description="Enable OpenMP support.") + + + Message Parsing Interface (MPI) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is common for high performance computing software/packages to use ``MPI``. diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py index 20896f9eec764e7ada8843aa2033b42f4ee8734c..b53c17494c95bcca9d226b3bd17556ebb069d05f 100644 --- a/lib/spack/spack/compiler.py +++ b/lib/spack/spack/compiler.py @@ -94,12 +94,6 @@ class Compiler(object): # Names of generic arguments used by this compiler arg_rpath = '-Wl,-rpath,%s' - # argument used to get C++11 options - cxx11_flag = "-std=c++11" - - # argument used to get C++14 options - cxx14_flag = "-std=c++1y" - def __init__(self, cspec, cc, cxx, f77, fc): def check(exe): @@ -120,6 +114,37 @@ def check(exe): def version(self): return self.spec.version + # This property should be overridden in the compiler subclass if + # OpenMP is supported by that compiler + @property + def openmp_flag(self): + # If it is not overridden, assume it is not supported and warn the user + tty.die("The compiler you have chosen does not currently support OpenMP.", + "If you think it should, please edit the compiler subclass and", + "submit a pull request or issue.") + + + # This property should be overridden in the compiler subclass if + # C++11 is supported by that compiler + @property + def cxx11_flag(self): + # If it is not overridden, assume it is not supported and warn the user + tty.die("The compiler you have chosen does not currently support C++11.", + "If you think it should, please edit the compiler subclass and", + "submit a pull request or issue.") + + + # This property should be overridden in the compiler subclass if + # C++14 is supported by that compiler + @property + def cxx14_flag(self): + # If it is not overridden, assume it is not supported and warn the user + tty.die("The compiler you have chosen does not currently support C++14.", + "If you think it should, please edit the compiler subclass and", + "submit a pull request or issue.") + + + # # Compiler classes have methods for querying the version of # specific compiler executables. This is used when discovering compilers. diff --git a/lib/spack/spack/compilers/clang.py b/lib/spack/spack/compilers/clang.py index e406d86a24525b1deeae0fe5646d4054aa59cf93..8c646905c7b32c86290a07c44fe7e3e73b0bd170 100644 --- a/lib/spack/spack/compilers/clang.py +++ b/lib/spack/spack/compilers/clang.py @@ -26,6 +26,8 @@ import spack.compiler as cpr from spack.compiler import * from spack.util.executable import * +import llnl.util.tty as tty +from spack.version import ver class Clang(Compiler): # Subclasses use possible names of C compiler @@ -47,6 +49,29 @@ class Clang(Compiler): 'f77' : 'f77', 'fc' : 'f90' } + @property + def is_apple(self): + ver_string = str(self.version) + return ver_string.endswith('-apple') + + @property + def openmp_flag(self): + if self.is_apple: + tty.die("Clang from Apple does not support Openmp yet.") + else: + return "-fopenmp" + + @property + def cxx11_flag(self): + if self.is_apple: + # FIXME: figure out from which version Apple's clang supports c++11 + return "-std=c++11" + else: + if self.version < ver('3.3'): + tty.die("Only Clang 3.3 and above support c++11.") + else: + return "-std=c++11" + @classmethod def default_version(self, comp): """The '--version' option works for clang compilers. diff --git a/lib/spack/spack/compilers/gcc.py b/lib/spack/spack/compilers/gcc.py index 2e57e4485625852344fa83f987918501559abaa3..91c498ac82edbb760dbbc8167b26dc74673b8587 100644 --- a/lib/spack/spack/compilers/gcc.py +++ b/lib/spack/spack/compilers/gcc.py @@ -49,6 +49,10 @@ class Gcc(Compiler): 'f77' : 'gcc/gfortran', 'fc' : 'gcc/gfortran' } + @property + def openmp_flag(self): + return "-fopenmp" + @property def cxx11_flag(self): if self.version < ver('4.3'): diff --git a/lib/spack/spack/compilers/intel.py b/lib/spack/spack/compilers/intel.py index 69e97647906bd76b7f6e1133f429d7155b6b50c1..9b1cf07c36ee7174731f8da738f296875e43f172 100644 --- a/lib/spack/spack/compilers/intel.py +++ b/lib/spack/spack/compilers/intel.py @@ -23,6 +23,8 @@ # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## from spack.compiler import * +import llnl.util.tty as tty +from spack.version import ver class Intel(Compiler): # Subclasses use possible names of C compiler @@ -43,6 +45,13 @@ class Intel(Compiler): 'f77' : 'intel/ifort', 'fc' : 'intel/ifort' } + @property + def openmp_flag(self): + if self.version < ver('16.0'): + return "-openmp" + else: + return "-qopenmp" + @property def cxx11_flag(self): if self.version < ver('11.1'): @@ -68,5 +77,3 @@ def default_version(cls, comp): """ return get_compiler_version( comp, '--version', r'\((?:IFORT|ICC)\) ([^ ]+)') - - diff --git a/lib/spack/spack/compilers/nag.py b/lib/spack/spack/compilers/nag.py index 527a05a090cf100f649c7dcd433a71fce5027b96..e9038c1039fa2a3d681e5e433eb7072d866c1155 100644 --- a/lib/spack/spack/compilers/nag.py +++ b/lib/spack/spack/compilers/nag.py @@ -1,4 +1,5 @@ from spack.compiler import * +import llnl.util.tty as tty class Nag(Compiler): # Subclasses use possible names of C compiler @@ -20,6 +21,16 @@ class Nag(Compiler): 'f77' : 'nag/nagfor', 'fc' : 'nag/nagfor' } + @property + def openmp_flag(self): + return "-openmp" + + @property + def cxx11_flag(self): + # NAG does not have a C++ compiler + # However, it can be mixed with a compiler that does support it + return "-std=c++11" + @classmethod def default_version(self, comp): """The '-V' option works for nag compilers. diff --git a/lib/spack/spack/compilers/pgi.py b/lib/spack/spack/compilers/pgi.py index c6a1078bd9ffecda87b8a1f31a34f66857321f5e..94c6b8365cda380d46e460bc6253a99318dae280 100644 --- a/lib/spack/spack/compilers/pgi.py +++ b/lib/spack/spack/compilers/pgi.py @@ -23,6 +23,7 @@ # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## from spack.compiler import * +import llnl.util.tty as tty class Pgi(Compiler): # Subclasses use possible names of C compiler @@ -43,6 +44,15 @@ class Pgi(Compiler): 'f77' : 'pgi/pgfortran', 'fc' : 'pgi/pgfortran' } + @property + def openmp_flag(self): + return "-mp" + + @property + def cxx11_flag(self): + return "-std=c++11" + + @classmethod def default_version(cls, comp): """The '-V' option works for all the PGI compilers. @@ -54,4 +64,3 @@ def default_version(cls, comp): """ return get_compiler_version( comp, '-V', r'pg[^ ]* ([^ ]+) \d\d\d?-bit target') - diff --git a/lib/spack/spack/compilers/xl.py b/lib/spack/spack/compilers/xl.py index c1d55109a3756b523ede7aa77afd0e092ba074a5..61a2e730dce29bb54c52595592eec32abfa7f933 100644 --- a/lib/spack/spack/compilers/xl.py +++ b/lib/spack/spack/compilers/xl.py @@ -24,6 +24,8 @@ # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## from spack.compiler import * +import llnl.util.tty as tty +from spack.version import ver class Xl(Compiler): # Subclasses use possible names of C compiler @@ -44,6 +46,10 @@ class Xl(Compiler): 'f77' : 'xl/xlf', 'fc' : 'xl/xlf90' } + @property + def openmp_flag(self): + return "-qsmp=omp" + @property def cxx11_flag(self): if self.version < ver('13.1'): diff --git a/var/spack/repos/builtin/packages/kripke/package.py b/var/spack/repos/builtin/packages/kripke/package.py new file mode 100644 index 0000000000000000000000000000000000000000..345b8af4d076be205c52991da60fd515700b99df --- /dev/null +++ b/var/spack/repos/builtin/packages/kripke/package.py @@ -0,0 +1,28 @@ +from spack import * + +class Kripke(Package): + """Kripke is a simple, scalable, 3D Sn deterministic particle + transport proxy/mini app. + """ + homepage = "https://codesign.llnl.gov/kripke.php" + url = "https://codesign.llnl.gov/downloads/kripke-openmp-1.1.tar.gz" + + version('1.1', '7fe6f2b26ed983a6ce5495ab701f85bf') + + variant('mpi', default=True, description='Enable MPI support') + + depends_on('mpi', when="+mpi") + + def install(self, spec, prefix): + with working_dir('build', create=True): + cmake('-DCMAKE_INSTALL_PREFIX:PATH=.', + '-DENABLE_OPENMP=1', + '-DENABLE_MPI=1', + '..', + *std_cmake_args) + make() + + # Kripke does not provide install target, so we have to copy + # things into place. + mkdirp(prefix.bin) + install('kripke', prefix.bin)