summaryrefslogtreecommitdiff
path: root/var/spack/repos/builtin/packages/openfoam-org/package.py
diff options
context:
space:
mode:
Diffstat (limited to 'var/spack/repos/builtin/packages/openfoam-org/package.py')
-rw-r--r--var/spack/repos/builtin/packages/openfoam-org/package.py344
1 files changed, 104 insertions, 240 deletions
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))