summaryrefslogtreecommitdiff
path: root/var
diff options
context:
space:
mode:
authorMark Olesen <Mark.Olesen@gmx.net>2017-03-31 01:35:57 +0200
committerTodd Gamblin <tgamblin@llnl.gov>2017-03-30 16:35:57 -0700
commit9e1abb13dcc4fb21042c6ca3b2e5c445811d6c15 (patch)
treed922d35abf9b8aec5a0a35eb26c406971f75f37f /var
parent2bd216a6a1cd38254befb9c58057a13072978cb8 (diff)
downloadspack-9e1abb13dcc4fb21042c6ca3b2e5c445811d6c15.tar.gz
spack-9e1abb13dcc4fb21042c6ca3b2e5c445811d6c15.tar.bz2
spack-9e1abb13dcc4fb21042c6ca3b2e5c445811d6c15.tar.xz
spack-9e1abb13dcc4fb21042c6ca3b2e5c445811d6c15.zip
support OpenFOAM package(s) (#3528)
* ENH: add package for building OpenFOAM (1612) from www.openfoam.com - provide 'openfoam' as virtual package. - package as openfoam-com to reflect the distribution point. This initial spack packaging for OpenFOAM supports a number of possible variants and should handle 64-bit labels properly now that the scotch package has been updated accordingly. * ENH: update package for foam-extend (extend-project.de) - provide 'openfoam' as virtual package. - much of the build is now aligned with how the openfoam-com package looks, with the aim of future refactoring. - avoid installing intermediate targets. - contains its own environment sourcing script for the build, for more flexibility and robustness (doesn't touch the python build environ) * ENH: added package for building from openfoam.org - provide 'openfoam' as a virtual package. - this is largely a direct copy of the openfoam-com package. It has been supplied as a courtesy for users and to ensure maximum consistency in quality and naming between the foam-extend, openfoam-com and openfoam-org packages. * CONFIG: add openfoam into bash completion providers list * ENH: have openfoam-com use spack as USERMPI - also simplify the generation of mplib/compiler rules * ENH: have openfoam-org use spack as SYSTEMMPI - this setup requires more environment settings than USERMPI (openfoam-com), but is currently the only means of integration for openfoam-org - simplify generation of mplib/compiler rules * ENH: simplify generation of mplib/compiler rules (foam-extend) - rename mpi rules from SPACK,SPACKMPI to USER,USERMPI for consistency with openfoam-com and to generalize for any build system. * STYLE: record spack tree as a log file (openfoam) - can be useful for future diagnostics and general record keeping
Diffstat (limited to 'var')
-rw-r--r--var/spack/repos/builtin/packages/foam-extend/package.py664
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/openfoam-bin-1612.patch503
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/openfoam-build-1612.patch17
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/openfoam-etc-1612.patch41
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/openfoam-mpi-1612.patch36
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/openfoam-site.patch42
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/package.py722
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/scotch-metis-lib-1612.patch48
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/zoltan-lib-1612.patch84
-rw-r--r--var/spack/repos/builtin/packages/openfoam-org/openfoam-etc-41.patch25
-rw-r--r--var/spack/repos/builtin/packages/openfoam-org/openfoam-site.patch42
-rw-r--r--var/spack/repos/builtin/packages/openfoam-org/package.py492
12 files changed, 2495 insertions, 221 deletions
diff --git a/var/spack/repos/builtin/packages/foam-extend/package.py b/var/spack/repos/builtin/packages/foam-extend/package.py
index e009d64f51..559cc45d7a 100644
--- a/var/spack/repos/builtin/packages/foam-extend/package.py
+++ b/var/spack/repos/builtin/packages/foam-extend/package.py
@@ -9,6 +9,8 @@
# For details, see https://github.com/llnl/spack
# Please also see the LICENSE file for our notice and the LGPL.
#
+# License
+# -------
# 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.
@@ -21,17 +23,51 @@
# 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
+#
+# Legal Notice
+# ------------
+# OPENFOAM is a trademark owned by OpenCFD Ltd
+# (producer and distributor of the OpenFOAM software via www.openfoam.com).
+# The trademark information must remain visible and unadulterated in this
+# file and via the "spack info" and comply with the term set by
+# http://openfoam.com/legal/trademark-policy.php
+#
+# This file is not part of OpenFOAM, nor does it constitute a component of an
+# OpenFOAM distribution.
+#
+##############################################################################
+#
+# Notes
+# - mpi handling: WM_MPLIB=USER and provide wmake rules for special purpose
+# 'USER and 'USERMPI' mpi implementations.
+# The choice of 'USER' vs 'USERMPI' may change in the future.
+#
+# Changes
+# 2017-03-28 Mark Olesen <mark.olesen@esi-group.com>
+# - avoid installing intermediate targets.
+# - reworked to mirror the openfoam-com package.
+# If changes are needed here, consider if they need applying there too.
+#
##############################################################################
from spack import *
from spack.environment import *
import multiprocessing
+import glob
+import re
+import shutil
import os
+from os.path import isdir, isfile
+from spack.pkg.builtin.openfoam_com import *
class FoamExtend(Package):
- """The foam-extend project is a fork of the OpenFOAM open source library
- for Computational Fluid Dynamics (CFD)."""
+ """The Extend Project is a fork of the OpenFOAM opensource library
+ for Computational Fluid Dynamics (CFD).
+ This offering is not approved or endorsed by OpenCFD Ltd,
+ producer and distributor of the OpenFOAM software via www.openfoam.com,
+ and owner of the OPENFOAM trademark.
+ """
homepage = "http://www.extend-project.de/"
@@ -40,207 +76,235 @@ class FoamExtend(Package):
version('3.1', git='http://git.code.sf.net/p/foam-extend/foam-extend-3.1')
version('3.0', git='http://git.code.sf.net/p/foam-extend/foam-extend-3.0')
- variant('paraview', default=False, description='Enable ParaFOAM')
- variant(
- 'scotch', default=True,
- description='Activate Scotch as a possible decomposition library')
- variant(
- 'ptscotch', default=True,
- description='Activate PT-Scotch as a possible decomposition library')
- variant(
- 'metis', default=True,
- description='Activate Metis as a possible decomposition library')
- variant(
- 'parmetis', default=True,
- description='Activate Parmetis as a possible decomposition library')
- variant(
- 'parmgridgen', default=True,
- description='Activate Parmgridgen support')
- variant(
- 'source', default=True,
- description='Installs also the source folder')
-
- supported_compilers = {'clang': 'Clang', 'gcc': 'Gcc', 'intel': 'Icc'}
-
+ # variant('int64', default=False,
+ # description='Compile with 64-bit labels')
+ variant('float32', default=False,
+ description='Compile with 32-bit scalar (single-precision)')
+
+ variant('paraview', default=False,
+ description='Build paraview plugins (eg, paraFoam)')
+ variant('scotch', default=True,
+ description='With scotch for decomposition')
+ variant('ptscotch', default=True,
+ description='With ptscotch for decomposition')
+ variant('metis', default=True,
+ description='With metis for decomposition')
+ variant('parmetis', default=True,
+ description='With parmetis for decomposition')
+ variant('parmgridgen', default=True,
+ description='With parmgridgen support')
+ variant('source', default=True,
+ description='Install library/application sources and tutorials')
+
+ #: Map spack compiler names to OpenFOAM compiler names
+ # By default, simply capitalize the first letter
+ compiler_mapping = {'intel': 'icc'}
+
+ provides('openfoam')
depends_on('mpi')
depends_on('python')
- depends_on('flex')
depends_on('zlib')
+ depends_on('flex@:2.6.1') # <- restriction due to scotch
depends_on('cmake', type='build')
- depends_on('scotch ~ metis', when='~ptscotch+scotch')
- depends_on('scotch ~ metis + mpi', when='+ptscotch')
- depends_on('metis@5:', when='+metis')
- depends_on('parmetis', when='+parmetis')
- depends_on('parmgridgen', when='+parmgridgen')
-
- depends_on('paraview', when='+paraview')
-
- def set_arch(self):
- (sysname, nodename, release, version, machine) = os.uname()
-
- if self.compiler.name not in self.supported_compilers:
- raise RuntimeError('{0} is not a supported compiler \
- to compile OpenFOAM'.format(self.compiler.name))
-
- foam_compiler = self.supported_compilers[self.compiler.name]
- if sysname == 'Linux':
- arch = 'linux'
- if foam_compiler == 'Clang':
- raise RuntimeError('OS, compiler combination not\
- supported ({0} {1})'.format(sysname, foam_compiler))
- elif sysname == 'Darwin':
- if machine == 'x86_64':
- arch = 'darwinIntel'
- if foam_compiler == 'Icc':
- raise RuntimeError('OS, compiler combination not\
- supported ({0} {1})'.format(sysname, foam_compiler))
- else:
- raise RuntimeError('{0} {1} is not a \
- supported architecture'.format(sysname, machine))
-
- return (arch, foam_compiler)
+ depends_on('scotch~metis', when='~ptscotch+scotch')
+ depends_on('scotch~metis+mpi', when='+ptscotch')
+ depends_on('metis@5:', when='+metis')
+ depends_on('parmetis', when='+parmetis')
+ depends_on('parmgridgen', when='+parmgridgen')
+ depends_on('paraview@:5.0.1', when='+paraview')
+
+ # Some user settings, to be adjusted manually or via variants
+ foam_cfg = {
+ 'WM_COMPILER': 'Gcc', # <- %compiler
+ 'WM_ARCH_OPTION': '64', # (32/64-bit on x86_64)
+ # FUTURE? 'WM_LABEL_SIZE': '32', # <- +int64
+ 'WM_PRECISION_OPTION': 'DP', # <- +float32
+ 'WM_COMPILE_OPTION': 'SPACKOpt', # Do not change
+ 'WM_MPLIB': 'USER', # USER | USERMPI
+ }
+
+ # The system description is frequently needed
+ foam_sys = {
+ 'WM_ARCH': None,
+ 'WM_COMPILER': None,
+ 'WM_OPTIONS': None,
+ }
+
+ # Content for etc/prefs.{csh,sh}
+ etc_prefs = {}
+
+ # Content for etc/config.{csh,sh}/ files
+ etc_config = {}
+
+ build_script = './spack-Allwmake' # <- Generated by patch() method.
+ # phases = ['configure', 'build', 'install']
+ # build_system_class = 'OpenfoamCom'
- def get_openfoam_environment(self):
- return EnvironmentModifications.from_sourcing_files(
- join_path(self.stage.source_path,
- 'etc/bashrc'))
+ def setup_environment(self, spack_env, run_env):
+ run_env.set('FOAM_INST_DIR', self.prefix)
+ run_env.set('WM_PROJECT_DIR', self.projectdir)
+
+ @property
+ def _canonical(self):
+ """Canonical name for this package and version"""
+ return 'foam-extend-{0}'.format(self.version.up_to(2))
+
+ @property
+ def projectdir(self):
+ """Absolute location of project directory: WM_PROJECT_DIR/"""
+ return join_path(self.prefix, self._canonical) # <- prefix/canonical
+
+ @property
+ def etc(self):
+ """Absolute location of the OpenFOAM etc/ directory"""
+ return join_path(self.projectdir, 'etc')
+
+ @property
+ def archbin(self):
+ """Relative location of architecture-specific executables"""
+ wm_options = self.set_openfoam()
+ return join_path('applications', 'bin', wm_options)
+
+ @property
+ def archlib(self):
+ """Relative location of architecture-specific libraries"""
+ wm_options = self.set_openfoam()
+ return join_path('lib', wm_options)
+
+ @property
+ def wm_options(self):
+ """The architecture+compiler+options for OpenFOAM"""
+ opts = self.set_openfoam()
+ return opts
+
+ @property
+ def rpath_info(self):
+ """Define 'SPACKOpt' compiler optimization file to have wmake
+ use spack information with minimum modifications to OpenFOAM
+ """
+ build_libpath = join_path(self.stage.source_path, self.archlib)
+ install_libpath = join_path(self.projectdir, self.archlib)
+
+ # 'DBUG': rpaths
+ return '{0}{1} {2}{3}'.format(
+ self.compiler.cxx_rpath_arg, install_libpath,
+ self.compiler.cxx_rpath_arg, build_libpath)
+
+ def openfoam_arch(self):
+ """Return an architecture value similar to what OpenFOAM does in
+ etc/config.sh/settings, but slightly more generous.
+ Uses and may adjust foam_cfg[WM_ARCH_OPTION] as a side-effect
+ """
+ # spec.architecture.platform is like `uname -s`, but lower-case
+ platform = self.spec.architecture.platform
+
+ # spec.architecture.target is like `uname -m`
+ target = self.spec.architecture.target
+
+ if platform == 'linux':
+ if target == 'i686':
+ self.foam_cfg['WM_ARCH_OPTION'] = '32' # Force consistency
+ elif target == 'x86_64':
+ if self.foam_cfg['WM_ARCH_OPTION'] == '64':
+ platform += '64'
+ elif target == 'ia64':
+ platform += 'ia64'
+ elif target == 'armv7l':
+ platform += 'ARM7'
+ elif target == ppc64:
+ platform += 'PPC64'
+ elif target == ppc64le:
+ platform += 'PPC64le'
+ elif platform == 'darwin':
+ if target == 'x86_64':
+ platform += 'Intel'
+ if self.foam_cfg['WM_ARCH_OPTION'] == '64':
+ platform += '64'
+ # ... and others?
+ return platform
+
+ def openfoam_compiler(self):
+ """Capitalized version of the compiler name, which usually corresponds
+ to how OpenFOAM will camel-case things.
+ Use compiler_mapping to handing special cases.
+ Also handle special compiler options (eg, KNL)
+ """
+ comp = self.compiler.name
+ if comp in self.compiler_mapping:
+ comp = self.compiler_mapping[comp]
+ comp = comp.capitalize()
+
+ if '+knl' in self.spec:
+ comp += 'KNL'
+ return comp
+
+ # For foam-extend: does not yet support +int64
+ def set_openfoam(self):
+ """Populate foam_cfg, foam_sys according to
+ variants, architecture, compiler.
+ Returns WM_OPTIONS.
+ """
+ # Run once
+ opts = self.foam_sys['WM_OPTIONS']
+ if opts:
+ return opts
+
+ wm_arch = self.openfoam_arch()
+ wm_compiler = self.openfoam_compiler()
+ compileOpt = self.foam_cfg['WM_COMPILE_OPTION']
+
+ # Insist on a wmake rule for this architecture/compiler combination
+ archCompiler = wm_arch + wm_compiler
+ compiler_rule = join_path(
+ self.stage.source_path, 'wmake', 'rules', archCompiler)
+
+ if not isdir(compiler_rule):
+ raise RuntimeError(
+ 'No wmake rule for {0}'.format(archCompiler))
+ if not re.match(r'.+Opt$', compileOpt):
+ raise RuntimeError(
+ "WM_COMPILE_OPTION={0} is not type '*Opt'".format(compileOpt))
+
+ # Adjust for variants
+ # FUTURE? self.foam_cfg['WM_LABEL_SIZE'] = (
+ # FUTURE? '64' if '+int64' in self.spec else '32'
+ # FUTURE? )
+ self.foam_cfg['WM_PRECISION_OPTION'] = (
+ 'SP' if '+float32' in self.spec else 'DP'
+ )
+
+ # ----
+ # WM_OPTIONS=$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_COMPILE_OPTION
+ # ----
+ self.foam_sys['WM_ARCH'] = wm_arch
+ self.foam_sys['WM_COMPILER'] = wm_compiler
+ self.foam_cfg['WM_COMPILER'] = wm_compiler # For bashrc,cshrc too
+ self.foam_sys['WM_OPTIONS'] = ''.join([
+ wm_arch,
+ wm_compiler,
+ self.foam_cfg['WM_PRECISION_OPTION'],
+ # FUTURE? 'Int', self.foam_cfg['WM_LABEL_SIZE'], # Int32/Int64
+ compileOpt
+ ])
+ return self.foam_sys['WM_OPTIONS']
def patch(self):
- # change names to match the package and not the one patch in
- # the Third-Party of foam-extend
- if '+parmgridgen' in self.spec:
- filter_file(r'-lMGridGen',
- r'-lmgrid',
- 'src/dbns/Make/options')
-
- filter_file(
- r'-lMGridGen',
- r'-lmgrid',
- 'src/fvAgglomerationMethods/MGridGenGamgAgglomeration/Make/options') # noqa: E501
-
- # Get the wmake arch and compiler
- (arch, foam_compiler) = self.set_arch()
-
- prefs_dict = {
- 'compilerInstall': 'System',
- 'WM_COMPILER': foam_compiler,
- 'WM_ARCH_OPTION': '64',
- 'WM_PRECISION_OPTION': 'DP',
- 'WM_COMPILE_OPTION': 'SPACKOpt',
- 'WM_MPLIB': 'SPACK',
-
- 'CMAKE_DIR': self.spec['cmake'].prefix,
- 'CMAKE_BIN_DIR': self.spec['cmake'].prefix.bin,
- 'PYTHON_DIR': self.spec['python'].prefix,
- 'PYTHON_BIN_DIR': self.spec['python'].prefix.bin,
-
- 'FLEX_SYSTEM': 1,
- 'FLEX_DIR': self.spec['flex'].prefix,
-
- 'BISON_SYSTEM': 1,
- 'BISON_DIR': self.spec['flex'].prefix,
-
- 'ZLIB_SYSTEM': 1,
- 'ZLIB_DIR': self.spec['zlib'].prefix,
- }
-
- if '+scotch' in self.spec or '+ptscotch' in self.spec:
- prefs_dict['SCOTCH_SYSTEM'] = 1
- prefs_dict['SCOTCH_DIR'] = self.spec['scotch'].prefix
- prefs_dict['SCOTCH_BIN_DIR'] = self.spec['scotch'].prefix.bin
- prefs_dict['SCOTCH_LIB_DIR'] = self.spec['scotch'].prefix.lib
- prefs_dict['SCOTCH_INCLUDE_DIR'] = \
- self.spec['scotch'].prefix.include
-
- if '+metis' in self.spec:
- prefs_dict['METIS_SYSTEM'] = 1
- prefs_dict['METIS_DIR'] = self.spec['metis'].prefix
- prefs_dict['METIS_BIN_DIR'] = self.spec['metis'].prefix.bin
- prefs_dict['METIS_LIB_DIR'] = self.spec['metis'].prefix.lib
- prefs_dict['METIS_INCLUDE_DIR'] = self.spec['metis'].prefix.include
-
- if '+parmetis' in self.spec:
- prefs_dict['PARMETIS_SYSTEM'] = 1
- prefs_dict['PARMETIS_DIR'] = self.spec['parmetis'].prefix
- prefs_dict['PARMETIS_BIN_DIR'] = self.spec['parmetis'].prefix.bin
- prefs_dict['PARMETIS_LIB_DIR'] = self.spec['parmetis'].prefix.lib
- prefs_dict['PARMETIS_INCLUDE_DIR'] = \
- self.spec['parmetis'].prefix.include
-
- if '+parmgridgen' in self.spec:
- prefs_dict['PARMGRIDGEN_SYSTEM'] = 1
- prefs_dict['PARMGRIDGEN_DIR'] = self.spec['parmgridgen'].prefix
- prefs_dict['PARMGRIDGEN_BIN_DIR'] = \
- self.spec['parmgridgen'].prefix.bin
- prefs_dict['PARMGRIDGEN_LIB_DIR'] = \
- self.spec['parmgridgen'].prefix.lib
- prefs_dict['PARMGRIDGEN_INCLUDE_DIR'] = \
- self.spec['parmgridgen'].prefix.include
-
- if '+paraview' in self.spec:
- prefs_dict['PARAVIEW_SYSTEM'] = 1
- prefs_dict['PARAVIEW_DIR'] = self.spec['paraview'].prefix
- prefs_dict['PARAVIEW_BIN_DIR'] = self.spec['paraview'].prefix.bin
- prefs_dict['QT_SYSTEM'] = 1
- prefs_dict['QT_DIR'] = self.spec['qt'].prefix
- prefs_dict['QT_BIN_DIR'] = self.spec['qt'].prefix.bin
-
- # write the prefs files to define the configuration needed,
- # only the prefs.sh is used by this script but both are
- # installed for end users
- with working_dir('.'):
- with open("etc/prefs.sh", "w") as fh:
- for key in sorted(prefs_dict):
- fh.write('export {0}={1}\n'.format(key, prefs_dict[key]))
-
- with open("etc/prefs.csh", "w") as fh:
- for key in sorted(prefs_dict):
- fh.write('setenv {0}={1}\n'.format(key, prefs_dict[key]))
-
- # Defining a different mpi and optimisation file to be able to
- # make wmake get spack info with minimum modifications on
- # configurations scripts
- mpi_info = [
- 'PFLAGS = -DOMPI_SKIP_MPICXX -DMPICH_IGNORE_CXX_SEEK',
- 'PINC = -I{0}'.format(self.spec['mpi'].prefix.include),
- 'PLIBS = -L{0} -lmpi'.format(self.spec['mpi'].prefix.lib)
+ """Adjust OpenFOAM build for spack. Where needed, apply filter as an
+ alternative to normal patching.
+ """
+ self.set_openfoam() # May need foam_cfg/foam_sys information
+
+ # Adjust ParMGridGen - this is still a mess
+ files = [
+ 'src/dbns/Make/options',
+ 'src/fvAgglomerationMethods/MGridGenGamgAgglomeration/Make/options' # noqa: E501
]
+ for f in files:
+ filter_file(r'-lMGridGen', r'-lmgrid', f, backup=False)
- arch_path = ''.join([arch, prefs_dict['WM_ARCH_OPTION'],
- foam_compiler])
- option_path = ''.join([arch_path,
- prefs_dict['WM_PRECISION_OPTION'],
- prefs_dict['WM_COMPILE_OPTION']])
- rule_path = join_path("wmake", "rules", arch_path)
- build_path = join_path(self.stage.source_path, 'lib', option_path)
- install_path = \
- join_path(self.prefix,
- 'foam-extend-{0}'.format(self.version.up_to(2)),
- option_path)
-
- rpaths_foam = ' '.join([
- '{0}{1}'.format(self.compiler.cxx_rpath_arg,
- install_path),
- '{0}{1}'.format(self.compiler.cxx_rpath_arg,
- build_path)
- ])
-
- compiler_flags = {
- 'DBUG': rpaths_foam,
- 'OPT': '-O3',
- }
-
- with working_dir(rule_path):
- with open('mplibSPACK', "w") as fh:
- fh.write('\n'.join(mpi_info))
-
- for comp in ['c', 'c++']:
- with open('{0}SPACKOpt'.format(comp), "w") as fh:
- for key, val in compiler_flags.iteritems():
- fh.write('{0}{1} = {2}\n'.format(comp, key, val))
-
- _files_to_patch = [
+ # Adjust for flex version check
+ files = [
'src/thermophysicalModels/reactionThermo/chemistryReaders/chemkinReader/chemkinLexer.L', # noqa: E501
'src/surfMesh/surfaceFormats/stl/STLsurfaceFormatASCII.L', # noqa: E501
'src/meshTools/triSurface/triSurface/interfaces/STL/readSTLASCII.L', # noqa: E501
@@ -251,40 +315,198 @@ class FoamExtend(Package):
'applications/utilities/mesh/conversion/fluentMeshToFoam/fluentMeshToFoam.L', # noqa: E501
'applications/utilities/mesh/conversion/fluent3DMeshToElmer/fluent3DMeshToElmer.L' # noqa: E501
]
- for _file in _files_to_patch:
- filter_file(r'#if YY_FLEX_SUBMINOR_VERSION < 34',
- r'#if YY_FLEX_MAJOR_VERSION <= 2 && YY_FLEX_MINOR_VERSION <= 5 && YY_FLEX_SUBMINOR_VERSION < 34', # noqa: E501
- _file)
+ for f in files:
+ filter_file(
+ r'#if YY_FLEX_SUBMINOR_VERSION < 34',
+ r'#if YY_FLEX_MAJOR_VERSION <= 2 && YY_FLEX_MINOR_VERSION <= 5 && YY_FLEX_SUBMINOR_VERSION < 34', # noqa: E501
+ f, backup=False
+ )
+
+ # Build wrapper script
+ with open(self.build_script, 'w') as out:
+ out.write(
+ """#!/bin/bash
+export FOAM_INST_DIR=$(cd .. && pwd -L)
+. $PWD/etc/bashrc '' # No arguments
+mkdir -p $FOAM_APPBIN $FOAM_LIBBIN 2>/dev/null # Allow interrupt
+echo Build openfoam with SPACK
+echo WM_PROJECT_DIR = $WM_PROJECT_DIR
+./Allwmake # No arguments
+#
+""")
+ set_executable(self.build_script)
+ self.configure(self.spec, self.prefix) # Should be a separate phase
+
+ def configure(self, spec, prefix):
+ """Make adjustments to the OpenFOAM configuration files in their various
+ locations: etc/bashrc, etc/config.sh/FEATURE and customizations that
+ don't properly fit get placed in the etc/prefs.sh file (similiarly for
+ csh).
+ """
+ self.set_openfoam() # Need foam_cfg/foam_sys information
+
+ # Content for etc/prefs.{csh,sh}
+ self.etc_prefs = {
+ '000': { # Sort first
+ 'compilerInstall': 'System',
+ },
+ '001': {},
+ 'cmake': {
+ 'CMAKE_DIR': spec['cmake'].prefix,
+ 'CMAKE_BIN_DIR': spec['cmake'].prefix.bin,
+ },
+ 'python': {
+ 'PYTHON_DIR': spec['python'].prefix,
+ 'PYTHON_BIN_DIR': spec['python'].prefix.bin,
+ },
+ 'flex': {
+ 'FLEX_SYSTEM': 1,
+ 'FLEX_DIR': spec['flex'].prefix,
+ },
+ 'bison': {
+ 'BISON_SYSTEM': 1,
+ 'BISON_DIR': spec['flex'].prefix,
+ },
+ 'zlib': {
+ 'ZLIB_SYSTEM': 1,
+ 'ZLIB_DIR': spec['zlib'].prefix,
+ },
+ }
+ # Adjust configuration via prefs - sort second
+ self.etc_prefs['001'].update(self.foam_cfg)
+
+ if '+scotch' in spec or '+ptscotch' in spec:
+ pkg = spec['scotch'].prefix
+ self.etc_prefs['scotch'] = {
+ 'SCOTCH_SYSTEM': 1,
+ 'SCOTCH_DIR': pkg,
+ 'SCOTCH_BIN_DIR': pkg.bin,
+ 'SCOTCH_LIB_DIR': pkg.lib,
+ 'SCOTCH_INCLUDE_DIR': pkg.include,
+ }
+
+ if '+metis' in spec:
+ pkg = spec['metis'].prefix
+ self.etc_prefs['metis'] = {
+ 'METIS_SYSTEM': 1,
+ 'METIS_DIR': pkg,
+ 'METIS_BIN_DIR': pkg.bin,
+ 'METIS_LIB_DIR': pkg.lib,
+ 'METIS_INCLUDE_DIR': pkg.include,
+ }
+
+ if '+parmetis' in spec:
+ pkg = spec['parmetis'].prefix
+ self.etc_prefs['parametis'] = {
+ 'PARMETIS_SYSTEM': 1,
+ 'PARMETIS_DIR': pkg,
+ 'PARMETIS_BIN_DIR': pkg.bin,
+ 'PARMETIS_LIB_DIR': pkg.lib,
+ 'PARMETIS_INCLUDE_DIR': pkg.include,
+ }
+
+ if '+parmgridgen' in spec:
+ pkg = spec['parmgridgen'].prefix
+ self.etc_prefs['parmgridgen'] = {
+ 'PARMGRIDGEN_SYSTEM': 1,
+ 'PARMGRIDGEN_DIR': pkg,
+ 'PARMGRIDGEN_BIN_DIR': pkg.bin,
+ 'PARMGRIDGEN_LIB_DIR': pkg.lib,
+ 'PARMGRIDGEN_INCLUDE_DIR': pkg.include,
+ }
- def setup_environment(self, spack_env, run_env):
- with working_dir(self.stage.path):
- spack_env.set('FOAM_INST_DIR', os.path.abspath('.'))
+ if '+paraview' in self.spec:
+ self.etc_prefs['paraview'] = {
+ 'PARAVIEW_SYSTEM': 1,
+ 'PARAVIEW_DIR': spec['paraview'].prefix,
+ 'PARAVIEW_BIN_DIR': spec['paraview'].prefix.bin,
+ }
+ self.etc_prefs['qt'] = {
+ 'QT_SYSTEM': 1,
+ 'QT_DIR': spec['qt'].prefix,
+ 'QT_BIN_DIR': spec['qt'].prefix.bin,
+ }
+
+ # Write prefs files according to the configuration.
+ # Only need prefs.sh for building, but install both for end-users
+ write_environ(
+ self.etc_prefs,
+ posix=join_path('etc', 'prefs.sh'),
+ cshell=join_path('etc', 'prefs.csh'))
+
+ archCompiler = self.foam_sys['WM_ARCH'] + self.foam_sys['WM_COMPILER']
+ compileOpt = self.foam_cfg['WM_COMPILE_OPTION']
+ # general_rule = join_path('wmake', 'rules', 'General')
+ compiler_rule = join_path('wmake', 'rules', archCompiler)
+ generate_mplib_rules(compiler_rule, self.spec)
+ generate_compiler_rules(compiler_rule, compileOpt, self.rpath_info)
+ # Record the spack spec information
+ with open("log.spack-spec", 'w') as outfile:
+ outfile.write(spec.tree())
+
+ def build(self, spec, prefix):
+ """Build using the OpenFOAM Allwmake script, with a wrapper to source
+ its environment first.
+ """
+ self.set_openfoam() # Force proper population of foam_cfg/foam_sys
+ args = []
+ if self.parallel: # Build in parallel? - pass via the environment
+ os.environ['WM_NCOMPPROCS'] = str(self.make_jobs) \
+ if self.make_jobs else str(multiprocessing.cpu_count())
+ builder = Executable(self.build_script)
+ builder(*args)
- (arch, foam_compiler) = self.set_arch()
+ def install(self, spec, prefix):
+ """Install under the projectdir (== prefix/name-version)"""
+ self.build(spec, prefix) # Should be a separate phase
+ opts = self.wm_options
- run_env.set('FOAM_INST_DIR', self.prefix)
+ # Fairly ugly since intermediate targets are scattered inside sources
+ appdir = 'applications'
+ mkdirp(self.projectdir, join_path(self.projectdir, appdir))
- def install(self, spec, prefix):
- env_openfoam = self.get_openfoam_environment()
- env_openfoam.apply_modifications()
+ # Retain build log file
+ out = "spack-build.out"
+ if isfile(out):
+ install(out, join_path(self.projectdir, "log." + opts))
- if self.parallel:
- os.environ['WM_NCOMPPROCS'] = str(self.make_jobs) \
- if self.make_jobs else str(multiprocessing.cpu_count())
+ # All top-level files, except spack build info and possibly Allwmake
+ if '+source' in spec:
+ ignored = re.compile(r'^spack-.*')
+ else:
+ ignored = re.compile(r'^(Allclean|Allwmake|spack-).*')
- allwmake = Executable('./Allwmake')
- allwmake()
+ files = [
+ f for f in glob.glob("*") if isfile(f) and not ignored.search(f)
+ ]
+ for f in files:
+ install(f, self.projectdir)
- install_path = \
- join_path(self.prefix,
- 'foam-extend-{0}'.format(self.version.up_to(2)))
+ # Install directories. install applications/bin directly
+ for d in ['bin', 'etc', 'wmake', 'lib', join_path(appdir, 'bin')]:
+ install_tree(
+ d,
+ join_path(self.projectdir, d))
if '+source' in spec:
- install_tree('src', join_path(install_path, 'src'))
- install_tree('tutorials', join_path(install_path, 'tutorials'))
-
- install_tree('lib', join_path(install_path, 'lib'))
- install_tree('bin', join_path(install_path, 'bin'))
- install_tree('applications', join_path(install_path, 'applications'))
- install_tree('etc', join_path(install_path, 'etc'))
- install_tree('wmake', join_path(install_path, 'wmake'))
+ subitem = join_path(appdir, 'Allwmake')
+ install(subitem, join_path(self.projectdir, subitem))
+
+ ignored = [opts] # Intermediate targets
+ for d in ['src', 'tutorials']:
+ install_tree(
+ d,
+ join_path(self.projectdir, d),
+ ignore=shutil.ignore_patterns(*ignored))
+
+ for d in ['solvers', 'utilities']:
+ install_tree(
+ join_path(appdir, d),
+ join_path(self.projectdir, appdir, d),
+ ignore=shutil.ignore_patterns(*ignored))
+
+ def install_links(self):
+ """Add symlinks into bin/, lib/ (eg, for other applications)"""
+ return
+
+# -----------------------------------------------------------------------------
diff --git a/var/spack/repos/builtin/packages/openfoam-com/openfoam-bin-1612.patch b/var/spack/repos/builtin/packages/openfoam-com/openfoam-bin-1612.patch
new file mode 100644
index 0000000000..b9e87a7ec8
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/openfoam-bin-1612.patch
@@ -0,0 +1,503 @@
+--- OpenFOAM-v1612+.orig/bin/foamEtcFile 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/bin/foamEtcFile 2017-03-23 10:08:37.296887070 +0100
+@@ -4,7 +4,7 @@
+ # \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ # \\ / O peration |
+ # \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
+-# \\/ M anipulation |
++# \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
+ #-------------------------------------------------------------------------------
+ # License
+ # This file is part of OpenFOAM.
+@@ -26,7 +26,7 @@
+ # foamEtcFile
+ #
+ # Description
+-# Locate user/group/shipped file with semantics similar to the
++# Locate user/group/other files with semantics similar to the
+ # ~OpenFOAM/fileName expansion.
+ #
+ # The -mode option can be used to allow chaining from
+@@ -34,40 +34,53 @@
+ #
+ # For example, within the user ~/.OpenFOAM/<VER>/prefs.sh:
+ # \code
+-# foamPrefs=`$WM_PROJECT_DIR/bin/foamEtcFile -m go prefs.sh` \
+-# && _foamSource $foamPrefs
++# eval $(foamEtcFile -sh -mode=go prefs.sh)
+ # \endcode
+ #
++# Environment
++# - WM_PROJECT: (unset defaults to OpenFOAM)
++# - WM_PROJECT_SITE: (unset defaults to PREFIX/site)
++# - WM_PROJECT_VERSION: (unset defaults to detect from path)
++#
+ # Note
+-# This script must exist in $FOAM_INST_DIR/OpenFOAM-<VERSION>/bin/
+-# or $FOAM_INST_DIR/openfoam<VERSION>/bin/ (for the debian version)
++# This script must exist in one of these locations:
++# - $WM_PROJECT_INST_DIR/OpenFOAM-<VERSION>/bin
++# - $WM_PROJECT_INST_DIR/openfoam-<VERSION>/bin
++# - $WM_PROJECT_INST_DIR/OpenFOAM+<VERSION>/bin
++# - $WM_PROJECT_INST_DIR/openfoam+<VERSION>/bin
++# - $WM_PROJECT_INST_DIR/openfoam<VERSION>/bin (debian version)
+ #
+ #-------------------------------------------------------------------------------
++unset optQuiet optSilent
+ usage() {
+ [ "${optQuiet:-$optSilent}" = true ] && exit 1
+-
+ exec 1>&2
+ while [ "$#" -ge 1 ]; do echo "$1"; shift; done
+ cat<<USAGE
+
+-Usage: ${0##*/} [OPTION] fileName
+- ${0##*/} [OPTION] -list
++Usage: foamEtcFile [OPTION] fileName
++ foamEtcFile [OPTION] [-list|-list-test] [fileName]
+ options:
+- -all return all files (otherwise stop after the first match)
+- -list list the directories to be searched
+- -mode <mode> any combination of u(user), g(group), o(other)
+- -prefix <dir> specify an alternative installation prefix
+- -quiet suppress all normal output
+- -silent suppress all stderr output
+- -version <ver> specify an alternative OpenFOAM version
+- in the form Maj.Min.Rev (eg, 1.7.0)
+- -help print the usage
++ -a, -all Return all files (otherwise stop after the first match)
++ -l, -list List directories or files to be checked
++ -list-test List (existing) directories or files to be checked
++ -mode=MODE Any combination of u(user), g(group), o(other)
++ -prefix=DIR Specify an alternative installation prefix
++ -version=VER Specify alternative OpenFOAM version (eg, 3.0, 1612, ...)
++ -csh | -sh Produce output suitable for a csh or sh 'eval'
++ -csh-verbose | -sh-verbose
++ As per -csh | -sh, with additional verbosity
++ -q, -quiet Suppress all normal output
++ -s, -silent Suppress stderr, except -csh-verbose, -sh-verbose output
++ -help Print the usage
+
+- Locate user/group/shipped file with semantics similar to the
++ Locate user/group/other file with semantics similar to the
+ ~OpenFOAM/fileName expansion.
+
+- The options can also be specified as a single character
+- (eg, '-q' instead of '-quiet'), but must not be grouped.
++ Single character options must not be grouped. Equivalent options:
++ -mode=MODE, -mode MODE, -m MODE
++ -prefix=DIR, -prefix DIR, -p DIR
++ -version=VER, -version VER, -v VER
+
+ Exit status
+ 0 when the file is found. Print resolved path to stdout.
+@@ -78,61 +91,117 @@
+ exit 1
+ }
+
+-#-------------------------------------------------------------------------------
++# Report error and exit
++die()
++{
++ [ "${optQuiet:-$optSilent}" = true ] && exit 1
++ exec 1>&2
++ echo
++ echo "Error encountered:"
++ while [ "$#" -ge 1 ]; do echo " $1"; shift; done
++ echo
++ echo "See 'foamEtcFile -help' for usage"
++ echo
++ exit 1
++}
+
+-# the bin dir:
+-binDir="${0%/*}"
++#-------------------------------------------------------------------------------
++binDir="${0%/*}" # The bin dir
++projectDir="${binDir%/bin}" # The project dir
++prefixDir="${projectDir%/*}" # The prefix dir (same as $WM_PROJECT_INST_DIR)
+
+-# the project dir:
++# Could not resolve projectDir, prefixDir? (eg, called as ./bin/foamEtcFile)
++if [ "$prefixDir" = "$projectDir" ]
++then
++ binDir="$(cd $binDir && pwd -L)"
+ projectDir="${binDir%/bin}"
+-
+-# the prefix dir (same as $FOAM_INST_DIR):
+ prefixDir="${projectDir%/*}"
++fi
++projectDirName="${projectDir##*/}" # The project directory name
+
+-# the name used for the project directory
+-projectDirName="${projectDir##*/}"
++projectName="${WM_PROJECT:-OpenFOAM}" # The project name
++projectVersion="$WM_PROJECT_VERSION" # Empty? - will be treated later
+
+-# version number used for debian packaging
+-unset versionNum
+
++#-------------------------------------------------------------------------------
++
++# Guess project version or simply get the stem part of the projectDirName.
++# Handle standard and debian naming conventions.
+ #
+-# handle standard and debian naming convention
++# - projectVersion: update unless already set
+ #
+-case "$projectDirName" in
+-OpenFOAM-*) # standard naming convention OpenFOAM-<VERSION>
+- version="${projectDirName##OpenFOAM-}"
+- ;;
++# Helper variables:
++# - dirBase (for reassembling name) == projectDirName without the version
++# - versionNum (debian packaging)
++unset dirBase versionNum
++guessVersion()
++{
++ local version
+
+-openfoam[0-9]* | openfoam-dev) # debian naming convention 'openfoam<VERSION>'
+- versionNum="${projectDirName##openfoam}"
+- case "$versionNum" in
+- ??) # convert 2 digit version number to decimal delineated
+- version=$(echo "$versionNum" | sed -e 's@\(.\)\(.\)@\1.\2@')
+- ;;
+- ???) # convert 3 digit version number to decimal delineated
+- version=$(echo "$versionNum" | sed -e 's@\(.\)\(.\)\(.\)@\1.\2.\3@')
+- ;;
+- ????) # convert 4 digit version number to decimal delineated
+- version=$(echo "$versionNum" | sed -e 's@\(.\)\(.\)\(.\)\(.\)@\1.\2.\3.\4@')
+- ;;
+- *) # failback - use current environment setting
+- version="$WM_PROJECT_VERSION"
++ case "$projectDirName" in
++ (OpenFOAM-* | openfoam-*)
++ # Standard naming: OpenFOAM-<VERSION> or openfoam-<VERSION>
++ dirBase="${projectDirName%%-*}-"
++ version="${projectDirName#*-}"
++ version="${version%%*-}" # Extra safety, eg openfoam-version-packager
++ ;;
++
++ (OpenFOAM+* | openfoam+*)
++ # Alternative naming: OpenFOAM+<VERSION> or openfoam+<VERSION>
++ dirBase="${projectDirName%%+*}+"
++ version="${projectDirName#*+}"
++ version="${version%%*-}" # Extra safety, eg openfoam-version-packager
++ ;;
++
++ (openfoam[0-9]*)
++ # Debian naming: openfoam<VERSION>
++ dirBase="openfoam"
++ version="${projectDirName#openfoam}"
++ versionNum="$version"
++
++ # Convert digits version number to decimal delineated
++ case "${#versionNum}" in (2|3|4)
++ version=$(echo "$versionNum" | sed -e 's@\([0-9]\)@\1.@g')
++ version="${version%.}"
+ ;;
+ esac
++
++ # Ignore special treatment if no decimals were inserted.
++ [ "${#version}" -gt "${#versionNum}" ] || unset versionNum
+ ;;
+
+-*)
+- echo "Error : unknown/unsupported naming convention"
+- exit 1
++ (*)
++ die "unknown/unsupported naming convention for '$projectDirName'"
+ ;;
+ esac
+
++ # Set projectVersion if required
++ : ${projectVersion:=$version}
++}
++
++
++# Set projectVersion and update versionNum, projectDirName accordingly
++setVersion()
++{
++ projectVersion="$1"
++
++ # Need dirBase when reassembling projectDirName
++ [ -n "$dirBase" ] || guessVersion
++
++ # Debian: update x.y.z -> xyz version
++ if [ -n "$versionNum" ]
++ then
++ versionNum=$(echo "$projectVersion" | sed -e 's@\.@@g')
++ fi
++
++ projectDirName="$dirBase${versionNum:-$projectVersion}"
++}
++
+
+-# default mode is 'ugo'
+-mode=ugo
+-unset optAll optList optQuiet optSilent
++optMode=ugo # Default mode is always 'ugo'
++unset optAll optList optShell optVersion
+
+-# parse options
++# Parse options
+ while [ "$#" -gt 0 ]
+ do
+ case "$1" in
+@@ -141,27 +210,45 @@
+ ;;
+ -a | -all)
+ optAll=true
++ unset optShell
+ ;;
+ -l | -list)
+ optList=true
++ unset optShell
++ ;;
++ -list-test)
++ optList='test'
++ unset optShell
++ ;;
++ -csh | -sh | -csh-verbose | -sh-verbose)
++ optShell="${1#-}"
++ unset optAll
++ ;;
++ -mode=[ugo]*)
++ optMode="${1#*=}"
++ ;;
++ -prefix=/*)
++ prefixDir="${1#*=}"
++ prefixDir="${prefixDir%/}"
++ ;;
++ -version=*)
++ optVersion="${1#*=}"
+ ;;
+ -m | -mode)
+- [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
+- mode="$2"
+-
+- # sanity check:
+- case "$mode" in
+- *u* | *g* | *o* )
++ optMode="$2"
++ shift
++ # Sanity check. Handles missing argument too.
++ case "$optMode" in
++ ([ugo]*)
+ ;;
+- *)
+- usage "'$1' option with invalid mode '$mode'"
++ (*)
++ die "invalid mode '$optMode'"
+ ;;
+ esac
+- shift
+ ;;
+ -p | -prefix)
+- [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
+- prefixDir="$2"
++ [ "$#" -ge 2 ] || die "'$1' option requires an argument"
++ prefixDir="${2%/}"
+ shift
+ ;;
+ -q | -quiet)
+@@ -171,13 +258,8 @@
+ optSilent=true
+ ;;
+ -v | -version)
+- [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
+- version="$2"
+- # convert x.y.z -> xyz version (if installation looked like debian)
+- if [ -n "$versionNum" ]
+- then
+- versionNum=$(echo "$version" | sed -e 's@\.@@g')
+- fi
++ [ "$#" -ge 2 ] || die "'$1' option requires an argument"
++ optVersion="$2"
+ shift
+ ;;
+ --)
+@@ -185,7 +267,7 @@
+ break
+ ;;
+ -*)
+- usage "unknown option: '$*'"
++ die "unknown option: '$1'"
+ ;;
+ *)
+ break
+@@ -195,11 +277,28 @@
+ done
+
+
+-# debugging:
+-# echo "Installed locations:"
+-# for i in projectDir prefixDir projectDirName version versionNum
++#-------------------------------------------------------------------------------
++
++if [ -n "$optVersion" ]
++then
++ setVersion $optVersion
++elif [ -z "$projectVersion" ]
++then
++ guessVersion
++fi
++
++# Updates:
++# - projectDir for changes via -prefix or -version
++# - projectSite for changes via -prefix
++projectDir="$prefixDir/$projectDirName"
++projectSite="${WM_PROJECT_SITE:-$prefixDir/site}"
++
++
++# Debugging:
++# echo "Installed locations:" 1>&2
++# for i in projectDir prefixDir projectDirName projectVersion
+ # do
+-# eval echo "$i=\$$i"
++# eval echo "$i=\$$i" 1>&2
+ # done
+
+
+@@ -210,30 +309,18 @@
+
+ # Define the various places to be searched:
+ unset dirList
+-case "$mode" in
+-*u*) # user
+- userDir="$HOME/.${WM_PROJECT:-OpenFOAM}"
+- dirList="$dirList $userDir/$version $userDir"
++case "$optMode" in (*u*) # (U)ser
++ dirList="$dirList $HOME/.$projectName/$projectVersion $HOME/.$projectName"
+ ;;
+ esac
+
+-case "$mode" in
+-*g*) # group (site)
+- siteDir="${WM_PROJECT_SITE:-$prefixDir/site}"
+- dirList="$dirList $siteDir/$version $siteDir"
++case "$optMode" in (*g*) # (G)roup == site
++ dirList="$dirList $projectSite/$projectVersion $projectSite"
+ ;;
+ esac
+
+-case "$mode" in
+-*o*) # other (shipped)
+- if [ -n "$versionNum" ]
+- then
+- # debian packaging
+- dirList="$dirList $prefixDir/openfoam$versionNum/etc"
+- else
+- # standard packaging
+- dirList="$dirList $prefixDir/${WM_PROJECT:-OpenFOAM}-$version/etc"
+- fi
++case "$optMode" in (*o*) # (O)ther == shipped
++ dirList="$dirList $projectDir/etc"
+ ;;
+ esac
+ set -- $dirList
+@@ -244,50 +331,87 @@
+ #
+
+ exitCode=0
+-if [ "$optList" = true ]
++if [ -n "$optList" ]
+ then
+
+- # list directories, or potential file locations
+- [ "$nArgs" -le 1 ] || usage
++ # List directories, or potential file locations
++ [ "$nArgs" -le 1 ] || \
++ die "-list expects 0 or 1 filename, but $nArgs provided"
++
++ # A silly combination, but -quiet does have precedence
++ [ -n "$optQuiet" ] && exit 0
+
+- # a silly combination, but -quiet does have precedence
+- [ "$optQuiet" = true ] && exit 0
++ # Test for directory or file too?
++ if [ "$optList" = "test" ]
++ then
++ exitCode=2 # Fallback to a general error (file not found)
+
++ if [ "$nArgs" -eq 1 ]
++ then
+ for dir
+ do
+- if [ "$nArgs" -eq 1 ]
++ resolved="$dir/$fileName"
++ if [ -f "$resolved" ]
+ then
+- echo "$dir/$fileName"
++ echo "$resolved"
++ exitCode=0 # OK
++ fi
++ done
+ else
++ for dir
++ do
++ if [ -d "$dir" ]
++ then
+ echo "$dir"
++ exitCode=0 # OK
+ fi
+ done
++ fi
++ else
++ for dir
++ do
++ echo "$dir${fileName:+/}$fileName"
++ done
++ fi
+
+ else
+
+- [ "$nArgs" -eq 1 ] || usage
++ [ "$nArgs" -eq 1 ] || die "One filename expected - $nArgs provided"
+
+- # general error, eg file not found
+- exitCode=2
++ exitCode=2 # Fallback to a general error (file not found)
+
+ for dir
+ do
+ if [ -f "$dir/$fileName" ]
+ then
+ exitCode=0
+- if [ "$optQuiet" = true ]
+- then
++ [ -n "$optQuiet" ] && break
++
++ case "$optShell" in
++ (*verbose)
++ echo "Using: $dir/$fileName" 1>&2
++ ;;
++ esac
++
++ case "$optShell" in
++ csh*)
++ echo "source $dir/$fileName"
+ break
+- else
++ ;;
++ sh*)
++ echo ". $dir/$fileName"
++ break
++ ;;
++ *)
+ echo "$dir/$fileName"
+- [ "$optAll" = true ] || break
+- fi
++ [ -n "$optAll" ] || break
++ ;;
++ esac
+ fi
+ done
+
+ fi
+
+-
+ exit $exitCode
+
+ #------------------------------------------------------------------------------
diff --git a/var/spack/repos/builtin/packages/openfoam-com/openfoam-build-1612.patch b/var/spack/repos/builtin/packages/openfoam-com/openfoam-build-1612.patch
new file mode 100644
index 0000000000..26e2d8f085
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/openfoam-build-1612.patch
@@ -0,0 +1,17 @@
+--- OpenFOAM-v1612+.orig/Allwmake 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/Allwmake 2017-03-29 09:08:15.503865203 +0200
+@@ -17,6 +17,14 @@
+ exit 1
+ }
+
++#------------------------------------------------------------------------------
++echo "========================================"
++date "+%Y-%m-%d %H:%M:%S %z" 2>/dev/null || echo "date is unknown"
++echo "Starting ${WM_PROJECT_DIR##*/} ${0##*}"
++echo " $WM_COMPILER $WM_COMPILER_TYPE compiler"
++echo " ${WM_OPTIONS}, with ${WM_MPLIB} ${FOAM_MPI}"
++echo
++
+ # Compile wmake support applications
+ (cd wmake/src && make)
+
diff --git a/var/spack/repos/builtin/packages/openfoam-com/openfoam-etc-1612.patch b/var/spack/repos/builtin/packages/openfoam-com/openfoam-etc-1612.patch
new file mode 100644
index 0000000000..dd8146e953
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/openfoam-etc-1612.patch
@@ -0,0 +1,41 @@
+--- OpenFOAM-v1612+.orig/etc/bashrc 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/etc/bashrc 2017-03-22 16:05:05.751237072 +0100
+@@ -42,7 +42,8 @@
+ #
+ # Please set to the appropriate path if the default is not correct.
+ #
+-[ $BASH_SOURCE ] && FOAM_INST_DIR=$(\cd ${BASH_SOURCE%/*/*/*} && \pwd -P) || \
++rc="${BASH_SOURCE:-${ZSH_NAME:+$0}}"
++[ -n "$rc" ] && FOAM_INST_DIR=$(\cd $(dirname $rc)/../.. && \pwd -L) || \
+ FOAM_INST_DIR=$HOME/$WM_PROJECT
+ # FOAM_INST_DIR=~$WM_PROJECT
+ # FOAM_INST_DIR=/opt/$WM_PROJECT
+@@ -135,8 +136,10 @@
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ . $WM_PROJECT_DIR/etc/config.sh/functions
+
+-# Add in preset user or site preferences:
+-_foamSource `$WM_PROJECT_DIR/bin/foamEtcFile prefs.sh`
++# Override definitions via prefs, with 'other' first so the sys-admin
++# can provide base values independent of WM_PROJECT_SITE
++_foamSource `$WM_PROJECT_DIR/bin/foamEtcFile -mode o prefs.sh`
++_foamSource `$WM_PROJECT_DIR/bin/foamEtcFile -mode ug prefs.sh`
+
+ # Evaluate command-line parameters and record settings for later
+ # these can be used to set/unset values, or specify alternative pref files
+diff -uw OpenFOAM-v1612+.orig/etc/cshrc OpenFOAM-v1612+/etc/cshrc
+--- OpenFOAM-v1612+.orig/etc/cshrc 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/etc/cshrc 2017-03-22 16:04:51.839291067 +0100
+@@ -148,8 +148,10 @@
+ # Source files, possibly with some verbosity
+ alias _foamSource 'if ($?FOAM_VERBOSE && $?prompt) echo "Sourcing: \!*"; if (\!* != "") source \!*'
+
+-# Add in preset user or site preferences:
+-_foamSource `$WM_PROJECT_DIR/bin/foamEtcFile prefs.csh`
++# Override definitions via prefs, with 'other' first so the sys-admin
++# can provide base values independent of WM_PROJECT_SITE
++_foamSource `$WM_PROJECT_DIR/bin/foamEtcFile -mode o prefs.csh`
++_foamSource `$WM_PROJECT_DIR/bin/foamEtcFile -mode ug prefs.csh`
+
+ # Evaluate command-line parameters and record settings for later
+ # these can be used to set/unset values, or specify alternative pref files
diff --git a/var/spack/repos/builtin/packages/openfoam-com/openfoam-mpi-1612.patch b/var/spack/repos/builtin/packages/openfoam-com/openfoam-mpi-1612.patch
new file mode 100644
index 0000000000..b3663b0a49
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/openfoam-mpi-1612.patch
@@ -0,0 +1,36 @@
+--- OpenFOAM-v1612+.orig/etc/config.sh/mpi 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/etc/config.sh/mpi 2017-03-29 13:55:57.507980699 +0200
+@@ -75,8 +75,15 @@
+ _foamAddMan $MPI_ARCH_PATH/share/man
+ ;;
+
++USERMPI)
++ # Use an arbitrary, user-specified mpi implementation
++ export FOAM_MPI=mpi-user
++ _foamSource `$WM_PROJECT_DIR/bin/foamEtcFile config.sh/mpi-user`
++ ;;
++
+ SYSTEMMPI)
+ export FOAM_MPI=mpi-system
++ _foamSource `$WM_PROJECT_DIR/bin/foamEtcFile config.sh/mpi-system`
+
+ if [ -z "$MPI_ROOT" ]
+ then
+--- OpenFOAM-v1612+.orig/etc/config.csh/mpi 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/etc/config.csh/mpi 2017-03-29 13:56:36.347835938 +0200
+@@ -71,8 +71,15 @@
+ _foamAddMan $MPI_ARCH_PATH/share/man
+ breaksw
+
++case USERMPI:
++ # Use an arbitrary, user-specified mpi implementation
++ setenv FOAM_MPI mpi-user
++ _foamSource `$WM_PROJECT_DIR/bin/foamEtcFile config.csh/mpi-user`
++ breaksw
++
+ case SYSTEMMPI:
+ setenv FOAM_MPI mpi-system
++ _foamSource `$WM_PROJECT_DIR/bin/foamEtcFile config.csh/mpi-system`
+
+ if ( ! ($?MPI_ROOT) ) then
+ echo
diff --git a/var/spack/repos/builtin/packages/openfoam-com/openfoam-site.patch b/var/spack/repos/builtin/packages/openfoam-com/openfoam-site.patch
new file mode 100644
index 0000000000..6631025788
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/openfoam-site.patch
@@ -0,0 +1,42 @@
+diff -uw OpenFOAM-v1612+.orig/etc/config.sh/settings OpenFOAM-v1612+/etc/config.sh/settings
+--- OpenFOAM-v1612+.orig/etc/config.sh/settings 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/etc/config.sh/settings 2017-03-23 12:22:52.002101020 +0100
+@@ -141,7 +141,7 @@
+ #------------------------------------------------------------------------------
+
+ # Location of the jobControl directory
+-export FOAM_JOB_DIR=$WM_PROJECT_INST_DIR/jobControl
++export FOAM_JOB_DIR=$HOME/$WM_PROJECT/jobControl #SPACK: non-central location
+
+ # wmake configuration
+ export WM_DIR=$WM_PROJECT_DIR/wmake
+@@ -157,7 +157,7 @@
+ export FOAM_EXT_LIBBIN=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_LABEL_OPTION/lib
+
+ # Site-specific directory
+-siteDir="${WM_PROJECT_SITE:-$WM_PROJECT_INST_DIR/site}"
++siteDir="${WM_PROJECT_SITE:-$WM_PROJECT/site}" #SPACK: not in parent directory
+
+ # Shared site executables/libraries
+ # Similar naming convention as ~OpenFOAM expansion
+diff -uw OpenFOAM-v1612+.orig/etc/config.csh/settings OpenFOAM-v1612+/etc/config.csh/settings
+--- OpenFOAM-v1612+.orig/etc/config.csh/settings 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/etc/config.csh/settings 2017-03-23 12:23:52.737891912 +0100
+@@ -137,7 +137,7 @@
+ #------------------------------------------------------------------------------
+
+ # Location of the jobControl directory
+-setenv FOAM_JOB_DIR $WM_PROJECT_INST_DIR/jobControl
++setenv FOAM_JOB_DIR=$HOME/$WM_PROJECT/jobControl #SPACK: non-central location
+
+ # wmake configuration
+ setenv WM_DIR $WM_PROJECT_DIR/wmake
+@@ -156,7 +156,7 @@
+ if ( $?WM_PROJECT_SITE ) then
+ set siteDir=$WM_PROJECT_SITE
+ else
+- set siteDir=$WM_PROJECT_INST_DIR/site
++ set siteDir=$WM_PROJECT_DIR/site #SPACK: not in parent directory
+ endif
+
+ # Shared site executables/libraries
diff --git a/var/spack/repos/builtin/packages/openfoam-com/package.py b/var/spack/repos/builtin/packages/openfoam-com/package.py
new file mode 100644
index 0000000000..fcd33eadcb
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/package.py
@@ -0,0 +1,722 @@
+##############################################################################
+# Copyright (c) 2017 Mark Olesen, OpenCFD Ltd.
+#
+# This file was authored by Mark Olesen <mark.olesen@esi-group.com>
+# and is released as part of spack under the LGPL license.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for the LLNL notice and the LGPL.
+#
+# License
+# -------
+# 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
+#
+# Legal Notice
+# ------------
+# OPENFOAM is a trademark owned by OpenCFD Ltd
+# (producer and distributor of the OpenFOAM software via www.openfoam.com).
+# The trademark information must remain visible and unadulterated in this
+# file and via the "spack info" and comply with the term set by
+# http://openfoam.com/legal/trademark-policy.php
+#
+# This file is not part of OpenFOAM, nor does it constitute a component of an
+# OpenFOAM distribution.
+#
+##############################################################################
+#
+# Notes
+# - mpi handling: WM_MPLIB=USERMPI and use spack to populate an appropriate
+# configuration and generate wmake rules for 'USER' and 'USERMPI'
+# mpi implementations.
+#
+# - Resolution of flex, zlib needs more attention (within OpenFOAM)
+# - +paraview:
+# depends_on should just be 'paraview+plugins' but that resolves poorly.
+# Workaround: use preferred variants "+plugins +qt"
+# packages:
+# paraview:
+# variants: +plugins +qt
+# in ~/.spack/packages.yaml
+#
+# - Combining +zoltan with +int64 has not been tested, but probably won't work.
+#
+##############################################################################
+from spack import *
+from spack.environment import *
+
+import glob
+import re
+import shutil
+import os
+from os.path import isdir, isfile
+
+# Not the nice way of doing things, but is a start for refactoring
+__all__ = [
+ 'format_export',
+ 'format_setenv',
+ 'write_environ',
+ 'rewrite_environ_files',
+ 'mplib_content',
+ 'generate_mplib_rules',
+ 'generate_compiler_rules',
+]
+
+
+def format_export(key, value):
+ """Format key,value pair as 'export' with newline for POSIX shell."""
+ return 'export {0}={1}\n'.format(key, value)
+
+
+def format_setenv(key, value):
+ """Format key,value pair as 'setenv' with newline for C-shell."""
+ return 'setenv {0} {1}\n'.format(key, value)
+
+
+def _write_environ_entries(outfile, environ, formatter):
+ """Write environment settings as 'export' or 'setenv'.
+ If environ is a dict, write in sorted order.
+ If environ is a list, write pair-wise.
+ Also descends into sub-dict and sub-list, but drops the key.
+ """
+ if isinstance(environ, dict):
+ for key in sorted(environ):
+ entry = environ[key]
+ if isinstance(entry, dict):
+ _write_environ_entries(outfile, entry, formatter)
+ elif isinstance(entry, list):
+ _write_environ_entries(outfile, entry, formatter)
+ else:
+ outfile.write(formatter(key, entry))
+ elif isinstance(environ, list):
+ for item in environ:
+ outfile.write(formatter(item[0], item[1]))
+
+
+def _write_environ_file(output, environ, formatter):
+ """Write environment settings as 'export' or 'setenv'.
+ If environ is a dict, write in sorted order.
+ If environ is a list, write pair-wise.
+ Also descends into sub-dict and sub-list, but drops the key.
+ """
+ with open(output, 'w') as outfile:
+ outfile.write('# SPACK settings\n\n')
+ _write_environ_entries(outfile, environ, formatter)
+
+
+def write_environ(environ, **kwargs):
+ """Write environment settings as 'export' or 'setenv'.
+ If environ is a dict, write in sorted order.
+ If environ is a list, write pair-wise.
+
+ Keyword Options:
+ posix[=None] If set, the name of the POSIX file to rewrite.
+ cshell[=None] If set, the name of the C-shell file to rewrite.
+ """
+ posix = kwargs.get('posix', None)
+ if posix:
+ _write_environ_file(posix, environ, format_export)
+ cshell = kwargs.get('cshell', None)
+ if cshell:
+ _write_environ_file(cshell, environ, format_setenv)
+
+
+def rewrite_environ_files(environ, **kwargs):
+ """Use filter_file to rewrite (existing) POSIX shell or C-shell files.
+ Keyword Options:
+ posix[=None] If set, the name of the POSIX file to rewrite.
+ cshell[=None] If set, the name of the C-shell file to rewrite.
+ """
+ posix = kwargs.get('posix', None)
+ if posix and isfile(posix):
+ for k, v in environ.iteritems():
+ filter_file(
+ r'^(\s*export\s+%s)=.*$' % k,
+ r'\1=%s' % v,
+ posix,
+ backup=False)
+ cshell = kwargs.get('cshell', None)
+ if cshell and isfile(cshell):
+ for k, v in environ.iteritems():
+ filter_file(
+ r'^(\s*setenv\s+%s)\s+.*$' % k,
+ r'\1 %s' % v,
+ cshell,
+ backup=False)
+
+
+def pkglib(package):
+ """Get lib64 or lib from package prefix"""
+ libdir = package.prefix.lib64
+ if isdir(libdir):
+ return libdir
+ return package.prefix.lib
+
+
+def mplib_content(spec, pre=None):
+ """The mpi settings to have wmake
+ use spack information with minimum modifications to OpenFOAM.
+
+ Optional parameter 'pre' to provid alternative prefix
+ """
+ mpi_spec = spec['mpi']
+ bin = mpi_spec.prefix.bin
+ inc = mpi_spec.prefix.include
+ lib = pkglib(mpi_spec)
+ if pre:
+ bin = join_path(pre, os.path.basename(bin))
+ inc = join_path(pre, os.path.basename(inc))
+ lib = join_path(pre, os.path.basename(lib))
+ else:
+ pre = mpi_spec.prefix
+
+ info = {
+ 'name': '{0}-{1}'.format(mpi_spec.name, mpi_spec.version),
+ 'prefix': pre,
+ 'include': inc,
+ 'bindir': bin,
+ 'libdir': lib,
+ 'FLAGS': '-DOMPI_SKIP_MPICXX -DMPICH_IGNORE_CXX_SEEK',
+ 'PINC': '-I{0}'.format(inc),
+ 'PLIBS': '-L{0} -lmpi'.format(lib),
+ }
+ return info
+
+
+def generate_mplib_rules(directory, spec):
+ """ Create mplibUSER,mplibUSERMPI rules in the specified directory"""
+ content = mplib_content(spec)
+ with working_dir(directory):
+ for mplib in ['mplibUSER', 'mplibUSERMPI']:
+ with open(mplib, 'w') as out:
+ out.write("""# Use mpi from spack ({name})\n
+PFLAGS = {FLAGS}
+PINC = {PINC}
+PLIBS = {PLIBS}
+""".format(**content))
+
+
+def generate_compiler_rules(directory, compOpt, value):
+ """ Create cSPACKOpt,c++SPACKOpt rules in the specified directory.
+ The file content is copied and filtered from the corresponding
+ cOpt,c++Opt rules"""
+ # Compiler options for SPACK - eg, wmake/rules/linux64Gcc/
+ # Copy from existing cOpt, c++Opt and modify DBUG value
+ with working_dir(directory):
+ for lang in ['c', 'c++']:
+ src = '{0}Opt'.format(lang)
+ dst = '{0}{1}'.format(lang, compOpt)
+ shutil.copyfile(src, dst) # src -> dst
+ filter_file(
+ r'^(\S+DBUG\s*)=.*$',
+ r'\1= %s' % value,
+ dst,
+ backup=False)
+
+
+class OpenfoamCom(Package):
+ """OpenFOAM is a GPL-opensource C++ CFD-toolbox.
+ This offering is supported by OpenCFD Ltd,
+ producer and distributor of the OpenFOAM software via www.openfoam.com,
+ and owner of the OPENFOAM trademark.
+ OpenCFD Ltd has been developing and releasing OpenFOAM since its debut
+ in 2004.
+ """
+
+ homepage = "http://www.openfoam.com/"
+ baseurl = "https://sourceforge.net/projects/openfoamplus/files"
+
+ version('1612', 'ca02c491369150ab127cbb88ec60fbdf',
+ url=baseurl + '/v1612+/OpenFOAM-v1612+.tgz')
+
+ variant('int64', default=False,
+ description='Compile with 64-bit labels')
+ variant('float32', default=False,
+ description='Compile with 32-bit scalar (single-precision)')
+ variant('knl', default=False,
+ description='Use KNL compiler settings')
+
+ variant('scotch', default=True,
+ description='With scotch/ptscotch for decomposition')
+ variant('metis', default=False,
+ description='With metis for decomposition')
+ variant('zoltan', default=False,
+ description='With zoltan renumbering')
+ # TODO?# variant('parmgridgen', default=True,
+ # TODO?# description='With parmgridgen support')
+ variant('source', default=True,
+ description='Install library/application sources and tutorials')
+
+ variant('paraview', default=True,
+ description='Build paraview plugins and runtime post-processing')
+
+ #: Map spack compiler names to OpenFOAM compiler names
+ # By default, simply capitalize the first letter
+ compiler_mapping = {'intel': 'icc'}
+
+ provides('openfoam')
+ depends_on('mpi')
+ depends_on('zlib')
+ depends_on('fftw')
+ depends_on('boost')
+ depends_on('cgal')
+ depends_on('flex@:2.6.1') # <- restriction due to scotch
+ depends_on('cmake', type='build')
+
+ # Require scotch with ptscotch - corresponds to standard OpenFOAM setup
+ depends_on('scotch~int64+mpi', when='+scotch~int64')
+ depends_on('scotch+int64+mpi', when='+scotch+int64')
+ depends_on('metis@5:', when='+metis')
+ depends_on('metis+int64', when='+metis+int64')
+ depends_on('parmgridgen', when='+parmgridgen')
+ depends_on('zoltan', when='+zoltan')
+
+ # For OpenFOAM plugins and run-time post-processing this should just be
+ # 'paraview+plugins' but that resolves poorly.
+ # Workaround: use preferred variants "+plugins +qt" in
+ # ~/.spack/packages.yaml
+
+ # 1612 plugins need older paraview
+ # The native reader in paraview 5.2 is broken, so start after that
+ depends_on('paraview@:5.0.1', when='@:1612+paraview')
+ depends_on('paraview@5.3:', when='@1706:+paraview')
+
+ # General patches
+ patch('openfoam-site.patch')
+
+ # Version-specific patches
+ patch('openfoam-bin-1612.patch', when='@1612')
+ patch('openfoam-etc-1612.patch', when='@1612')
+ patch('openfoam-mpi-1612.patch', when='@1612')
+ patch('openfoam-build-1612.patch', when='@1612')
+ patch('scotch-metis-lib-1612.patch', when='@1612')
+ patch('zoltan-lib-1612.patch', when='@1612')
+
+ # Some user settings, to be adjusted manually or via variants
+ foam_cfg = {
+ 'WM_COMPILER': 'Gcc', # <- %compiler
+ 'WM_ARCH_OPTION': '64', # (32/64-bit on x86_64)
+ 'WM_LABEL_SIZE': '32', # <- +int64
+ 'WM_PRECISION_OPTION': 'DP', # <- +float32
+ 'WM_COMPILE_OPTION': 'SPACKOpt', # Do not change
+ 'WM_MPLIB': 'USERMPI', # Use user mpi for spack
+ }
+
+ # The system description is frequently needed
+ foam_sys = {
+ 'WM_ARCH': None,
+ 'WM_COMPILER': None,
+ 'WM_OPTIONS': None,
+ }
+
+ # Content for etc/prefs.{csh,sh}
+ etc_prefs = {}
+
+ # Content for etc/config.{csh,sh}/ files
+ etc_config = {}
+
+ build_script = './spack-Allwmake' # <- Generated by patch() method.
+ # phases = ['configure', 'build', 'install']
+ # build_system_class = 'OpenfoamCom'
+
+ # Add symlinks into bin/, lib/ (eg, for other applications)
+ extra_symlinks = False
+
+ # Quickly enable/disable testing with the current develop branch
+ if False:
+ version(
+ 'plus',
+ branch='develop',
+ git='file://{0}/{1}'
+ .format(os.path.expanduser("~"), 'openfoam/OpenFOAM-plus/.git'))
+
+ def setup_environment(self, spack_env, run_env):
+ run_env.set('WM_PROJECT_DIR', self.projectdir)
+
+ @property
+ def projectdir(self):
+ """Absolute location of project directory: WM_PROJECT_DIR/"""
+ return self.prefix # <- install directly under prefix
+
+ @property
+ def etc(self):
+ """Absolute location of the OpenFOAM etc/ directory"""
+ return join_path(self.projectdir, 'etc')
+
+ @property
+ def archbin(self):
+ """Relative location of architecture-specific executables"""
+ return join_path('platforms', self.wm_options, 'bin')
+
+ @property
+ def archlib(self):
+ """Relative location of architecture-specific libraries"""
+ return join_path('platforms', self.wm_options, 'lib')
+
+ @property
+ def wm_options(self):
+ """The architecture+compiler+options for OpenFOAM"""
+ opts = self.set_openfoam()
+ return opts
+
+ @property
+ def rpath_info(self):
+ """Define 'SPACKOpt' compiler optimization file to have wmake
+ use spack information with minimum modifications to OpenFOAM
+ """
+ build_libpath = join_path(self.stage.source_path, self.archlib)
+ install_libpath = join_path(self.projectdir, self.archlib)
+
+ # 'DBUG': rpaths
+ return '{0}{1} {2}{3}'.format(
+ self.compiler.cxx_rpath_arg, install_libpath,
+ self.compiler.cxx_rpath_arg, build_libpath)
+
+ def openfoam_arch(self):
+ """Return an architecture value similar to what OpenFOAM does in
+ etc/config.sh/settings, but slightly more generous.
+ Uses and may adjust foam_cfg[WM_ARCH_OPTION] as a side-effect
+ """
+ # spec.architecture.platform is like `uname -s`, but lower-case
+ platform = self.spec.architecture.platform
+
+ # spec.architecture.target is like `uname -m`
+ target = self.spec.architecture.target
+
+ if platform == 'linux':
+ if target == 'i686':
+ self.foam_cfg['WM_ARCH_OPTION'] = '32' # Force consistency
+ elif target == 'x86_64':
+ if self.foam_cfg['WM_ARCH_OPTION'] == '64':
+ platform += '64'
+ elif target == 'ia64':
+ platform += 'ia64'
+ elif target == 'armv7l':
+ platform += 'ARM7'
+ elif target == ppc64:
+ platform += 'PPC64'
+ elif target == ppc64le:
+ platform += 'PPC64le'
+ elif platform == 'darwin':
+ if target == 'x86_64':
+ platform += 'Intel'
+ if self.foam_cfg['WM_ARCH_OPTION'] == '64':
+ platform += '64'
+ # ... and others?
+ return platform
+
+ def openfoam_compiler(self):
+ """Capitalized version of the compiler name, which usually corresponds
+ to how OpenFOAM will camel-case things.
+ Use compiler_mapping to handing special cases.
+ Also handle special compiler options (eg, KNL)
+ """
+ comp = self.compiler.name
+ if comp in self.compiler_mapping:
+ comp = self.compiler_mapping[comp]
+ comp = comp.capitalize()
+
+ if '+knl' in self.spec:
+ comp += 'KNL'
+ return comp
+
+ def set_openfoam(self):
+ """Populate foam_cfg, foam_sys according to
+ variants, architecture, compiler.
+ Returns WM_OPTIONS.
+ """
+ # Run once
+ opts = self.foam_sys['WM_OPTIONS']
+ if opts:
+ return opts
+
+ wm_arch = self.openfoam_arch()
+ wm_compiler = self.openfoam_compiler()
+ compileOpt = self.foam_cfg['WM_COMPILE_OPTION']
+
+ # Insist on a wmake rule for this architecture/compiler combination
+ archCompiler = wm_arch + wm_compiler
+ compiler_rule = join_path(
+ self.stage.source_path, 'wmake', 'rules', archCompiler)
+
+ if not isdir(compiler_rule):
+ raise RuntimeError(
+ 'No wmake rule for {0}'.format(archCompiler))
+ if not re.match(r'.+Opt$', compileOpt):
+ raise RuntimeError(
+ "WM_COMPILE_OPTION={0} is not type '*Opt'".format(compileOpt))
+
+ # Adjust for variants
+ self.foam_cfg['WM_LABEL_SIZE'] = (
+ '64' if '+int64' in self.spec else '32'
+ )
+ self.foam_cfg['WM_PRECISION_OPTION'] = (
+ 'SP' if '+float32' in self.spec else 'DP'
+ )
+
+ # ----
+ # WM_LABEL_OPTION=Int$WM_LABEL_SIZE
+ # WM_OPTIONS=$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_LABEL_OPTION$WM_COMPILE_OPTION
+ # ----
+ self.foam_sys['WM_ARCH'] = wm_arch
+ self.foam_sys['WM_COMPILER'] = wm_compiler
+ self.foam_cfg['WM_COMPILER'] = wm_compiler # For bashrc,cshrc too
+ self.foam_sys['WM_OPTIONS'] = ''.join([
+ wm_arch,
+ wm_compiler,
+ self.foam_cfg['WM_PRECISION_OPTION'],
+ 'Int', self.foam_cfg['WM_LABEL_SIZE'], # Int32/Int64
+ compileOpt
+ ])
+ return self.foam_sys['WM_OPTIONS']
+
+ def patch(self):
+ """Adjust OpenFOAM build for spack. Where needed, apply filter as an
+ alternative to normal patching.
+ """
+ self.set_openfoam() # May need foam_cfg/foam_sys information
+
+ # Avoid WM_PROJECT_INST_DIR for ThirdParty, site or jobControl.
+ # Use openfoam-site.patch to handle jobControl, site.
+ #
+ # Filter (not patch) bashrc,cshrc for additional flexibility
+ wm_setting = {
+ 'WM_THIRD_PARTY_DIR':
+ r'$WM_PROJECT_DIR/ThirdParty #SPACK: No separate third-party',
+ }
+
+ rewrite_environ_files( # Adjust etc/bashrc and etc/cshrc
+ wm_setting,
+ posix=join_path('etc', 'bashrc'),
+ cshell=join_path('etc', 'cshrc'))
+
+ # Adjust ParMGridGen - this is still a mess.
+ # We also have no assurances about sizes (int/long, float/double) etc.
+ #
+ # Need to adjust src/fvAgglomerationMethods/Allwmake
+ # "export ParMGridGen=%s" % spec['parmgridgen'].prefix
+ #
+ # and src/fvAgglomerationMethods/MGridGenGamgAgglomeration/Make/options
+ # "-I=%s" % spec['parmgridgen'].include
+ # "-L=%s -lmgrid" % spec['parmgridgen'].lib
+
+ # Build wrapper script
+ with open(self.build_script, 'w') as out:
+ out.write(
+ """#!/bin/bash
+. $PWD/etc/bashrc '' # No arguments
+mkdir -p $FOAM_APPBIN $FOAM_LIBBIN 2>/dev/null # Allow interrupt
+echo Build openfoam with SPACK
+echo WM_PROJECT_DIR = $WM_PROJECT_DIR
+./Allwmake $@
+#
+""")
+ set_executable(self.build_script)
+ self.configure(self.spec, self.prefix) # Should be a separate phase
+
+ def configure(self, spec, prefix):
+ """Make adjustments to the OpenFOAM configuration files in their various
+ locations: etc/bashrc, etc/config.sh/FEATURE and customizations that
+ don't properly fit get placed in the etc/prefs.sh file (similiarly for
+ csh).
+ """
+ self.set_openfoam() # Need foam_cfg/foam_sys information
+
+ # Some settings for filtering bashrc, cshrc
+ wm_setting = {}
+ wm_setting.update(self.foam_cfg)
+
+ rewrite_environ_files( # Adjust etc/bashrc and etc/cshrc
+ wm_setting,
+ posix=join_path('etc', 'bashrc'),
+ cshell=join_path('etc', 'cshrc'))
+
+ # Content for etc/prefs.{csh,sh}
+ self.etc_prefs = {
+ # TODO
+ # 'CMAKE_ARCH_PATH': spec['cmake'].prefix,
+ # 'FLEX_ARCH_PATH': spec['flex'].prefix,
+ # 'ZLIB_ARCH_PATH': spec['zlib'].prefix,
+ }
+
+ # MPI content, using MPI_ARCH_PATH
+ content = mplib_content(spec, '${MPI_ARCH_PATH}')
+
+ # Content for etc/config.{csh,sh}/ files
+ self.etc_config = {
+ 'CGAL': {
+ 'BOOST_ARCH_PATH': spec['boost'].prefix,
+ 'CGAL_ARCH_PATH': spec['cgal'].prefix,
+ },
+ 'FFTW': {
+ 'FFTW_ARCH_PATH': spec['fftw'].prefix,
+ },
+ # User-defined MPI
+ 'mpi-user': [
+ ('MPI_ARCH_PATH', spec['mpi'].prefix), # Absolute
+ ('LD_LIBRARY_PATH',
+ '"%s:${LD_LIBRARY_PATH}"' % content['libdir']),
+ ('PATH', '"%s:${PATH}"' % content['bindir']),
+ ],
+ 'scotch': {},
+ 'metis': {},
+ 'paraview': [],
+ }
+
+ if '+scotch' in spec:
+ self.etc_config['scotch'] = {
+ 'SCOTCH_ARCH_PATH': spec['scotch'].prefix,
+ # For src/parallel/decompose/Allwmake
+ 'SCOTCH_VERSION': 'scotch-{0}'.format(spec['scotch'].version),
+ }
+
+ if '+metis' in spec:
+ self.etc_config['metis'] = {
+ 'METIS_ARCH_PATH': spec['metis'].prefix,
+ }
+
+ if '+paraview' in spec:
+ pvMajor = 'paraview-{0}'.format(spec['paraview'].version.up_to(2))
+ self.etc_config['paraview'] = [
+ ('ParaView_DIR', spec['paraview'].prefix),
+ ('ParaView_INCLUDE_DIR', '$ParaView_DIR/include/' + pvMajor),
+ ('PV_PLUGIN_PATH', '$FOAM_LIBBIN/' + pvMajor),
+ ('PATH', '"${ParaView_DIR}/bin:${PATH}"'),
+ ]
+
+ # Not normally included as etc/config file
+ if '+parmgridgen' in spec:
+ self.etc_config['parmgridgen'] = {
+ 'PARMGRIDGEN_ARCH_PATH': spec['parmgridgen'].prefix
+ }
+
+ # Optional
+ if '+zoltan' in spec:
+ self.etc_config['zoltan'] = {
+ 'ZOLTAN_ARCH_PATH': spec['zoltan'].prefix
+ }
+
+ # Write prefs files according to the configuration.
+ # Only need prefs.sh for building, but install both for end-users
+ if self.etc_prefs:
+ write_environ(
+ self.etc_prefs,
+ posix=join_path('etc', 'prefs.sh'),
+ cshell=join_path('etc', 'prefs.csh'))
+
+ # Adjust components to use SPACK variants
+ for component, subdict in self.etc_config.iteritems():
+ write_environ(
+ subdict,
+ posix=join_path('etc', 'config.sh', component),
+ cshell=join_path('etc', 'config.csh', component))
+
+ archCompiler = self.foam_sys['WM_ARCH'] + self.foam_sys['WM_COMPILER']
+ compileOpt = self.foam_cfg['WM_COMPILE_OPTION']
+ general_rule = join_path('wmake', 'rules', 'General')
+ compiler_rule = join_path('wmake', 'rules', archCompiler)
+ generate_mplib_rules(general_rule, self.spec)
+ generate_compiler_rules(compiler_rule, compileOpt, self.rpath_info)
+ # Record the spack spec information
+ with open("log.spack-spec", 'w') as outfile:
+ outfile.write(spec.tree())
+
+ def build(self, spec, prefix):
+ """Build using the OpenFOAM Allwmake script, with a wrapper to source
+ its environment first.
+ """
+ self.set_openfoam() # Force proper population of foam_cfg/foam_sys
+ args = ['-silent']
+ if self.parallel: # Build in parallel? - pass as an argument
+ args.append(
+ '-j{0}'.format(str(self.make_jobs) if self.make_jobs else ''))
+ builder = Executable(self.build_script)
+ builder(*args)
+
+ def install(self, spec, prefix):
+ """Install under the projectdir (== prefix)"""
+ self.build(spec, prefix) # Should be a separate phase
+ opts = self.wm_options
+
+ mkdirp(self.projectdir)
+ projdir = os.path.basename(self.projectdir)
+ wm_setting = {
+ 'WM_PROJECT_INST_DIR': os.path.dirname(self.projectdir),
+ 'WM_PROJECT_DIR': join_path('$WM_PROJECT_INST_DIR', projdir),
+ }
+
+ # Retain build log file
+ out = "spack-build.out"
+ if isfile(out):
+ install(out, join_path(self.projectdir, "log." + opts))
+
+ # All top-level files, except spack build info and possibly Allwmake
+ if '+source' in spec:
+ ignored = re.compile(r'^spack-.*')
+ else:
+ ignored = re.compile(r'^(Allwmake|spack-).*')
+
+ files = [
+ f for f in glob.glob("*") if isfile(f) and not ignored.search(f)
+ ]
+ for f in files:
+ install(f, self.projectdir)
+
+ # Having wmake without sources is actually somewhat pointless...
+ dirs = ['bin', 'etc', 'wmake']
+ if '+source' in spec:
+ dirs.extend(['applications', 'src', 'tutorials'])
+
+ for d in dirs:
+ install_tree(
+ d,
+ join_path(self.projectdir, d))
+
+ dirs = ['platforms']
+ if '+source' in spec:
+ dirs.extend(['doc'])
+
+ # Install platforms (and doc) skipping intermediate targets
+ ignored = ['src', 'applications', 'html', 'Guides']
+ for d in dirs:
+ install_tree(
+ d,
+ join_path(self.projectdir, d),
+ ignore=shutil.ignore_patterns(*ignored))
+
+ rewrite_environ_files( # Adjust etc/bashrc and etc/cshrc
+ wm_setting,
+ posix=join_path(self.etc, 'bashrc'),
+ cshell=join_path(self.etc, 'cshrc'))
+ self.install_links()
+
+ def install_links(self):
+ """Add symlinks into bin/, lib/ (eg, for other applications)"""
+ if not self.extra_symlinks:
+ return
+
+ # ln -s platforms/linux64GccXXX/lib lib
+ with working_dir(self.projectdir):
+ if isdir(self.archlib):
+ os.symlink(self.archlib, 'lib')
+
+ # (cd bin && ln -s ../platforms/linux64GccXXX/bin/* .)
+ with working_dir(join_path(self.projectdir, 'bin')):
+ for f in [
+ f for f in glob.glob(join_path('..', self.archbin, "*"))
+ if isfile(f)
+ ]:
+ os.symlink(f, os.path.basename(f))
+
+# -----------------------------------------------------------------------------
diff --git a/var/spack/repos/builtin/packages/openfoam-com/scotch-metis-lib-1612.patch b/var/spack/repos/builtin/packages/openfoam-com/scotch-metis-lib-1612.patch
new file mode 100644
index 0000000000..b7530e6320
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/scotch-metis-lib-1612.patch
@@ -0,0 +1,48 @@
+--- OpenFOAM-v1612+.orig/src/parallel/decompose/Allwmake 2017-03-21 16:34:44.599021283 +0100
++++ OpenFOAM-v1612+/src/parallel/decompose/Allwmake 2017-03-21 16:28:57.243969660 +0100
+@@ -36,6 +36,7 @@
+
+ # Library
+ [ -r $FOAM_EXT_LIBBIN/libmetis.so ] || \
++ [ -r $METIS_ARCH_PATH/lib/libmetis.so ] || \
+ [ -r $METIS_ARCH_PATH/lib$WM_COMPILER_LIB_ARCH/libmetis.so ] || \
+ [ "${METIS_ARCH_PATH##*-}" = system ] || {
+ echo "$warning (missing library)"
+@@ -90,6 +91,7 @@
+
+ # Library
+ [ -r $FOAM_EXT_LIBBIN/libscotch.so ] || \
++ [ -r $SCOTCH_ARCH_PATH/lib/libscotch.so ] || \
+ [ -r $SCOTCH_ARCH_PATH/lib$WM_COMPILER_LIB_ARCH/libscotch.so ] || \
+ [ "${SCOTCH_ARCH_PATH##*-}" = system ] || {
+ echo "$warning (missing library)"
+--- OpenFOAM-v1612+.orig/src/parallel/decompose/metisDecomp/Make/options 2017-03-21 16:34:25.383075328 +0100
++++ OpenFOAM-v1612+/src/parallel/decompose/metisDecomp/Make/options 2017-03-21 16:30:15.727758338 +0100
+@@ -8,6 +8,7 @@
+ * to support central, non-thirdparty installations
+ */
+ LIB_LIBS = \
++ -L$(METIS_ARCH_PATH)/lib \
+ -L$(METIS_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
+ -L$(FOAM_EXT_LIBBIN) \
+ -lmetis
+--- OpenFOAM-v1612+.orig/src/parallel/decompose/ptscotchDecomp/Make/options 2017-03-21 16:34:34.607049385 +0100
++++ OpenFOAM-v1612+/src/parallel/decompose/ptscotchDecomp/Make/options 2017-03-21 16:30:00.479799399 +0100
+@@ -16,6 +16,7 @@
+ * to support central, non-thirdparty installations
+ */
+ LIB_LIBS = \
++ -L$(SCOTCH_ARCH_PATH)/lib \
+ -L$(SCOTCH_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
+ -L$(FOAM_EXT_LIBBIN) \
+ -L$(FOAM_EXT_LIBBIN)/$(FOAM_MPI) \
+--- OpenFOAM-v1612+.orig/src/parallel/decompose/scotchDecomp/Make/options 2017-03-21 16:34:39.159036582 +0100
++++ OpenFOAM-v1612+/src/parallel/decompose/scotchDecomp/Make/options 2017-03-21 16:29:46.719836452 +0100
+@@ -16,6 +16,7 @@
+ * to support central, non-thirdparty installations
+ */
+ LIB_LIBS = \
++ -L$(SCOTCH_ARCH_PATH)/lib \
+ -L$(SCOTCH_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
+ -L$(FOAM_EXT_LIBBIN) \
+ -lscotch \
diff --git a/var/spack/repos/builtin/packages/openfoam-com/zoltan-lib-1612.patch b/var/spack/repos/builtin/packages/openfoam-com/zoltan-lib-1612.patch
new file mode 100644
index 0000000000..712e6a7dfd
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/zoltan-lib-1612.patch
@@ -0,0 +1,84 @@
+--- OpenFOAM-v1612+.orig/applications/utilities/mesh/manipulation/renumberMesh/Allwmake 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/applications/utilities/mesh/manipulation/renumberMesh/Allwmake 2017-03-28 11:13:35.222727218 +0200
+@@ -4,20 +4,35 @@
+ # Parse arguments for compilation (at least for error catching)
+ . $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
+
+-export COMPILE_FLAGS=''
+-export LINK_FLAGS=''
++unset COMP_FLAGS LINK_FLAGS
+
+ if [ -f "${FOAM_LIBBIN}/libSloanRenumber.so" ]
+ then
+- echo "Found libSloanRenumber.so -- enabling Sloan renumbering support."
++ echo " found libSloanRenumber -- enabling sloan renumbering support."
+ export LINK_FLAGS="${LINK_FLAGS} -lSloanRenumber"
+ fi
+
+-if [ -f "${ZOLTAN_ARCH_PATH}/lib/libzoltan.a" -a -f "${FOAM_LIBBIN}/libzoltanRenumber.so" ]
++if [ -f "${FOAM_LIBBIN}/libzoltanRenumber.so" ]
+ then
+- echo "Found libzoltanRenumber.so -- enabling zoltan renumbering support."
+- export COMPILE_FLAGS="-DFOAM_USE_ZOLTAN"
+- export LINK_FLAGS="${LINK_FLAGS} -lzoltanRenumber -L${ZOLTAN_ARCH_PATH}/lib -lzoltan"
++ if [ -z "$ZOLTAN_ARCH_PATH" ]
++ then
++ # Optional: get ZOLTAN_ARCH_PATH
++ if settings=$($WM_PROJECT_DIR/bin/foamEtcFile config.sh/zoltan)
++ then
++ . $settings
++ fi
++ fi
++
++ for libdir in lib "lib${WM_COMPILER_LIB_ARCH}"
++ do
++ if [ -f "$ZOLTAN_ARCH_PATH/$libdir/libzoltan.a" ]
++ then
++ echo " found libzoltanRenumber -- enabling zoltan renumbering support."
++ export COMP_FLAGS="-DFOAM_USE_ZOLTAN"
++ export LINK_FLAGS="${LINK_FLAGS} -lzoltanRenumber -L$ZOLTAN_ARCH_PATH/$libdir -lzoltan"
++ break
++ fi
++ done
+ fi
+
+ wmake $targetType
+--- OpenFOAM-v1612+.orig/src/renumber/Allwmake 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/src/renumber/Allwmake 2017-03-28 11:10:22.195543610 +0200
+@@ -5,14 +5,11 @@
+ targetType=libso
+ . $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
+
+-## Get ZOLTAN_ARCH_PATH
+-#if settings=$($WM_PROJECT_DIR/bin/foamEtcFile config.sh/zoltan)
+-#then
+-# . $settings
+-# echo "using ZOLTAN_ARCH_PATH=$ZOLTAN_ARCH_PATH"
+-#else
+-# echo "Error: no config.sh/zoltan settings"
+-#fi
++# Optional: get ZOLTAN_ARCH_PATH
++if settings=$($WM_PROJECT_DIR/bin/foamEtcFile config.sh/zoltan)
++then
++ . $settings
++fi
+
+ wmake $targetType renumberMethods
+
+--- OpenFOAM-v1612+.orig/src/renumber/zoltanRenumber/Make/options 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/src/renumber/zoltanRenumber/Make/options 2017-03-28 11:50:46.484343848 +0200
+@@ -4,10 +4,13 @@
+ EXE_INC = \
+ /* -DFULLDEBUG -g -O0 */ \
+ $(PFLAGS) $(PINC) \
++ ${c++LESSWARN} \
+ -I$(FOAM_SRC)/renumber/renumberMethods/lnInclude \
+ -I$(ZOLTAN_ARCH_PATH)/include/ \
+ -I$(LIB_SRC)/meshTools/lnInclude
+
+ LIB_LIBS = \
+- /* -L$(ZOLTAN_ARCH_PATH)/lib -lzoltan */ \
++ -L$(ZOLTAN_ARCH_PATH)/lib \
++ -L$(ZOLTAN_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
++ -lzoltan \
+ -lmeshTools
diff --git a/var/spack/repos/builtin/packages/openfoam-org/openfoam-etc-41.patch b/var/spack/repos/builtin/packages/openfoam-org/openfoam-etc-41.patch
new file mode 100644
index 0000000000..6fe3b7b4d3
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-org/openfoam-etc-41.patch
@@ -0,0 +1,25 @@
+--- OpenFOAM-4.x.orig/etc/bashrc 2016-10-16 16:11:45.000000000 +0200
++++ OpenFOAM-4.x/etc/bashrc 2017-03-24 12:41:25.233267894 +0100
+@@ -43,17 +43,17 @@
+ # Please set to the appropriate path if the default is not correct.
+ #
+ [ $BASH_SOURCE ] && \
+-export FOAM_INST_DIR=$(cd ${BASH_SOURCE%/*/*/*} && pwd -P) || \
+-export FOAM_INST_DIR=$HOME/$WM_PROJECT
+-# export FOAM_INST_DIR=~$WM_PROJECT
+-# export FOAM_INST_DIR=/opt/$WM_PROJECT
+-# export FOAM_INST_DIR=/usr/local/$WM_PROJECT
++FOAM_INST_DIR=$(\cd $(dirname $BASH_SOURCE)/../.. && \pwd -P) || \
++FOAM_INST_DIR=$HOME/$WM_PROJECT
++# FOAM_INST_DIR=/opt/$WM_PROJECT
++# FOAM_INST_DIR=/usr/local/$WM_PROJECT
+ #
+ # Build foamyHexMesh
+ export FOAMY_HEX_MESH=yes
+ #
+ # END OF (NORMAL) USER EDITABLE PART
+ ################################################################################
++export FOAM_INST_DIR
+
+ # The default environment variables below can be overridden in a prefs.sh file
+ # located in ~/.OpenFOAM/$WM_PROJECT_VERSION, ~/.OpenFOAM,
diff --git a/var/spack/repos/builtin/packages/openfoam-org/openfoam-site.patch b/var/spack/repos/builtin/packages/openfoam-org/openfoam-site.patch
new file mode 100644
index 0000000000..6631025788
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-org/openfoam-site.patch
@@ -0,0 +1,42 @@
+diff -uw OpenFOAM-v1612+.orig/etc/config.sh/settings OpenFOAM-v1612+/etc/config.sh/settings
+--- OpenFOAM-v1612+.orig/etc/config.sh/settings 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/etc/config.sh/settings 2017-03-23 12:22:52.002101020 +0100
+@@ -141,7 +141,7 @@
+ #------------------------------------------------------------------------------
+
+ # Location of the jobControl directory
+-export FOAM_JOB_DIR=$WM_PROJECT_INST_DIR/jobControl
++export FOAM_JOB_DIR=$HOME/$WM_PROJECT/jobControl #SPACK: non-central location
+
+ # wmake configuration
+ export WM_DIR=$WM_PROJECT_DIR/wmake
+@@ -157,7 +157,7 @@
+ export FOAM_EXT_LIBBIN=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_LABEL_OPTION/lib
+
+ # Site-specific directory
+-siteDir="${WM_PROJECT_SITE:-$WM_PROJECT_INST_DIR/site}"
++siteDir="${WM_PROJECT_SITE:-$WM_PROJECT/site}" #SPACK: not in parent directory
+
+ # Shared site executables/libraries
+ # Similar naming convention as ~OpenFOAM expansion
+diff -uw OpenFOAM-v1612+.orig/etc/config.csh/settings OpenFOAM-v1612+/etc/config.csh/settings
+--- OpenFOAM-v1612+.orig/etc/config.csh/settings 2016-12-23 15:22:59.000000000 +0100
++++ OpenFOAM-v1612+/etc/config.csh/settings 2017-03-23 12:23:52.737891912 +0100
+@@ -137,7 +137,7 @@
+ #------------------------------------------------------------------------------
+
+ # Location of the jobControl directory
+-setenv FOAM_JOB_DIR $WM_PROJECT_INST_DIR/jobControl
++setenv FOAM_JOB_DIR=$HOME/$WM_PROJECT/jobControl #SPACK: non-central location
+
+ # wmake configuration
+ setenv WM_DIR $WM_PROJECT_DIR/wmake
+@@ -156,7 +156,7 @@
+ if ( $?WM_PROJECT_SITE ) then
+ set siteDir=$WM_PROJECT_SITE
+ else
+- set siteDir=$WM_PROJECT_INST_DIR/site
++ set siteDir=$WM_PROJECT_DIR/site #SPACK: not in parent directory
+ endif
+
+ # Shared site executables/libraries
diff --git a/var/spack/repos/builtin/packages/openfoam-org/package.py b/var/spack/repos/builtin/packages/openfoam-org/package.py
new file mode 100644
index 0000000000..19ffd40507
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-org/package.py
@@ -0,0 +1,492 @@
+##############################################################################
+# Copyright (c) 2017 Mark Olesen, OpenCFD Ltd.
+#
+# This file was authored by Mark Olesen <mark.olesen@esi-group.com>
+# and is released as part of spack under the LGPL license.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for the LLNL notice and the LGPL.
+#
+# License
+# -------
+# 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
+#
+# Legal Notice
+# ------------
+# OPENFOAM is a trademark owned by OpenCFD Ltd
+# (producer and distributor of the OpenFOAM software via www.openfoam.com).
+# The trademark information must remain visible and unadulterated in this
+# file and via the "spack info" and comply with the term set by
+# http://openfoam.com/legal/trademark-policy.php
+#
+# This file is not part of OpenFOAM, nor does it constitute a component of an
+# OpenFOAM distribution.
+#
+##############################################################################
+#
+# Notes
+# - The openfoam-org package is a modified version of the openfoam-com package.
+# If changes are needed here, consider if they should also be applied there.
+#
+# - Building with boost/cgal is not included, since some of the logic is not
+# entirely clear and thus untested.
+# - Resolution of flex, zlib needs more attention (within OpenFOAM)
+#
+# - mpi handling: WM_MPLIB=SYSTEMMPI and use spack to populate the prefs.sh
+# for it.
+# Also provide wmake rules for special purpose 'USER' and 'USERMPI'
+# mpi implementations, in case these are required.
+#
+##############################################################################
+from spack import *
+from spack.environment import *
+import llnl.util.tty as tty
+
+import multiprocessing
+import glob
+import re
+import shutil
+import os
+from os.path import isdir, isfile
+from spack.pkg.builtin.openfoam_com import *
+
+
+class OpenfoamOrg(Package):
+ """OpenFOAM is a GPL-opensource C++ CFD-toolbox.
+ The openfoam.org release is managed by the OpenFOAM Foundation Ltd as
+ a licensee of the OPENFOAM trademark.
+ This offering is not approved or endorsed by OpenCFD Ltd,
+ producer and distributor of the OpenFOAM software via www.openfoam.com,
+ and owner of the OPENFOAM trademark.
+ """
+
+ homepage = "http://www.openfoam.org/"
+ baseurl = "https://github.com/OpenFOAM"
+ url = "https://github.com/OpenFOAM/OpenFOAM-4.x/archive/version-4.1.tar.gz"
+
+ version('4.1', '318a446c4ae6366c7296b61184acd37c',
+ url=baseurl + '/OpenFOAM-4.x/archive/version-4.1.tar.gz')
+
+ variant('int64', default=False,
+ description='Compile with 64-bit labels')
+ variant('float32', default=False,
+ description='Compile with 32-bit scalar (single-precision)')
+
+ variant('source', default=True,
+ description='Install library/application sources and tutorials')
+
+ #: Map spack compiler names to OpenFOAM compiler names
+ # By default, simply capitalize the first letter
+ compiler_mapping = {'intel': 'icc'}
+
+ provides('openfoam')
+ depends_on('mpi')
+ depends_on('zlib')
+ depends_on('flex@:2.6.1') # <- restriction due to scotch
+ depends_on('cmake', type='build')
+
+ # Require scotch with ptscotch - corresponds to standard OpenFOAM setup
+ depends_on('scotch~int64+mpi', when='~int64')
+ depends_on('scotch+int64+mpi', when='+int64')
+
+ # General patches
+ patch('openfoam-site.patch')
+
+ # Version-specific patches
+ patch('openfoam-etc-41.patch')
+
+ # Some user settings, to be adjusted manually or via variants
+ foam_cfg = {
+ 'WM_COMPILER': 'Gcc', # <- %compiler
+ 'WM_ARCH_OPTION': '64', # (32/64-bit on x86_64)
+ 'WM_LABEL_SIZE': '32', # <- +int64
+ 'WM_PRECISION_OPTION': 'DP', # <- +float32
+ 'WM_COMPILE_OPTION': 'SPACKOpt', # Do not change
+ 'WM_MPLIB': 'SYSTEMMPI', # Use system mpi for spack
+ }
+
+ # The system description is frequently needed
+ foam_sys = {
+ 'WM_ARCH': None,
+ 'WM_COMPILER': None,
+ 'WM_OPTIONS': None,
+ }
+
+ # Content for etc/prefs.{csh,sh}
+ etc_prefs = {}
+
+ # Content for etc/config.{csh,sh}/ files
+ etc_config = {}
+
+ build_script = './spack-Allwmake' # <- Generated by patch() method.
+ # phases = ['configure', 'build', 'install']
+ # build_system_class = 'OpenfoamCom'
+
+ # Add symlinks into bin/, lib/ (eg, for other applications)
+ extra_symlinks = False
+
+ def setup_environment(self, spack_env, run_env):
+ run_env.set('WM_PROJECT_DIR', self.projectdir)
+
+ @property
+ def _canonical(self):
+ """Canonical name for this package and version"""
+ return 'OpenFOAM-{0}'.format(self.version)
+
+ @property
+ def projectdir(self):
+ """Absolute location of project directory: WM_PROJECT_DIR/"""
+ return join_path(self.prefix, self._canonical) # <- prefix/canonical
+
+ @property
+ def etc(self):
+ """Absolute location of the OpenFOAM etc/ directory"""
+ return join_path(self.projectdir, 'etc')
+
+ @property
+ def archbin(self):
+ """Relative location of architecture-specific executables"""
+ return join_path('platforms', self.wm_options, 'bin')
+
+ @property
+ def archlib(self):
+ """Relative location of architecture-specific libraries"""
+ return join_path('platforms', self.wm_options, 'lib')
+
+ @property
+ def wm_options(self):
+ """The architecture+compiler+options for OpenFOAM"""
+ opts = self.set_openfoam()
+ return opts
+
+ @property
+ def rpath_info(self):
+ """Define 'SPACKOpt' compiler optimization file to have wmake
+ use spack information with minimum modifications to OpenFOAM
+ """
+ build_libpath = join_path(self.stage.source_path, self.archlib)
+ install_libpath = join_path(self.projectdir, self.archlib)
+
+ # 'DBUG': rpaths
+ return '{0}{1} {2}{3}'.format(
+ self.compiler.cxx_rpath_arg, install_libpath,
+ self.compiler.cxx_rpath_arg, build_libpath)
+
+ def openfoam_arch(self):
+ """Return an architecture value similar to what OpenFOAM does in
+ etc/config.sh/settings, but slightly more generous.
+ Uses and may adjust foam_cfg[WM_ARCH_OPTION] as a side-effect
+ """
+ # spec.architecture.platform is like `uname -s`, but lower-case
+ platform = self.spec.architecture.platform
+
+ # spec.architecture.target is like `uname -m`
+ target = self.spec.architecture.target
+
+ if platform == 'linux':
+ if target == 'i686':
+ self.foam_cfg['WM_ARCH_OPTION'] = '32' # Force consistency
+ elif target == 'x86_64':
+ if self.foam_cfg['WM_ARCH_OPTION'] == '64':
+ platform += '64'
+ elif target == 'ia64':
+ platform += 'ia64'
+ elif target == 'armv7l':
+ platform += 'ARM7'
+ elif target == ppc64:
+ platform += 'PPC64'
+ elif target == ppc64le:
+ platform += 'PPC64le'
+ elif platform == 'darwin':
+ if target == 'x86_64':
+ platform += 'Intel'
+ if self.foam_cfg['WM_ARCH_OPTION'] == '64':
+ platform += '64'
+ # ... and others?
+ return platform
+
+ def openfoam_compiler(self):
+ """Capitalized version of the compiler name, which usually corresponds
+ to how OpenFOAM will camel-case things.
+ Use compiler_mapping to handing special cases.
+ Also handle special compiler options (eg, KNL)
+ """
+ comp = self.compiler.name
+ if comp in self.compiler_mapping:
+ comp = self.compiler_mapping[comp]
+ comp = comp.capitalize()
+
+ if '+knl' in self.spec:
+ comp += 'KNL'
+ return comp
+
+ def set_openfoam(self):
+ """Populate foam_cfg, foam_sys according to
+ variants, architecture, compiler.
+ Returns WM_OPTIONS.
+ """
+ # Run once
+ opts = self.foam_sys['WM_OPTIONS']
+ if opts:
+ return opts
+
+ wm_arch = self.openfoam_arch()
+ wm_compiler = self.openfoam_compiler()
+ compileOpt = self.foam_cfg['WM_COMPILE_OPTION']
+
+ # Insist on a wmake rule for this architecture/compiler combination
+ archCompiler = wm_arch + wm_compiler
+ compiler_rule = join_path(
+ self.stage.source_path, 'wmake', 'rules', archCompiler)
+
+ if not isdir(compiler_rule):
+ raise RuntimeError(
+ 'No wmake rule for {0}'.format(archCompiler))
+ if not re.match(r'.+Opt$', compileOpt):
+ raise RuntimeError(
+ "WM_COMPILE_OPTION={0} is not type '*Opt'".format(compileOpt))
+
+ # Adjust for variants
+ self.foam_cfg['WM_LABEL_SIZE'] = (
+ '64' if '+int64' in self.spec else '32'
+ )
+ self.foam_cfg['WM_PRECISION_OPTION'] = (
+ 'SP' if '+float32' in self.spec else 'DP'
+ )
+
+ # ----
+ # WM_LABEL_OPTION=Int$WM_LABEL_SIZE
+ # WM_OPTIONS=$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_LABEL_OPTION$WM_COMPILE_OPTION
+ # ----
+ self.foam_sys['WM_ARCH'] = wm_arch
+ self.foam_sys['WM_COMPILER'] = wm_compiler
+ self.foam_cfg['WM_COMPILER'] = wm_compiler # For bashrc,cshrc too
+ self.foam_sys['WM_OPTIONS'] = ''.join([
+ wm_arch,
+ wm_compiler,
+ self.foam_cfg['WM_PRECISION_OPTION'],
+ 'Int', self.foam_cfg['WM_LABEL_SIZE'], # Int32/Int64
+ compileOpt
+ ])
+ return self.foam_sys['WM_OPTIONS']
+
+ def patch(self):
+ """Adjust OpenFOAM build for spack. Where needed, apply filter as an
+ alternative to normal patching.
+ """
+ self.set_openfoam() # May need foam_cfg/foam_sys information
+
+ # This is fairly horrible.
+ # The github tarfiles have weird names that do not correspond to the
+ # canonical name. We need to rename these, but leave a symlink for
+ # spack to work with.
+ #
+ # Note that this particular OpenFOAM release requires absolute
+ # directories to build correctly!
+ parent = os.path.dirname(self.stage.source_path)
+ original = os.path.basename(self.stage.source_path)
+ target = self._canonical
+ with working_dir(parent):
+ if original != target and not os.path.lexists(target):
+ os.rename(original, target)
+ os.symlink(target, original)
+ tty.info('renamed {0} -> {1}'.format(original, target))
+
+ # Avoid WM_PROJECT_INST_DIR for ThirdParty, site or jobControl.
+ # Use openfoam-site.patch to handle jobControl, site.
+ #
+ # Filter (not patch) bashrc,cshrc for additional flexibility
+ wm_setting = {
+ 'WM_THIRD_PARTY_DIR':
+ r'$WM_PROJECT_DIR/ThirdParty #SPACK: No separate third-party',
+ 'WM_VERSION': self.version, # consistency
+ 'FOAMY_HEX_MESH': '', # This is horrible (unset variable?)
+ }
+
+ rewrite_environ_files( # Adjust etc/bashrc and etc/cshrc
+ wm_setting,
+ posix=join_path('etc', 'bashrc'),
+ cshell=join_path('etc', 'cshrc'))
+
+ # Build wrapper script
+ with open(self.build_script, 'w') as out:
+ out.write(
+ """#!/bin/bash
+. $PWD/etc/bashrc '' # No arguments
+mkdir -p $FOAM_APPBIN $FOAM_LIBBIN 2>/dev/null # Allow interrupt
+echo Build openfoam with SPACK
+echo WM_PROJECT_DIR = $WM_PROJECT_DIR
+./Allwmake $@
+#
+""")
+ set_executable(self.build_script)
+ self.configure(self.spec, self.prefix) # Should be a separate phase
+
+ def configure(self, spec, prefix):
+ """Make adjustments to the OpenFOAM configuration files in their various
+ locations: etc/bashrc, etc/config.sh/FEATURE and customizations that
+ don't properly fit get placed in the etc/prefs.sh file (similiarly for
+ csh).
+ """
+ self.set_openfoam() # Need foam_cfg/foam_sys information
+
+ # Some settings for filtering bashrc, cshrc
+ wm_setting = {}
+ wm_setting.update(self.foam_cfg)
+
+ rewrite_environ_files( # Adjust etc/bashrc and etc/cshrc
+ wm_setting,
+ posix=join_path('etc', 'bashrc'),
+ cshell=join_path('etc', 'cshrc'))
+
+ # MPI content, with absolute paths
+ content = mplib_content(spec)
+
+ # Content for etc/prefs.{csh,sh}
+ self.etc_prefs = {
+ r'MPI_ROOT': spec['mpi'].prefix, # Absolute
+ r'MPI_ARCH_FLAGS': '"%s"' % content['FLAGS'],
+ r'MPI_ARCH_INC': '"%s"' % content['PINC'],
+ r'MPI_ARCH_LIBS': '"%s"' % content['PLIBS'],
+ }
+
+ # Content for etc/config.{csh,sh}/ files
+ self.etc_config = {
+ 'CGAL': {},
+ 'scotch': {},
+ 'metis': {},
+ 'paraview': [],
+ }
+
+ if True:
+ self.etc_config['scotch'] = {
+ 'SCOTCH_ARCH_PATH': spec['scotch'].prefix,
+ # For src/parallel/decompose/Allwmake
+ 'SCOTCH_VERSION': 'scotch-{0}'.format(spec['scotch'].version),
+ }
+
+ # Write prefs files according to the configuration.
+ # Only need prefs.sh for building, but install both for end-users
+ if self.etc_prefs:
+ write_environ(
+ self.etc_prefs,
+ posix=join_path('etc', 'prefs.sh'),
+ cshell=join_path('etc', 'prefs.csh'))
+
+ # Adjust components to use SPACK variants
+ for component, subdict in self.etc_config.iteritems():
+ write_environ(
+ subdict,
+ posix=join_path('etc', 'config.sh', component),
+ cshell=join_path('etc', 'config.csh', component))
+
+ archCompiler = self.foam_sys['WM_ARCH'] + self.foam_sys['WM_COMPILER']
+ compileOpt = self.foam_cfg['WM_COMPILE_OPTION']
+ general_rule = join_path('wmake', 'rules', 'General')
+ compiler_rule = join_path('wmake', 'rules', archCompiler)
+ generate_mplib_rules(general_rule, self.spec)
+ generate_compiler_rules(compiler_rule, compileOpt, self.rpath_info)
+ # Record the spack spec information
+ with open("log.spack-spec", 'w') as outfile:
+ outfile.write(spec.tree())
+
+ def build(self, spec, prefix):
+ """Build using the OpenFOAM Allwmake script, with a wrapper to source
+ its environment first.
+ """
+ self.set_openfoam() # Force proper population of foam_cfg/foam_sys
+ args = []
+ if self.parallel: # Build in parallel? - pass via the environment
+ os.environ['WM_NCOMPPROCS'] = str(self.make_jobs) \
+ if self.make_jobs else str(multiprocessing.cpu_count())
+ builder = Executable(self.build_script)
+ builder(*args)
+
+ def install(self, spec, prefix):
+ """Install under the projectdir (== prefix/name-version)"""
+ self.build(spec, prefix) # Should be a separate phase
+ opts = self.wm_options
+
+ mkdirp(self.projectdir)
+ projdir = os.path.basename(self.projectdir)
+ wm_setting = {
+ 'WM_PROJECT_INST_DIR': os.path.dirname(self.projectdir),
+ 'WM_PROJECT_DIR': join_path('$WM_PROJECT_INST_DIR', projdir),
+ }
+
+ # Retain build log file
+ out = "spack-build.out"
+ if isfile(out):
+ install(out, join_path(self.projectdir, "log." + opts))
+
+ # All top-level files, except spack build info and possibly Allwmake
+ if '+source' in spec:
+ ignored = re.compile(r'^spack-.*')
+ else:
+ ignored = re.compile(r'^(Allwmake|spack-).*')
+
+ files = [
+ f for f in glob.glob("*") if isfile(f) and not ignored.search(f)
+ ]
+ for f in files:
+ install(f, self.projectdir)
+
+ # Having wmake without sources is actually somewhat pointless...
+ dirs = ['bin', 'etc', 'wmake']
+ if '+source' in spec:
+ dirs.extend(['applications', 'src', 'tutorials'])
+
+ for d in dirs:
+ install_tree(
+ d,
+ join_path(self.projectdir, d))
+
+ dirs = ['platforms']
+ if '+source' in spec:
+ dirs.extend(['doc'])
+
+ # Install platforms (and doc) skipping intermediate targets
+ ignored = ['src', 'applications', 'html', 'Guides']
+ for d in dirs:
+ install_tree(
+ d,
+ join_path(self.projectdir, d),
+ ignore=shutil.ignore_patterns(*ignored))
+
+ rewrite_environ_files( # Adjust etc/bashrc and etc/cshrc
+ wm_setting,
+ posix=join_path(self.etc, 'bashrc'),
+ cshell=join_path(self.etc, 'cshrc'))
+ self.install_links()
+
+ def install_links(self):
+ """Add symlinks into bin/, lib/ (eg, for other applications)"""
+ if not self.extra_symlinks:
+ return
+
+ # ln -s platforms/linux64GccXXX/lib lib
+ with working_dir(self.projectdir):
+ if isdir(self.archlib):
+ os.symlink(self.archlib, 'lib')
+
+ # (cd bin && ln -s ../platforms/linux64GccXXX/bin/* .)
+ with working_dir(join_path(self.projectdir, 'bin')):
+ for f in [
+ f for f in glob.glob(join_path('..', self.archbin, "*"))
+ if isfile(f)
+ ]:
+ os.symlink(f, os.path.basename(f))
+
+# -----------------------------------------------------------------------------