summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/spack/defaults/packages.yaml2
-rw-r--r--var/spack/repos/builtin/packages/foam-extend/package.py292
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/common/README2
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/common/README-spack15
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/common/change-sitedir.sh94
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/common/change-userdir.sh94
-rwxr-xr-xvar/spack/repos/builtin/packages/openfoam-com/common/spack-Allwmake22
-rwxr-xr-xvar/spack/repos/builtin/packages/openfoam-com/common/spack-derived-Allwmake26
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/mgridgen-lib-1612.patch41
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/openfoam-site-1612.patch (renamed from var/spack/repos/builtin/packages/openfoam-com/openfoam-site.patch)6
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/openfoam-site-plus.patch35
-rw-r--r--var/spack/repos/builtin/packages/openfoam-com/package.py677
-rwxr-xr-xvar/spack/repos/builtin/packages/openfoam-org/assets/bin/foamEtcFile417
-rw-r--r--var/spack/repos/builtin/packages/openfoam-org/openfoam-site-41.patch (renamed from var/spack/repos/builtin/packages/openfoam-org/openfoam-site.patch)6
-rw-r--r--var/spack/repos/builtin/packages/openfoam-org/package.py344
15 files changed, 1316 insertions, 757 deletions
diff --git a/etc/spack/defaults/packages.yaml b/etc/spack/defaults/packages.yaml
index 0cafab28e9..d04ce76e6b 100644
--- a/etc/spack/defaults/packages.yaml
+++ b/etc/spack/defaults/packages.yaml
@@ -28,6 +28,6 @@ packages:
mpe: [mpe2]
mpi: [openmpi, mpich]
opencl: [pocl]
- openfoam: [foam-extend]
+ openfoam: [openfoam-com, openfoam-org, foam-extend]
pil: [py-pillow]
scalapack: [netlib-scalapack]
diff --git a/var/spack/repos/builtin/packages/foam-extend/package.py b/var/spack/repos/builtin/packages/foam-extend/package.py
index c68e570c0f..d417ef8cf3 100644
--- a/var/spack/repos/builtin/packages/foam-extend/package.py
+++ b/var/spack/repos/builtin/packages/foam-extend/package.py
@@ -48,16 +48,17 @@
# - reworked to mirror the openfoam-com package.
# If changes are needed here, consider if they need applying there too.
#
+# Known issues
+# - Combining +parmgridgen with +float32 probably won't work.
+#
##############################################################################
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 *
@@ -77,10 +78,9 @@ class FoamExtend(Package):
version('3.0', git='http://git.code.sf.net/p/foam-extend/foam-extend-3.0')
# variant('int64', default=False,
- # description='Compile with 64-bit labels')
+ # description='Compile with 64-bit label')
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,
@@ -96,10 +96,6 @@ class FoamExtend(Package):
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')
@@ -111,189 +107,77 @@ class FoamExtend(Package):
depends_on('scotch~metis+mpi', when='+ptscotch')
depends_on('metis@5:', when='+metis')
depends_on('parmetis', when='+parmetis')
- depends_on('parmgridgen', when='+parmgridgen')
+ # mgridgen is statically linked
+ depends_on('parmgridgen', when='+parmgridgen', type='build')
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
- }
+ # General patches
+ common = ['spack-Allwmake', 'README-spack']
+ assets = []
- # The system description is frequently needed
- foam_sys = {
- 'WM_ARCH': None,
- 'WM_COMPILER': None,
- 'WM_OPTIONS': None,
+ # Some user config settings
+ config = {
+ 'label-size': False, # <- No int32/int64 support
+ 'mplib': 'USERMPI', # USER | USERMPI
}
+ # The openfoam architecture, compiler information etc
+ _foam_arch = 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'
+ phases = ['configure', 'build', 'install']
+ build_script = './spack-Allwmake' # <- Added by patch() method.
+
+ #
+ # - End of definitions / setup -
+ #
def setup_environment(self, spack_env, run_env):
- run_env.set('FOAM_INST_DIR', self.prefix)
+ run_env.set('FOAM_INST_DIR', os.path.dirname(self.projectdir)),
+ run_env.set('FOAM_PROJECT_DIR', self.projectdir)
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))
+ for d in ['wmake', self.archbin]: # bin already added automatically
+ run_env.prepend_path('PATH', join_path(self.projectdir, d))
+ run_env.set('MPI_BUFFER_SIZE', "20000000")
+
+ def setup_dependent_environment(self, spack_env, run_env, dependent_spec):
+ """Provide location of the OpenFOAM project.
+ This is identical to the WM_PROJECT_DIR value, but we avoid that
+ variable since it would mask the normal OpenFOAM cleanup of
+ previous versions.
+ """
+ spack_env.set('FOAM_PROJECT_DIR', self.projectdir)
@property
def projectdir(self):
"""Absolute location of project directory: WM_PROJECT_DIR/"""
- return join_path(self.prefix, self._canonical) # <- prefix/canonical
+ return self.prefix # <- install directly under prefix
@property
- def etc(self):
- """Absolute location of the OpenFOAM etc/ directory"""
- return join_path(self.projectdir, 'etc')
+ def foam_arch(self):
+ if not self._foam_arch:
+ self._foam_arch = OpenfoamArch(self.spec, **self.config)
+ return self._foam_arch
@property
def archbin(self):
"""Relative location of architecture-specific executables"""
- wm_options = self.set_openfoam()
- return join_path('applications', 'bin', wm_options)
+ return join_path('applications', 'bin', self.foam_arch)
@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']
+ return join_path('lib', self.foam_arch)
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
+ """Adjust OpenFOAM build for spack.
+ Where needed, apply filter as an alternative to normal patching."""
+ add_extra_files(self, self.common, self.assets)
# Adjust ParMGridGen - this is still a mess
files = [
@@ -319,23 +203,7 @@ class FoamExtend(Package):
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
+ f, backup=False)
def configure(self, spec, prefix):
"""Make adjustments to the OpenFOAM configuration files in their various
@@ -343,8 +211,6 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
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
@@ -373,7 +239,7 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
},
}
# Adjust configuration via prefs - sort second
- self.etc_prefs['001'].update(self.foam_cfg)
+ self.etc_prefs['001'].update(self.foam_arch.foam_dict())
if '+scotch' in spec or '+ptscotch' in spec:
pkg = spec['scotch'].prefix
@@ -434,41 +300,33 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
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.
+ Only build if the compiler is known to be supported.
"""
- self.set_openfoam() # Force proper population of foam_cfg/foam_sys
+ self.foam_arch.has_rule(self.stage.source_path)
+ self.foam_arch.create_rules(self.stage.source_path, self)
+
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())
+ os.environ['WM_NCOMPPROCS'] = str(make_jobs)
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
+ """Install under the projectdir"""
+ opts = str(self.foam_arch)
# Fairly ugly since intermediate targets are scattered inside sources
appdir = 'applications'
+ projdir = os.path.basename(self.projectdir)
mkdirp(self.projectdir, join_path(self.projectdir, appdir))
-
- # Retain build log file
- out = "spack-build.out"
- if isfile(out):
- install(out, join_path(self.projectdir, "log." + opts))
+ # Filtering: bashrc, cshrc
+ edits = {
+ 'WM_PROJECT_INST_DIR': os.path.dirname(self.projectdir),
+ 'WM_PROJECT_DIR': join_path('$WM_PROJECT_INST_DIR', projdir),
+ }
# All top-level files, except spack build info and possibly Allwmake
if '+source' in spec:
@@ -477,36 +335,52 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
ignored = re.compile(r'^(Allclean|Allwmake|spack-).*')
files = [
- f for f in glob.glob("*") if isfile(f) and not ignored.search(f)
+ f for f in glob.glob("*")
+ if os.path.isfile(f) and not ignored.search(f)
]
for f in files:
install(f, self.projectdir)
# Install directories. install applications/bin directly
- for d in ['bin', 'etc', 'wmake', 'lib', join_path(appdir, 'bin')]:
+ # Install 'etc' before 'bin' (for symlinks)
+ for d in ['etc', 'bin', 'wmake', 'lib', join_path(appdir, 'bin')]:
install_tree(
d,
- join_path(self.projectdir, d))
+ join_path(self.projectdir, d),
+ symlinks=True)
if '+source' in spec:
subitem = join_path(appdir, 'Allwmake')
install(subitem, join_path(self.projectdir, subitem))
- ignored = [opts] # Intermediate targets
+ ignored = [opts] # Ignore intermediate targets
for d in ['src', 'tutorials']:
install_tree(
d,
join_path(self.projectdir, d),
- ignore=shutil.ignore_patterns(*ignored))
+ ignore=shutil.ignore_patterns(*ignored),
+ symlinks=True)
for d in ['solvers', 'utilities']:
install_tree(
join_path(appdir, d),
join_path(self.projectdir, appdir, d),
- ignore=shutil.ignore_patterns(*ignored))
+ ignore=shutil.ignore_patterns(*ignored),
+ symlinks=True)
+
+ etc_dir = join_path(self.projectdir, 'etc')
+ rewrite_environ_files( # Adjust etc/bashrc and etc/cshrc
+ edits,
+ posix=join_path(etc_dir, 'bashrc'),
+ cshell=join_path(etc_dir, 'cshrc'))
+ self.install_links()
def install_links(self):
"""Add symlinks into bin/, lib/ (eg, for other applications)"""
- return
+ # Make build log visible - it contains OpenFOAM-specific information
+ with working_dir(self.projectdir):
+ os.symlink(
+ join_path('.spack', 'build.out'),
+ join_path('log.' + str(self.foam_arch)))
# -----------------------------------------------------------------------------
diff --git a/var/spack/repos/builtin/packages/openfoam-com/common/README b/var/spack/repos/builtin/packages/openfoam-com/common/README
new file mode 100644
index 0000000000..d116bbaa23
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/common/README
@@ -0,0 +1,2 @@
+Some helper tools for packaging applications/libraries dependent on an
+openfoam provider.
diff --git a/var/spack/repos/builtin/packages/openfoam-com/common/README-spack b/var/spack/repos/builtin/packages/openfoam-com/common/README-spack
new file mode 100644
index 0000000000..83b606dda1
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/common/README-spack
@@ -0,0 +1,15 @@
+Additional notes for spack
+--------------------------
+
+OpenFOAM largely manages its own PATH and LD_LIBRARY_PATH settings.
+The spack build currently also follows this and only provides
+a minimum modules environment.
+
+The variable FOAM_PROJECT_DIR points to the location of the OpenFOAM project
+and shall contain a $FOAM_PROJECT_DIR/etc/bashrc file for OpenFOAM.
+The variable FOAM_INST_DIR may also be provided for older OpenFOAM versions.
+
+It is the aim for the future to use spack to provide the environment directly,
+but this still needs more work.
+
+2017-04-18
diff --git a/var/spack/repos/builtin/packages/openfoam-com/common/change-sitedir.sh b/var/spack/repos/builtin/packages/openfoam-com/common/change-sitedir.sh
new file mode 100644
index 0000000000..61d9c3ea8b
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/common/change-sitedir.sh
@@ -0,0 +1,94 @@
+#----------------------------------*-sh-*--------------------------------------
+# ========= |
+# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+# \\ / O peration |
+# \\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
+# \\/ M anipulation |
+#------------------------------------------------------------------------------
+# License
+# This file is part of OpenFOAM.
+#
+# OpenFOAM is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# OpenFOAM 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 GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
+#
+# Script
+# . change-sitedir.sh PREFIX [SUFFIX]
+#
+# Shortcuts (prefix)
+# -prefix "$WM_PROJECT_INST_DIR/site"
+# -project "$WM_PROJECT_DIR/site"
+# -none remove from environment
+#
+# Shortcuts (suffix)
+# -platforms "platforms/$WM_OPTIONS"
+#
+# Description
+# Change WM_PROJECT_SITE, FOAM_SITE_APPBIN, FOAM_SITE_LIBBIN
+# and the respective entries in PATH, LD_LIBRARY_PATH.
+#
+# This can be useful when temporarily reassigning the site directory
+# when packaging OpenFOAM.
+#
+# The suffix value should normally include "platforms/$WM_OPTIONS"
+#
+# Example
+# . /path/change-sitedir.sh -prefix -platforms
+#
+# corresponds to the standard site location:
+#
+# $WM_PROJECT_INST_DIR/site{/$WM_PROJECT_VERSION/platforms/$WM_OPTIONS}
+#
+#------------------------------------------------------------------------------
+
+if [ "$#" -ge 1 ]
+then
+ prefix="$1"
+ suffix="$2"
+
+ foamOldDirs="$FOAM_SITE_APPBIN $FOAM_SITE_LIBBIN \
+ $WM_PROJECT_SITE $WM_PROJECT_INST_DIR/site $WM_PROJECT_DIR/site"
+ foamClean=$WM_PROJECT_DIR/bin/foamCleanPath
+ if [ -x "$foamClean" ]
+ then
+ cleaned=$($foamClean "$PATH" "$foamOldDirs") && PATH="$cleaned"
+ cleaned=$($foamClean "$LD_LIBRARY_PATH" "$foamOldDirs") \
+ && LD_LIBRARY_PATH="$cleaned"
+ fi
+
+ case "$suffix" in
+ -plat*) suffix="platforms/$WM_OPTIONS" ;;
+ esac
+ case "$prefix" in
+ -prefix) prefix="$WM_PROJECT_INST_DIR/site" ;;
+ -project) prefix="$WM_PROJECT_DIR/site" ;;
+ -none) unset prefix ;;
+ esac
+
+ if [ -n "$prefix" ]
+ then
+ export WM_PROJECT_SITE="$prefix"
+
+ prefix="$prefix/${WM_PROJECT_VERSION:-unknown}${suffix:+/}${suffix}"
+
+ export FOAM_SITE_APPBIN="$prefix/bin"
+ export FOAM_SITE_LIBBIN="$prefix/lib"
+ PATH="$FOAM_SITE_APPBIN:$PATH"
+ LD_LIBRARY_PATH="$FOAM_SITE_LIBBIN:$LD_LIBRARY_PATH"
+ else
+ unset WM_PROJECT_SITE FOAM_SITE_APPBIN FOAM_SITE_LIBBIN
+ fi
+fi
+
+unset foamClean foamOldDirs cleaned prefix suffix
+
+#------------------------------------------------------------------------------
diff --git a/var/spack/repos/builtin/packages/openfoam-com/common/change-userdir.sh b/var/spack/repos/builtin/packages/openfoam-com/common/change-userdir.sh
new file mode 100644
index 0000000000..d126fcfe5d
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/common/change-userdir.sh
@@ -0,0 +1,94 @@
+#----------------------------------*-sh-*--------------------------------------
+# ========= |
+# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+# \\ / O peration |
+# \\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
+# \\/ M anipulation |
+#------------------------------------------------------------------------------
+# License
+# This file is part of OpenFOAM.
+#
+# OpenFOAM is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# OpenFOAM 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 GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
+#
+# Script
+# . change-userdir.sh PREFIX [SUFFIX]
+#
+# Shortcuts (prefix)
+# -home "$HOME/OpenFOAM/$USER-$WM_PROJECT_VERSION"
+# -none remove from environment
+#
+# Shortcuts (suffix)
+# -platforms "platforms/$WM_OPTIONS"
+#
+# Description
+# Change WM_PROJECT_USER_DIR, FOAM_USER_APPBIN, FOAM_USER_LIBBIN
+# and the respective entries in PATH, LD_LIBRARY_PATH.
+# Also adjusts FOAM_RUN.
+#
+# This can be useful with compiling additional OpenFOAM programs
+# (that use FOAM_USER_APPBIN, FOAM_USER_LIBBIN for their build),
+# to avoid conflicts with the normal user bin/lib files.
+#
+# The suffix value should normally include "platforms/$WM_OPTIONS"
+#
+# Example
+# . /path/change-userdir.sh -home -platforms
+#
+# corresponds to the standard user location:
+#
+# $HOME/OpenFOAM/$USER-$WM_PROJECT_VERSION/platforms/$WM_OPTIONS
+#
+#------------------------------------------------------------------------------
+
+if [ "$#" -ge 1 ]
+then
+ prefix="$1"
+ suffix="$2"
+
+ foamOldDirs="$FOAM_USER_APPBIN $FOAM_USER_LIBBIN"
+ foamClean=$WM_PROJECT_DIR/bin/foamCleanPath
+ if [ -x "$foamClean" ]
+ then
+ cleaned=$($foamClean "$PATH" "$foamOldDirs") && PATH="$cleaned"
+ cleaned=$($foamClean "$LD_LIBRARY_PATH" "$foamOldDirs") \
+ && LD_LIBRARY_PATH="$cleaned"
+ fi
+
+ case "$suffix" in
+ -plat*) suffix="platforms/$WM_OPTIONS" ;;
+ esac
+ case "$prefix" in
+ -home) prefix="$HOME/OpenFOAM/$USER-${WM_PROJECT_VERSION:-unknown}" ;;
+ -none) unset prefix ;;
+ esac
+
+ if [ -n "$prefix" ]
+ then
+ export WM_PROJECT_USER_DIR="$prefix"
+ export FOAM_RUN="$prefix/run"
+
+ prefix="$prefix${suffix:+/}${suffix}"
+ export FOAM_USER_APPBIN="$prefix/bin"
+ export FOAM_USER_LIBBIN="$prefix/lib"
+
+ PATH="$FOAM_USER_APPBIN:$PATH"
+ LD_LIBRARY_PATH="$FOAM_USER_LIBBIN:$LD_LIBRARY_PATH"
+ else
+ unset WM_PROJECT_USER_DIR FOAM_RUN FOAM_USER_APPBIN FOAM_USER_LIBBIN
+ fi
+fi
+
+unset foamClean foamOldDirs cleaned prefix suffix
+
+#------------------------------------------------------------------------------
diff --git a/var/spack/repos/builtin/packages/openfoam-com/common/spack-Allwmake b/var/spack/repos/builtin/packages/openfoam-com/common/spack-Allwmake
new file mode 100755
index 0000000000..cff22daf10
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/common/spack-Allwmake
@@ -0,0 +1,22 @@
+#!/bin/bash
+# Build wrapper script - FOAM_INST_DIR is only required by foam-extend
+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 $@ # Pass arguments
+
+# Link non-dummy MPI_FOAM type to parent-dir, where rpath can find it
+if [ "${FOAM_MPI:=dummy}" != dummy -a -d "$FOAM_LIBBIN/$FOAM_MPI" ]
+then
+(
+ cd "$FOAM_LIBBIN" || exit 1
+ for i in $FOAM_MPI/lib*.so
+ do
+ [ -f $i ] && ln -sf $i "${i##*/}"
+ done
+)
+fi
+
+# -----------------------------------------------------------------------------
diff --git a/var/spack/repos/builtin/packages/openfoam-com/common/spack-derived-Allwmake b/var/spack/repos/builtin/packages/openfoam-com/common/spack-derived-Allwmake
new file mode 100755
index 0000000000..407ad734e8
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/common/spack-derived-Allwmake
@@ -0,0 +1,26 @@
+#!/bin/bash
+# The openfoam providers must export 'FOAM_PROJECT_DIR'
+# The package is expected to supply an appropriate Allwmake file.
+
+[ -d "$FOAM_PROJECT_DIR" -a -f "$FOAM_PROJECT_DIR/etc/bashrc" ] || {
+ echo "Error: no PROJECT=$FOAM_PROJECT_DIR" 1>&2
+ echo " or no etc/bashrc found" 1>&2
+ exit 1
+}
+
+export FOAM_INST_DIR=$(cd $FOAM_PROJECT_DIR/.. && pwd -L) # Needed by foam-extend
+. $FOAM_PROJECT_DIR/etc/bashrc '' # No arguments
+
+# Package-specific adjustments
+[ -f spack-config.sh ] && . ./spack-config.sh '' # No arguments
+
+echo "========================================"
+date "+%Y-%m-%d %H:%M:%S %z" 2>/dev/null || echo "date is unknown"
+echo "Build with ${WM_PROJECT}-${WM_PROJECT_VERSION}"
+echo " WM_PROJECT_DIR = $WM_PROJECT_DIR"
+echo " $WM_COMPILER $WM_COMPILER_TYPE compiler"
+echo " $WM_OPTIONS - with $WM_MPLIB $FOAM_MPI"
+echo
+
+./Allwmake $@ # Pass arguments
+# -----------------------------------------------------------------------------
diff --git a/var/spack/repos/builtin/packages/openfoam-com/mgridgen-lib-1612.patch b/var/spack/repos/builtin/packages/openfoam-com/mgridgen-lib-1612.patch
new file mode 100644
index 0000000000..8dc0b995ff
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/mgridgen-lib-1612.patch
@@ -0,0 +1,41 @@
+--- OpenFOAM-v1612+.orig/src/fvAgglomerationMethods/Allwmake 2017-01-02 09:56:17.578558265 +0100
++++ OpenFOAM-v1612+/src/fvAgglomerationMethods/Allwmake 2017-04-18 18:58:38.236795902 +0200
+@@ -4,9 +4,13 @@
+ # Parse arguments for library compilation
+ . $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
+
+-export ParMGridGen=$WM_THIRD_PARTY_DIR/ParMGridGen-1.0
++unset MGRIDGEN_ARCH_PATH
++if settings=$($WM_PROJECT_DIR/bin/foamEtcFile config.sh/mgridgen)
++then
++ . $settings
++fi
+
+-if [ -e "$FOAM_LIBBIN/libMGridGen.so" ]
++if [ -e "$MGRIDGEN_ARCH_PATH/include/mgridgen.h" ]
+ then
+ wmake $targetType MGridGenGamgAgglomeration
+ fi
+--- OpenFOAM-v1612+.orig/src/fvAgglomerationMethods/MGridGenGamgAgglomeration/Make/options 2017-01-02 09:56:17.578558265 +0100
++++ OpenFOAM-v1612+/src/fvAgglomerationMethods/MGridGenGamgAgglomeration/Make/options 2017-04-18 18:59:16.860662811 +0200
+@@ -1,15 +1,9 @@
+-/* Needs ParMGridGen environment variable set. (see Allwmake script) */
+-
+-TYPE_REAL=
+-#if defined(WM_SP)
+-TYPE_REAL=-DTYPE_REAL
+-#endif
+-
+ EXE_INC = \
+ -I$(LIB_SRC)/finiteVolume/lnInclude \
+- -I$(ParMGridGen)/MGridGen/Lib/lnInclude \
+- -I$(ParMGridGen)/MGridGen/IMlib/lnInclude \
+- $(TYPE_REAL)
++ -I$(MGRIDGEN_ARCH_PATH)/include
+
+ LIB_LIBS = \
+- -L$(FOAM_EXT_LIBBIN) -lMGridGen
++ -L$(FOAM_EXT_LIBBIN) \
++ -L$(MGRIDGEN_ARCH_PATH)/lib \
++ -L$(MGRIDGEN_ARCH_PATH)/lib$(WM_COMPILER_LIB_ARCH) \
++ -lmgrid
diff --git a/var/spack/repos/builtin/packages/openfoam-com/openfoam-site.patch b/var/spack/repos/builtin/packages/openfoam-com/openfoam-site-1612.patch
index 6631025788..d988c2f9b8 100644
--- a/var/spack/repos/builtin/packages/openfoam-com/openfoam-site.patch
+++ b/var/spack/repos/builtin/packages/openfoam-com/openfoam-site-1612.patch
@@ -6,7 +6,7 @@ diff -uw OpenFOAM-v1612+.orig/etc/config.sh/settings OpenFOAM-v1612+/etc/config.
# 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
++export FOAM_JOB_DIR=$HOME/.OpenFOAM/jobControl #SPACK: non-central location
# wmake configuration
export WM_DIR=$WM_PROJECT_DIR/wmake
@@ -15,7 +15,7 @@ diff -uw OpenFOAM-v1612+.orig/etc/config.sh/settings OpenFOAM-v1612+/etc/config.
# Site-specific directory
-siteDir="${WM_PROJECT_SITE:-$WM_PROJECT_INST_DIR/site}"
-+siteDir="${WM_PROJECT_SITE:-$WM_PROJECT/site}" #SPACK: not in parent directory
++siteDir="${WM_PROJECT_SITE:-$WM_PROJECT_DIR/site}" #SPACK: not in parent directory
# Shared site executables/libraries
# Similar naming convention as ~OpenFOAM expansion
@@ -27,7 +27,7 @@ diff -uw OpenFOAM-v1612+.orig/etc/config.csh/settings OpenFOAM-v1612+/etc/config
# 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
++setenv FOAM_JOB_DIR=$HOME/.OpenFOAM/jobControl #SPACK: non-central location
# wmake configuration
setenv WM_DIR $WM_PROJECT_DIR/wmake
diff --git a/var/spack/repos/builtin/packages/openfoam-com/openfoam-site-plus.patch b/var/spack/repos/builtin/packages/openfoam-com/openfoam-site-plus.patch
new file mode 100644
index 0000000000..a1f5d8a08a
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-com/openfoam-site-plus.patch
@@ -0,0 +1,35 @@
+diff -uw OpenFOAM-plus.orig/etc/config.sh/settings OpenFOAM-plus/etc/config.sh/settings
+--- OpenFOAM-plus.orig/etc/config.sh/settings 2017-04-04 17:34:29.875873400 +0200
++++ OpenFOAM-plus/etc/config.sh/settings 2017-04-04 17:38:40.174992466 +0200
+@@ -154,10 +154,10 @@
+ export FOAM_LIBBIN=$WM_PROJECT_DIR/platforms/$WM_OPTIONS/lib
+
+ # External (ThirdParty) libraries
+-export FOAM_EXT_LIBBIN=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_LABEL_OPTION/lib
++unset FOAM_EXT_LIBBIN #SPACK: none
+
+ # Site-specific directory
+-siteDir="${WM_PROJECT_SITE:-$WM_PROJECT_INST_DIR/site}"
++siteDir="${WM_PROJECT_SITE:-$WM_PROJECT_DIR/site}" #SPACK: not in parent directory
+
+ # Shared site executables/libraries
+ # Similar naming convention as ~OpenFOAM expansion
+diff -uw OpenFOAM-plus.orig/etc/config.csh/settings OpenFOAM-plus/etc/config.csh/settings
+--- OpenFOAM-plus.orig/etc/config.csh/settings 2017-04-04 17:34:28.255879107 +0200
++++ OpenFOAM-plus/etc/config.csh/settings 2017-04-04 17:39:22.214844670 +0200
+@@ -151,13 +151,13 @@
+ setenv FOAM_LIBBIN $WM_PROJECT_DIR/platforms/$WM_OPTIONS/lib
+
+ # External (ThirdParty) libraries
+-setenv FOAM_EXT_LIBBIN $WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_LABEL_OPTION/lib
++unsetenv FOAM_EXT_LIBBIN #SPACK: none
+
+ # Site-specific directory
+ 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
index 15c4f8fdd4..c6dd6dbe9a 100644
--- a/var/spack/repos/builtin/packages/openfoam-com/package.py
+++ b/var/spack/repos/builtin/packages/openfoam-com/package.py
@@ -50,38 +50,74 @@
# variants: +plugins +qt
# in ~/.spack/packages.yaml
#
+# Known issues
# - Combining +zoltan with +int64 has not been tested, but probably won't work.
+# - Combining +mgridgen with +int64 or +float32 probably won't work.
#
##############################################################################
from spack import *
from spack.environment import *
+import llnl.util.tty as tty
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',
+ 'add_extra_files',
'write_environ',
'rewrite_environ_files',
'mplib_content',
- 'generate_mplib_rules',
- 'generate_compiler_rules',
+ 'foamAddPath',
+ 'foamAddLib',
+ 'OpenfoamArch',
]
+def add_extra_files(foam_pkg, common, local, **kwargs):
+ """Copy additional common and local files into the stage.source_path
+ from the openfoam-com/common and the package/assets directories,
+ respectively
+ """
+ outdir = foam_pkg.stage.source_path
+
+ indir = join_path(os.path.dirname(__file__), 'common')
+ for f in common:
+ tty.info('Added file {0}'.format(f))
+ install(join_path(indir, f), join_path(outdir, f))
+
+ indir = join_path(foam_pkg.package_dir, 'assets')
+ for f in local:
+ tty.info('Added file {0}'.format(f))
+ install(join_path(indir, f), join_path(outdir, f))
+
+
def format_export(key, value):
- """Format key,value pair as 'export' with newline for POSIX shell."""
- return 'export {0}={1}\n'.format(key, value)
+ """Format key,value pair as 'export' with newline for POSIX shell.
+ A leading '#' for key adds a comment character to the entire line.
+ A value of 'None' corresponds to 'unset'.
+ """
+ if key.startswith('#'):
+ return '## export {0}={1}\n'.format(re.sub(r'^#+\s*', '', key), value)
+ elif value is None:
+ return 'unset {0}\n'.format(key)
+ else:
+ 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)
+ """Format key,value pair as 'setenv' with newline for C-shell.
+ A leading '#' for key adds a comment character to the entire line.
+ A value of 'None' corresponds to 'unsetenv'.
+ """
+ if key.startswith('#'):
+ return '## setenv {0} {1}\n'.format(re.sub(r'^#+\s*', '', key), value)
+ elif value is None:
+ return 'unsetenv {0}\n'.format(key)
+ else:
+ return 'setenv {0} {1}\n'.format(key, value)
def _write_environ_entries(outfile, environ, formatter):
@@ -139,7 +175,7 @@ def rewrite_environ_files(environ, **kwargs):
cshell[=None] If set, the name of the C-shell file to rewrite.
"""
posix = kwargs.get('posix', None)
- if posix and isfile(posix):
+ if posix and os.path.isfile(posix):
for k, v in environ.items():
filter_file(
r'^(\s*export\s+%s)=.*$' % k,
@@ -147,7 +183,7 @@ def rewrite_environ_files(environ, **kwargs):
posix,
backup=False)
cshell = kwargs.get('cshell', None)
- if cshell and isfile(cshell):
+ if cshell and os.path.isfile(cshell):
for k, v in environ.items():
filter_file(
r'^(\s*setenv\s+%s)\s+.*$' % k,
@@ -156,19 +192,35 @@ def rewrite_environ_files(environ, **kwargs):
backup=False)
-def pkglib(package):
- """Get lib64 or lib from package prefix"""
+def foamAddPath(*args):
+ """A string with args prepended to 'PATH'"""
+ return '"' + ':'.join(args) + ':${PATH}"'
+
+
+def foamAddLib(*args):
+ """A string with args prepended to 'LD_LIBRARY_PATH'"""
+ return '"' + ':'.join(args) + ':${LD_LIBRARY_PATH}"'
+
+
+def pkglib(package, pre=None):
+ """Get lib64 or lib from package prefix.
+
+ Optional parameter 'pre' to provide alternative prefix
+ """
libdir = package.prefix.lib64
- if isdir(libdir):
+ if not os.path.isdir(libdir):
+ libdir = package.prefix.lib
+ if pre:
+ return join_path(pre, os.path.basename(libdir))
+ else:
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
+ Optional parameter 'pre' to provide alternative prefix
"""
mpi_spec = spec['mpi']
bin = mpi_spec.prefix.bin
@@ -194,36 +246,7 @@ def mplib_content(spec, pre=None):
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.
@@ -239,31 +262,28 @@ class OpenfoamCom(Package):
version('1612', 'ca02c491369150ab127cbb88ec60fbdf',
url=baseurl + '/v1612+/OpenFOAM-v1612+.tgz')
+ version('plus', branch='develop', # Note: needs user credentials
+ git='https://develop.openfoam.com/Development/OpenFOAM-plus.git')
variant('int64', default=False,
- description='Compile with 64-bit labels')
+ description='Compile with 64-bit label')
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')
-
+ # TODO?# variant('scalasca', default=False,
+ # TODO?# description='With scalasca profiling')
+ variant('mgridgen', default=False, description='With mgridgen support')
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'}
+ variant('source', default=True,
+ description='Install library/application sources and tutorials')
provides('openfoam')
depends_on('mpi')
@@ -275,12 +295,14 @@ class OpenfoamCom(Package):
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('scotch~metis+mpi~int64', when='+scotch~int64')
+ depends_on('scotch~metis+mpi+int64', when='+scotch+int64')
depends_on('metis@5:', when='+metis')
depends_on('metis+int64', when='+metis+int64')
- depends_on('parmgridgen', when='+parmgridgen')
+ # mgridgen is statically linked
+ depends_on('parmgridgen', when='+mgridgen', type='build')
depends_on('zoltan', when='+zoltan')
+ # TODO?# depends_on('scalasca', when='+scalasca')
# For OpenFOAM plugins and run-time post-processing this should just be
# 'paraview+plugins' but that resolves poorly.
@@ -289,60 +311,64 @@ class OpenfoamCom(Package):
# 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.0.1', when='@1612+paraview')
depends_on('paraview@5.3:', when='@1706:+paraview')
+ depends_on('paraview@5.3:', when='@plus+paraview')
# General patches
- patch('openfoam-site.patch')
+ common = ['spack-Allwmake', 'README-spack']
+ assets = []
# Version-specific patches
patch('openfoam-bin-1612.patch', when='@1612')
patch('openfoam-etc-1612.patch', when='@1612')
+ patch('openfoam-site-1612.patch', when='@1612')
patch('openfoam-mpi-1612.patch', when='@1612')
patch('openfoam-build-1612.patch', when='@1612')
+ patch('mgridgen-lib-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
- }
+ patch('openfoam-site-plus.patch', when='@plus')
- # The system description is frequently needed
- foam_sys = {
- 'WM_ARCH': None,
- 'WM_COMPILER': None,
- 'WM_OPTIONS': None,
+ # Some user config settings
+ # default: 'compile-option': 'RpathOpt',
+ # default: 'mplib': 'USERMPI', # Use user mpi for spack
+ config = {
+ # Add links into bin/, lib/ (eg, for other applications)
+ 'link': False
}
+ # The openfoam architecture, compiler information etc
+ _foam_arch = 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'
+ phases = ['configure', 'build', 'install']
+ build_script = './spack-Allwmake' # <- Added by patch() method.
- # 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'))
+ #
+ # - End of definitions / setup -
+ #
def setup_environment(self, spack_env, run_env):
+ run_env.set('FOAM_PROJECT_DIR', self.projectdir)
run_env.set('WM_PROJECT_DIR', self.projectdir)
+ for d in ['wmake', self.archbin]: # bin already added automatically
+ run_env.prepend_path('PATH', join_path(self.projectdir, d))
+ run_env.set('MPI_BUFFER_SIZE', "20000000")
+
+ def setup_dependent_environment(self, spack_env, run_env, dependent_spec):
+ """Provide location of the OpenFOAM project.
+ This is identical to the WM_PROJECT_DIR value, but we avoid that
+ variable since it would mask the normal OpenFOAM cleanup of
+ previous versions.
+ """
+ spack_env.set('FOAM_PROJECT_DIR', self.projectdir)
@property
def projectdir(self):
@@ -350,195 +376,50 @@ class OpenfoamCom(Package):
return self.prefix # <- install directly under prefix
@property
- def etc(self):
- """Absolute location of the OpenFOAM etc/ directory"""
- return join_path(self.projectdir, 'etc')
+ def foam_arch(self):
+ if not self._foam_arch:
+ self._foam_arch = OpenfoamArch(self.spec, **self.config)
+ return self._foam_arch
@property
def archbin(self):
"""Relative location of architecture-specific executables"""
- return join_path('platforms', self.wm_options, 'bin')
+ return join_path('platforms', self.foam_arch, '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']
+ return join_path('platforms', self.foam_arch, 'lib')
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
+ """Adjust OpenFOAM build for spack.
+ Where needed, apply filter as an alternative to normal patching."""
+ add_extra_files(self, self.common, self.assets)
# 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 = {
+ # Filtering: bashrc,cshrc (using a patch is less flexible)
+ edits = {
'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,
+ edits,
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)
-
+ # Filtering bashrc, cshrc
+ edits = {}
+ edits.update(self.foam_arch.foam_dict())
rewrite_environ_files( # Adjust etc/bashrc and etc/cshrc
- wm_setting,
+ edits,
posix=join_path('etc', 'bashrc'),
cshell=join_path('etc', 'cshrc'))
@@ -551,27 +432,34 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
}
# MPI content, using MPI_ARCH_PATH
- content = mplib_content(spec, '${MPI_ARCH_PATH}')
+ user_mpi = 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,
- },
+ 'CGAL': [
+ ('BOOST_ARCH_PATH', spec['boost'].prefix),
+ ('CGAL_ARCH_PATH', spec['cgal'].prefix),
+ ('LD_LIBRARY_PATH',
+ foamAddLib(
+ pkglib(spec['boost'], '${BOOST_ARCH_PATH}'),
+ pkglib(spec['cgal'], '${CGAL_ARCH_PATH}'))),
+ ],
+ 'FFTW': [
+ ('FFTW_ARCH_PATH', spec['fftw'].prefix), # Absolute
+ ('LD_LIBRARY_PATH',
+ foamAddLib(
+ pkglib(spec['fftw'], '${BOOST_ARCH_PATH}'))),
+ ],
# 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']),
+ ('LD_LIBRARY_PATH', foamAddLib(user_mpi['libdir'])),
+ ('PATH', foamAddPath(user_mpi['bindir'])),
],
'scotch': {},
'metis': {},
'paraview': [],
+ 'gperftools': [], # Currently unused
}
if '+scotch' in spec:
@@ -590,15 +478,15 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
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),
+ ('ParaView_INCLUDE_DIR', '${ParaView_DIR}/include/' + pvMajor),
('PV_PLUGIN_PATH', '$FOAM_LIBBIN/' + pvMajor),
- ('PATH', '"${ParaView_DIR}/bin:${PATH}"'),
+ ('PATH', foamAddPath('${ParaView_DIR}/bin')),
]
- # Not normally included as etc/config file
- if '+parmgridgen' in spec:
- self.etc_config['parmgridgen'] = {
- 'PARMGRIDGEN_ARCH_PATH': spec['parmgridgen'].prefix
+ # Optional
+ if '+mgridgen' in spec:
+ self.etc_config['mgridgen'] = {
+ 'MGRIDGEN_ARCH_PATH': spec['parmgridgen'].prefix
}
# Optional
@@ -622,45 +510,30 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
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.
+ Only build if the compiler is known to be supported.
"""
- self.set_openfoam() # Force proper population of foam_cfg/foam_sys
+ self.foam_arch.has_rule(self.stage.source_path)
+ self.foam_arch.create_rules(self.stage.source_path, self)
+
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 ''))
+ args.append('-j{0}'.format(make_jobs))
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
-
+ """Install under the projectdir"""
mkdirp(self.projectdir)
projdir = os.path.basename(self.projectdir)
- wm_setting = {
+ # Filtering: bashrc, cshrc
+ edits = {
'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-.*')
@@ -668,20 +541,23 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
ignored = re.compile(r'^(Allwmake|spack-).*')
files = [
- f for f in glob.glob("*") if isfile(f) and not ignored.search(f)
+ f for f in glob.glob("*")
+ if os.path.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']
+ # Having wmake and ~source is actually somewhat pointless...
+ # Install 'etc' before 'bin' (for symlinks)
+ dirs = ['etc', 'bin', 'wmake']
if '+source' in spec:
dirs.extend(['applications', 'src', 'tutorials'])
for d in dirs:
install_tree(
d,
- join_path(self.projectdir, d))
+ join_path(self.projectdir, d),
+ symlinks=True)
dirs = ['platforms']
if '+source' in spec:
@@ -693,30 +569,229 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
install_tree(
d,
join_path(self.projectdir, d),
- ignore=shutil.ignore_patterns(*ignored))
+ ignore=shutil.ignore_patterns(*ignored),
+ symlinks=True)
+ etc_dir = join_path(self.projectdir, 'etc')
rewrite_environ_files( # Adjust etc/bashrc and etc/cshrc
- wm_setting,
- posix=join_path(self.etc, 'bashrc'),
- cshell=join_path(self.etc, 'cshrc'))
+ edits,
+ posix=join_path(etc_dir, 'bashrc'),
+ cshell=join_path(etc_dir, 'cshrc'))
self.install_links()
def install_links(self):
"""Add symlinks into bin/, lib/ (eg, for other applications)"""
- if not self.extra_symlinks:
+ # Make build log visible - it contains OpenFOAM-specific information
+ with working_dir(self.projectdir):
+ os.symlink(
+ join_path('.spack', 'build.out'),
+ join_path('log.' + str(self.foam_arch)))
+
+ if not self.config['link']:
return
# ln -s platforms/linux64GccXXX/lib lib
with working_dir(self.projectdir):
- if isdir(self.archlib):
+ if os.path.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)
+ if os.path.isfile(f)
]:
os.symlink(f, os.path.basename(f))
+ def openfoam_run_environment(self, projdir):
+ # This seems to bomb out with an ImportError 'site'!
+ # mods = EnvironmentModifications.from_sourcing_files(
+ # join_path(projdir, 'etc/bashrc'))
+ pass
+
+
+# -----------------------------------------------------------------------------
+
+class OpenfoamArch(object):
+ """OpenfoamArch represents architecture/compiler settings for OpenFOAM.
+ The string representation is WM_OPTIONS.
+
+ Keywords
+ label-size=[True] supports int32/int64
+ compile-option[=RpathOpt]
+ mplib[=USERMPI]
+ """
+
+ #: Map spack compiler names to OpenFOAM compiler names
+ # By default, simply capitalize the first letter
+ compiler_mapping = {'intel': 'icc'}
+
+ def __init__(self, spec, **kwargs):
+ # Some user settings, to be adjusted manually or via variants
+ self.compiler = None # <- %compiler
+ self.arch_option = '64' # (32/64-bit on x86_64)
+ self.label_size = None # <- +int64
+ self.precision_option = 'DP' # <- +float32
+ self.compile_option = kwargs.get('compile-option', 'RpathOpt')
+ self.arch = None
+ self.options = None
+ self.rule = None
+ self.mplib = kwargs.get('mplib', 'USERMPI')
+
+ # Normally support WM_LABEL_OPTION, but not yet for foam-extend
+ if '+int64' in spec:
+ self.label_size = '64'
+ elif kwargs.get('label-size', True):
+ self.label_size = '32'
+
+ if '+float32' in spec:
+ self.precision_option = 'SP'
+
+ # spec.architecture.platform is like `uname -s`, but lower-case
+ platform = spec.architecture.platform
+
+ # spec.architecture.target is like `uname -m`
+ target = spec.architecture.target
+
+ if platform == 'linux':
+ if target == 'i686':
+ self.arch_option = '32' # Force consistency
+ elif target == 'x86_64':
+ if self.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.arch_option == '64':
+ platform += '64'
+ # ... and others?
+
+ self.arch = platform
+
+ # 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 = spec.compiler.name
+
+ if comp in self.compiler_mapping:
+ comp = self.compiler_mapping[comp]
+ comp = comp.capitalize()
+
+ if '+knl' in spec:
+ comp += 'KNL'
+ self.compiler = comp
+ self.rule = self.arch + self.compiler
+
+ # Build WM_OPTIONS
+ # ----
+ # WM_LABEL_OPTION=Int$WM_LABEL_SIZE
+ # WM_OPTIONS=$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_LABEL_OPTION$WM_COMPILE_OPTION
+ # or
+ # WM_OPTIONS=$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_COMPILE_OPTION
+ # ----
+ self.options = ''.join([
+ self.rule,
+ self.precision_option,
+ ('Int' + self.label_size if self.label_size else ''),
+ self.compile_option])
+
+ def __str__(self):
+ return self.options
+
+ def __repr__(self):
+ return str(self)
+
+ def foam_dict(self):
+ """Returns a dictionary for OpenFOAM prefs, bashrc, cshrc."""
+ return dict([
+ ('WM_COMPILER', self.compiler),
+ ('WM_ARCH_OPTION', self.arch_option),
+ ('WM_LABEL_SIZE', self.label_size),
+ ('WM_PRECISION_OPTION', self.precision_option),
+ ('WM_COMPILE_OPTION', self.compile_option),
+ ('WM_MPLIB', self.mplib),
+ ])
+
+ def _rule_directory(self, projdir=None, general=False):
+ """The wmake/rules/ compiler directory"""
+ if general:
+ relative = os.path.join('wmake', 'rules', 'General')
+ else:
+ relative = os.path.join('wmake', 'rules', self.rule)
+ if projdir:
+ return os.path.join(projdir, relative)
+ else:
+ return relative
+
+ def has_rule(self, projdir):
+ """Verify that a wmake/rules/ compiler rule exists in the project
+ directory.
+ """
+ # Insist on a wmake rule for this architecture/compiler combination
+ rule_dir = self._rule_directory(projdir)
+
+ if not os.path.isdir(rule_dir):
+ raise InstallError(
+ 'No wmake rule for {0}'.format(self.rule))
+ if not re.match(r'.+Opt$', self.compile_option):
+ raise InstallError(
+ "WM_COMPILE_OPTION={0} is not type '*Opt'"
+ .format(self.compile_option))
+ return True
+
+ def create_rules(self, projdir, foam_pkg):
+ """ Create cRpathOpt,c++RpathOpt and mplibUSER,mplibUSERMPI
+ rules in the specified project directory.
+ The compiler rules are based on the respective cOpt,c++Opt rules
+ but with additional rpath information for the OpenFOAM libraries.
+
+ The rpath rules allow wmake to use spack information with minimal
+ modification to OpenFOAM.
+ The rpath is used for the installed libpath (continue to use
+ LD_LIBRARY_PATH for values during the build).
+ """
+ # Note: the 'c' rules normally don't need rpath, since they are just
+ # used for statically linked wmake utilities, but left in anyhow.
+
+ # rpath for installed OpenFOAM libraries
+ rpath = '{0}{1}'.format(
+ foam_pkg.compiler.cxx_rpath_arg,
+ join_path(foam_pkg.projectdir, foam_pkg.archlib))
+
+ user_mpi = mplib_content(foam_pkg.spec)
+ rule_dir = self._rule_directory(projdir)
+
+ with working_dir(rule_dir):
+ # Compiler: copy existing cOpt,c++Opt and modify '*DBUG' value
+ for lang in ['c', 'c++']:
+ src = '{0}Opt'.format(lang)
+ dst = '{0}{1}'.format(lang, self.compile_option)
+ with open(src, 'r') as infile:
+ with open(dst, 'w') as outfile:
+ for line in infile:
+ line = line.rstrip()
+ outfile.write(line)
+ if re.match(r'^\S+DBUG\s*=', line):
+ outfile.write(' ')
+ outfile.write(rpath)
+ outfile.write('\n')
+
+ # MPI rules
+ 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(**user_mpi))
+
# -----------------------------------------------------------------------------
diff --git a/var/spack/repos/builtin/packages/openfoam-org/assets/bin/foamEtcFile b/var/spack/repos/builtin/packages/openfoam-org/assets/bin/foamEtcFile
new file mode 100755
index 0000000000..294cc26505
--- /dev/null
+++ b/var/spack/repos/builtin/packages/openfoam-org/assets/bin/foamEtcFile
@@ -0,0 +1,417 @@
+#!/bin/sh
+#------------------------------------------------------------------------------
+# ========= |
+# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+# \\ / O peration |
+# \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
+# \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
+#-------------------------------------------------------------------------------
+# License
+# This file is part of OpenFOAM.
+#
+# OpenFOAM is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# OpenFOAM 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 GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
+#
+# Script
+# foamEtcFile
+#
+# Description
+# Locate user/group/other files with semantics similar to the
+# ~OpenFOAM/fileName expansion.
+#
+# The -mode option can be used to allow chaining from
+# personal settings to site-wide settings.
+#
+# For example, within the user ~/.OpenFOAM/<VER>/prefs.sh:
+# \code
+# 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 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: foamEtcFile [OPTION] fileName
+ foamEtcFile [OPTION] [-list|-list-test] [fileName]
+
+options:
+ -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/other file with semantics similar to the
+~OpenFOAM/fileName expansion.
+
+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.
+ 1 for miscellaneous errors.
+ 2 when the file is not found.
+
+USAGE
+ 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
+}
+
+#-------------------------------------------------------------------------------
+binDir="${0%/*}" # The bin dir
+projectDir="${binDir%/bin}" # The project dir
+prefixDir="${projectDir%/*}" # The prefix dir (same as $WM_PROJECT_INST_DIR)
+
+# Could not resolve projectDir, prefixDir? (eg, called as ./bin/foamEtcFile)
+if [ "$prefixDir" = "$projectDir" ]
+then
+ binDir="$(cd $binDir && pwd -L)"
+ projectDir="${binDir%/bin}"
+ prefixDir="${projectDir%/*}"
+fi
+projectDirName="${projectDir##*/}" # The project directory name
+
+projectVersion="$WM_PROJECT_VERSION" # Empty? - will be treated later
+userDir="$HOME/.OpenFOAM" # Hard-coded as per foamVersion.H
+
+#-------------------------------------------------------------------------------
+
+# Guess project version or simply get the stem part of the projectDirName.
+# Handle standard and debian naming conventions.
+#
+# - projectVersion: update unless already set
+#
+# Helper variables:
+# - dirBase (for reassembling name) == projectDirName without the version
+# - versionNum (debian packaging)
+unset dirBase versionNum
+guessVersion()
+{
+ local 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
+ ;;
+
+ (*)
+ 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}"
+}
+
+
+optMode=ugo # Default mode is always 'ugo'
+unset optAll optList optShell optVersion
+
+# Parse options
+while [ "$#" -gt 0 ]
+do
+ case "$1" in
+ -h | -help)
+ usage
+ ;;
+ -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)
+ optMode="$2"
+ shift
+ # Sanity check. Handles missing argument too.
+ case "$optMode" in
+ ([ugo]*)
+ ;;
+ (*)
+ die "invalid mode '$optMode'"
+ ;;
+ esac
+ ;;
+ -p | -prefix)
+ [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+ prefixDir="${2%/}"
+ shift
+ ;;
+ -q | -quiet)
+ optQuiet=true
+ ;;
+ -s | -silent)
+ optSilent=true
+ ;;
+ -v | -version)
+ [ "$#" -ge 2 ] || die "'$1' option requires an argument"
+ optVersion="$2"
+ shift
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -*)
+ die "unknown option: '$1'"
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+
+#-------------------------------------------------------------------------------
+
+if [ -n "$optVersion" ]
+then
+ setVersion $optVersion
+elif [ -z "$projectVersion" ]
+then
+ guessVersion
+fi
+
+# Updates:
+# - projectDir for changes via -prefix or -version
+# - groupDir for changes via -prefix
+projectDir="$prefixDir/$projectDirName"
+groupDir="${WM_PROJECT_SITE:-$prefixDir/site}"
+
+
+# Debugging:
+# echo "Installed locations:" 1>&2
+# for i in projectDir prefixDir projectDirName projectVersion
+# do
+# eval echo "$i=\$$i" 1>&2
+# done
+
+
+# Save the essential bits of information
+# silently remove leading ~OpenFOAM/ (used in Foam::findEtcFile)
+nArgs=$#
+fileName="${1#~OpenFOAM/}"
+
+# Define the various places to be searched:
+unset dirList
+case "$optMode" in (*u*) # (U)ser
+ dirList="$dirList $userDir/$projectVersion $userDir"
+ ;;
+esac
+
+case "$optMode" in (*g*) # (G)roup == site
+ dirList="$dirList $groupDir/$projectVersion $groupDir"
+ ;;
+esac
+
+case "$optMode" in (*o*) # (O)ther == shipped
+ dirList="$dirList $projectDir/etc"
+ ;;
+esac
+set -- $dirList
+
+
+#
+# The main routine
+#
+
+exitCode=0
+if [ -n "$optList" ]
+then
+
+ # 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
+
+ # 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
+ resolved="$dir/$fileName"
+ if [ -f "$resolved" ]
+ then
+ 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 ] || die "One filename expected - $nArgs provided"
+
+ exitCode=2 # Fallback to a general error (file not found)
+
+ for dir
+ do
+ if [ -f "$dir/$fileName" ]
+ then
+ exitCode=0
+ [ -n "$optQuiet" ] && break
+
+ case "$optShell" in
+ (*verbose)
+ echo "Using: $dir/$fileName" 1>&2
+ ;;
+ esac
+
+ case "$optShell" in
+ csh*)
+ echo "source $dir/$fileName"
+ break
+ ;;
+ sh*)
+ echo ". $dir/$fileName"
+ break
+ ;;
+ *)
+ echo "$dir/$fileName"
+ [ -n "$optAll" ] || break
+ ;;
+ esac
+ fi
+ done
+
+fi
+
+exit $exitCode
+
+#------------------------------------------------------------------------------
diff --git a/var/spack/repos/builtin/packages/openfoam-org/openfoam-site.patch b/var/spack/repos/builtin/packages/openfoam-org/openfoam-site-41.patch
index 6631025788..d988c2f9b8 100644
--- a/var/spack/repos/builtin/packages/openfoam-org/openfoam-site.patch
+++ b/var/spack/repos/builtin/packages/openfoam-org/openfoam-site-41.patch
@@ -6,7 +6,7 @@ diff -uw OpenFOAM-v1612+.orig/etc/config.sh/settings OpenFOAM-v1612+/etc/config.
# 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
++export FOAM_JOB_DIR=$HOME/.OpenFOAM/jobControl #SPACK: non-central location
# wmake configuration
export WM_DIR=$WM_PROJECT_DIR/wmake
@@ -15,7 +15,7 @@ diff -uw OpenFOAM-v1612+.orig/etc/config.sh/settings OpenFOAM-v1612+/etc/config.
# Site-specific directory
-siteDir="${WM_PROJECT_SITE:-$WM_PROJECT_INST_DIR/site}"
-+siteDir="${WM_PROJECT_SITE:-$WM_PROJECT/site}" #SPACK: not in parent directory
++siteDir="${WM_PROJECT_SITE:-$WM_PROJECT_DIR/site}" #SPACK: not in parent directory
# Shared site executables/libraries
# Similar naming convention as ~OpenFOAM expansion
@@ -27,7 +27,7 @@ diff -uw OpenFOAM-v1612+.orig/etc/config.csh/settings OpenFOAM-v1612+/etc/config
# 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
++setenv FOAM_JOB_DIR=$HOME/.OpenFOAM/jobControl #SPACK: non-central location
# wmake configuration
setenv WM_DIR $WM_PROJECT_DIR/wmake
diff --git a/var/spack/repos/builtin/packages/openfoam-org/package.py b/var/spack/repos/builtin/packages/openfoam-org/package.py
index 53be5f6337..02c27a0db5 100644
--- a/var/spack/repos/builtin/packages/openfoam-org/package.py
+++ b/var/spack/repos/builtin/packages/openfoam-org/package.py
@@ -44,22 +44,23 @@
# 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 handling: WM_MPLIB=SYSTEMMPI and use spack to populate prefs.sh for it.
+# Provide wmake rules for special purpose 'USER' and 'USERMPI'
# mpi implementations, in case these are required.
#
+# Known issues
+# - Combining +zoltan with +int64 has not been tested, but probably won't work.
+# - Combining +mgridgen with +int64 or +float32 probably won't work.
+#
##############################################################################
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 *
@@ -78,19 +79,15 @@ class OpenfoamOrg(Package):
version('4.1', '318a446c4ae6366c7296b61184acd37c',
url=baseurl + '/OpenFOAM-4.x/archive/version-4.1.tar.gz')
+ version('dev', git='https://github.com/OpenFOAM/OpenFOAM-dev.git')
variant('int64', default=False,
- description='Compile with 64-bit labels')
+ description='Compile with 64-bit label')
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')
@@ -98,31 +95,26 @@ class OpenfoamOrg(Package):
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')
+ depends_on('scotch~metis+mpi~int64', when='~int64')
+ depends_on('scotch~metis+mpi+int64', when='+int64')
- # General patches
- patch('openfoam-site.patch')
+ # General patches - foamEtcFile as per openfoam.com (robuster)
+ common = ['spack-Allwmake', 'README-spack']
+ assets = ['bin/foamEtcFile']
# 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
+ patch('openfoam-etc-41.patch', when='@4.1')
+ patch('openfoam-site-41.patch', when='@4.1')
+
+ # Some user config settings
+ config = {
+ 'mplib': 'SYSTEMMPI', # Use system mpi for spack
+ # Add links into bin/, lib/ (eg, for other applications)
+ 'link': False
}
- # The system description is frequently needed
- foam_sys = {
- 'WM_ARCH': None,
- 'WM_COMPILER': None,
- 'WM_OPTIONS': None,
- }
+ # The openfoam architecture, compiler information etc
+ _foam_arch = None
# Content for etc/prefs.{csh,sh}
etc_prefs = {}
@@ -130,236 +122,111 @@ class OpenfoamOrg(Package):
# 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'
+ phases = ['configure', 'build', 'install']
+ build_script = './spack-Allwmake' # <- Added by patch() method.
- # Add symlinks into bin/, lib/ (eg, for other applications)
- extra_symlinks = False
+ #
+ # - End of definitions / setup -
+ #
def setup_environment(self, spack_env, run_env):
+ run_env.set('FOAM_PROJECT_DIR', self.projectdir)
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)
+ for d in ['wmake', self.archbin]: # bin already added automatically
+ run_env.prepend_path('PATH', join_path(self.projectdir, d))
+ run_env.set('MPI_BUFFER_SIZE', "20000000")
+
+ def setup_dependent_environment(self, spack_env, run_env, dependent_spec):
+ """Provide location of the OpenFOAM project.
+ This is identical to the WM_PROJECT_DIR value, but we avoid that
+ variable since it would mask the normal OpenFOAM cleanup of
+ previous versions.
+ """
+ spack_env.set('FOAM_PROJECT_DIR', self.projectdir)
@property
def projectdir(self):
"""Absolute location of project directory: WM_PROJECT_DIR/"""
- return join_path(self.prefix, self._canonical) # <- prefix/canonical
+ return self.prefix # <- install directly under prefix
@property
- def etc(self):
- """Absolute location of the OpenFOAM etc/ directory"""
- return join_path(self.projectdir, 'etc')
+ def foam_arch(self):
+ if not self._foam_arch:
+ self._foam_arch = OpenfoamArch(self.spec, **self.config)
+ return self._foam_arch
@property
def archbin(self):
"""Relative location of architecture-specific executables"""
- return join_path('platforms', self.wm_options, 'bin')
+ return join_path('platforms', self.foam_arch, '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']
+ return join_path('platforms', self.foam_arch, 'lib')
- def patch(self):
- """Adjust OpenFOAM build for spack. Where needed, apply filter as an
- alternative to normal patching.
+ def rename_source(self):
+ """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.
"""
- 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!
+ # Note that this particular OpenFOAM 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
+ target = 'OpenFOAM-{0}'.format(self.version)
+ # Could also grep through etc/bashrc for WM_PROJECT_VERSION
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))
+ def patch(self):
+ """Adjust OpenFOAM build for spack.
+ Where needed, apply filter as an alternative to normal patching."""
+ self.rename_source()
+ add_extra_files(self, self.common, self.assets)
+
# 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 = {
+ # Filtering: bashrc,cshrc (using a patch is less flexible)
+ edits = {
'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,
+ edits,
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)
-
+ # Filtering bashrc, cshrc
+ edits = {}
+ edits.update(self.foam_arch.foam_dict())
rewrite_environ_files( # Adjust etc/bashrc and etc/cshrc
- wm_setting,
+ edits,
posix=join_path('etc', 'bashrc'),
cshell=join_path('etc', 'cshrc'))
# MPI content, with absolute paths
- content = mplib_content(spec)
+ user_mpi = 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'],
+ r'MPI_ARCH_FLAGS': '"%s"' % user_mpi['FLAGS'],
+ r'MPI_ARCH_INC': '"%s"' % user_mpi['PINC'],
+ r'MPI_ARCH_LIBS': '"%s"' % user_mpi['PLIBS'],
}
# Content for etc/config.{csh,sh}/ files
@@ -368,6 +235,7 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
'scotch': {},
'metis': {},
'paraview': [],
+ 'gperftools': [], # Currently unused
}
if True:
@@ -392,45 +260,30 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
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.
+ Only build if the compiler is known to be supported.
"""
- self.set_openfoam() # Force proper population of foam_cfg/foam_sys
+ self.foam_arch.has_rule(self.stage.source_path)
+ self.foam_arch.create_rules(self.stage.source_path, self)
+
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())
+ os.environ['WM_NCOMPPROCS'] = str(make_jobs)
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
-
+ """Install under the projectdir"""
mkdirp(self.projectdir)
projdir = os.path.basename(self.projectdir)
- wm_setting = {
+ # Filtering: bashrc, cshrc
+ edits = {
'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-.*')
@@ -438,20 +291,23 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
ignored = re.compile(r'^(Allwmake|spack-).*')
files = [
- f for f in glob.glob("*") if isfile(f) and not ignored.search(f)
+ f for f in glob.glob("*")
+ if os.path.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']
+ # Having wmake and ~source is actually somewhat pointless...
+ # Install 'etc' before 'bin' (for symlinks)
+ dirs = ['etc', 'bin', 'wmake']
if '+source' in spec:
dirs.extend(['applications', 'src', 'tutorials'])
for d in dirs:
install_tree(
d,
- join_path(self.projectdir, d))
+ join_path(self.projectdir, d),
+ symlinks=True)
dirs = ['platforms']
if '+source' in spec:
@@ -463,29 +319,37 @@ echo WM_PROJECT_DIR = $WM_PROJECT_DIR
install_tree(
d,
join_path(self.projectdir, d),
- ignore=shutil.ignore_patterns(*ignored))
+ ignore=shutil.ignore_patterns(*ignored),
+ symlinks=True)
+ etc_dir = join_path(self.projectdir, 'etc')
rewrite_environ_files( # Adjust etc/bashrc and etc/cshrc
- wm_setting,
- posix=join_path(self.etc, 'bashrc'),
- cshell=join_path(self.etc, 'cshrc'))
+ edits,
+ posix=join_path(etc_dir, 'bashrc'),
+ cshell=join_path(etc_dir, 'cshrc'))
self.install_links()
def install_links(self):
"""Add symlinks into bin/, lib/ (eg, for other applications)"""
- if not self.extra_symlinks:
+ # Make build log visible - it contains OpenFOAM-specific information
+ with working_dir(self.projectdir):
+ os.symlink(
+ join_path('.spack', 'build.out'),
+ join_path('log.' + str(self.foam_arch)))
+
+ if not self.config['link']:
return
# ln -s platforms/linux64GccXXX/lib lib
with working_dir(self.projectdir):
- if isdir(self.archlib):
+ if os.path.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)
+ if os.path.isfile(f)
]:
os.symlink(f, os.path.basename(f))