diff --git a/Allwmake b/Allwmake
index c6e1ca4f8c..77b5bc703a 100755
--- a/Allwmake
+++ b/Allwmake
@@ -86,8 +86,8 @@ echo " ${WM_PROJECT_DIR##*/}"
echo " $WM_COMPILER ${WM_COMPILER_TYPE:-system} compiler"
echo " ${WM_OPTIONS}, with ${WM_MPLIB} ${FOAM_MPI}"
echo
-echo " api = $(foamEtcFile -show-api 2>/dev/null)"
-echo " patch = $(foamEtcFile -show-patch 2>/dev/null)"
+echo " api = $(etc/openfoam -show-api 2>/dev/null)"
+echo " patch = $(etc/openfoam -show-patch 2>/dev/null)"
echo " bin = $(_foamCountDirEntries $FOAM_APPBIN) entries"
echo " lib = $(_foamCountDirEntries $FOAM_LIBBIN) entries"
echo
diff --git a/META-INFO/api-info b/META-INFO/api-info
index 916aebe43e..0092fb8952 100644
--- a/META-INFO/api-info
+++ b/META-INFO/api-info
@@ -1,2 +1,2 @@
api=1912
-patch=200403
+patch=200417
diff --git a/bin/foamEtcFile b/bin/foamEtcFile
index c9a385abf0..fc8cc57bf5 100755
--- a/bin/foamEtcFile
+++ b/bin/foamEtcFile
@@ -7,14 +7,13 @@
# \\/ M anipulation |
#------------------------------------------------------------------------------
# Copyright (C) 2011-2016 OpenFOAM Foundation
-# Copyright (C) 2017-2018 OpenCFD Ltd.
+# Copyright (C) 2017-2020 OpenCFD Ltd.
#------------------------------------------------------------------------------
# License
-# This file is part of OpenFOAM, licensed under GNU General Public License
-# .
+# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
#
# Script
-# foamEtcFile
+# bin/foamEtcFile
#
# Description
# Locate user/group/other file as per '#includeEtc'.
@@ -67,8 +66,8 @@ options:
-config Add config directory prefix for shell type:
with -csh* for a config.csh/ prefix
with -sh* for a config.sh/ prefix
- -show-api Print api value from wmake/rules, or meta-info and exit
- -show-patch Print patch value from meta-info and exit
+ -show-api Print META-INFO api value and exit
+ -show-patch Print META-INFO patch value and exit
-with-api=NUM Specify alternative api value to search with
-quiet (-q) Suppress all normal output
-silent (-s) Suppress stderr, except -csh-verbose, -sh-verbose output
@@ -129,54 +128,17 @@ fi
#-------------------------------------------------------------------------------
-# The API locations. See wmake/wmakeBuildInfo
-rulesFile="$projectDir/wmake/rules/General/general"
-metaInfoDir="$projectDir/META-INFO"
-
-# Get api from rules/General/general
-#
-# Failure modes:
-# - No api information (can't find file etc).
-# -> Fatal for building, but could be OK for a stripped down version
-#
-# Fallback. Get from api-info
-#
-getApi()
+# Get a value from META-INFO/api-info
+# $1 : keyword
+getApiInfo()
{
- local value
-
- value="$(sed -ne '/^ *#/!{ /WM_VERSION.*OPENFOAM=/{ s@^.*OPENFOAM= *\([0-9][0-9]*\).*@\1@p; q }}' $rulesFile 2>/dev/null)"
- if [ -z "$value" ] && [ -f "$metaInfoDir/api-info" ]
- then
- # Fallback. Get from api-info
- value="$(sed -ne 's@^ *api *= *\([0-9][0-9]*\).*@\1@p' $metaInfoDir/api-info 2>/dev/null)"
- fi
-
- if [ -n "$value" ]
- then
- echo "$value"
- else
- return 1
- fi
-}
-
-
-# Get patch from meta-info / api-info
-#
-# Failure modes:
-# - No patch information (can't find file etc).
-#
-getPatchLevel()
-{
- local value
-
- # Fallback. Get from api-info
- value="$(sed -ne 's@^ *patch *= *\([0-9][0-9]*\).*@\1@p' $metaInfoDir/api-info 2>/dev/null)"
+ value="$(sed -ne 's@^'"$1"' *= *\([0-9][0-9]*\).*@\1@p' "$projectDir"/META-INFO/api-info 2>/dev/null)"
if [ -n "$value" ]
then
echo "$value"
else
+ echo "Could not determine OPENFOAM '$1' value" 1>&2
return 1
fi
}
@@ -193,14 +155,12 @@ do
-h | -help*)
printHelp
;;
- -show-api)
- # Show API and exit
- getApi
+ -show-api) # Show API and exit
+ getApiInfo api
exit $?
;;
- -show-patch)
- # Show patch level and exit
- getPatchLevel
+ -show-patch) # Show patch level and exit
+ getApiInfo patch
exit $?
;;
-with-api=*)
@@ -276,7 +236,7 @@ done
#-------------------------------------------------------------------------------
# Establish the API value
-[ -n "$projectApi" ] || projectApi=$(getApi)
+[ -n "$projectApi" ] || projectApi=$(getApiInfo api)
# Split arguments into filename (for searching) and trailing bits for shell eval
# Silently remove leading ~OpenFOAM/ (as per Foam::findEtcFile)
diff --git a/bin/tools/create-mpi-config b/bin/tools/create-mpi-config
new file mode 100755
index 0000000000..561923f59d
--- /dev/null
+++ b/bin/tools/create-mpi-config
@@ -0,0 +1,272 @@
+#!/bin/sh
+#------------------------------------------------------------------------------
+# ========= |
+# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+# \\ / O peration |
+# \\ / A nd | www.openfoam.com
+# \\/ M anipulation |
+#------------------------------------------------------------------------------
+# Copyright (C) 2020 OpenCFD Ltd.
+#------------------------------------------------------------------------------
+# License
+# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
+#
+# Script
+# bin/tools/create-mpi-config
+#
+# Description
+# Define hard-coded packaging settings for MPI flavours,
+# primarily for system openmpi.
+# This eliminates a runtime dependency on mpicc, for example.
+#
+# Instead of querying/parsing 'mpicc --showme:link' each time,
+# it is done once during packaging.
+#
+# Environment
+# FOAM_MPI, MPI_ARCH_PATH, DEB_TARGET_MULTIARCH
+#
+# Possible Dependencies
+# - dpkg-architecture
+# - mpicc
+#
+# Notes
+# Run from top-level directory when creating config files
+#
+#------------------------------------------------------------------------------
+printHelp() {
+ exec 1>&2
+ while [ "$#" -ge 1 ]; do echo "$1"; shift; done
+ cat<&2
+ echo
+ echo "Error encountered:"
+ while [ "$#" -ge 1 ]; do echo " $1"; shift; done
+ echo
+ echo "See '${0##*/} -help' for usage"
+ echo
+ exit 1
+}
+
+
+#------------------------------------------------------------------------------
+# Options
+unset optDryRun
+useMpicc=true
+
+# Get installation directory for system openmpi
+# - from "mpicc --showme:link"
+# - manual fallback
+#
+# The mpicc content looks like this:
+# ----
+# -pthread -L/usr/lib64/mpi/gcc/openmpi/lib64 -lmpi
+# ----
+
+query_system_openmpi()
+{
+ unset arch_path
+
+ if [ "$useMpicc" = true ]
+ then
+ arch_path=$(mpicc --showme:link 2>/dev/null | sed -e 's#^.*-L\([^ ]*\).*#\1#')
+ arch_path="${arch_path%/*}"
+
+ if [ -n "$arch_path" ]
+ then
+ echo "$arch_path"
+ return 0 # Clean exit
+ fi
+
+ echo "No mpicc found. Attempt manually" 1>&2
+ fi
+
+
+ # Manual discovery
+ if [ -z "$DEB_TARGET_MULTIARCH" ]
+ then
+ DEB_TARGET_MULTIARCH=$(dpkg-architecture -qDEB_TARGET_MULTIARCH 2>/dev/null || true)
+ fi
+
+ # Include is under /usr/lib... (eg, debian, openSUSE)
+ for testdir in \
+ /usr/lib/"${DEB_TARGET_MULTIARCH:+${DEB_TARGET_MULTIARCH}/}"openmpi/include \
+ /usr/lib64/mpi/gcc/openmpi/include \
+ ;
+ do
+ if [ -e "$testdir/mpi.h" ]
+ then
+ echo "${testdir%/*}"
+ return 0 # Clean exit
+ fi
+ done
+
+ # Include is under /usr/include (eg, RedHat)
+ for testdir in \
+ /usr/include/openmpi-"$(uname -m)" \
+ /usr/include/openmpi \
+ ;
+ do
+ if [ -e "$testdir/mpi.h" ]
+ then
+ echo "/usr"
+ return 0 # Clean exit
+ fi
+ done
+
+ # Failed (should not happen)
+ # - report '/usr', but with error code 2
+ echo "/usr"
+ return 2
+}
+
+
+# Generate etc/config.{csh,sh}/MPI-TYPE files
+# based on the values for FOAM_MPI and MPI_ARCH_PATH
+
+create_files()
+{
+ [ -n "$FOAM_MPI" ] || die "FOAM_MPI not set"
+
+ if [ -d "$MPI_ARCH_PATH" ]
+ then
+ echo "Define $FOAM_MPI with $MPI_ARCH_PATH" 1>&2
+
+ case "$FOAM_MPI" in
+ (openmpi-system)
+ configDir="etc/config.sh"
+ if [ "$optDryRun" = true ]
+ then
+ cat << CONTENT 1>&2
+dry-run: $configDir/$FOAM_MPI
+#
+# Packaging configured value for $FOAM_MPI
+export MPI_ARCH_PATH="$MPI_ARCH_PATH"
+
+CONTENT
+ elif [ -d "$configDir" ]
+ then
+ echo "Write $configDir/$FOAM_MPI" 1>&2
+ cat << CONTENT > "$configDir/$FOAM_MPI"
+# $configDir/$FOAM_MPI
+#
+# Packaging configured value for $FOAM_MPI
+
+export MPI_ARCH_PATH="$MPI_ARCH_PATH"
+#----
+CONTENT
+ else
+ echo "Cannot write $configDir/$FOAM_MPI - no directory" 1>&2
+ fi
+
+ configDir="etc/config.csh"
+ if [ "$optDryRun" = true ]
+ then
+ cat << CONTENT 1>&2
+dry-run: $configDir/$FOAM_MPI
+#
+# Packaging configured value for $FOAM_MPI
+setenv MPI_ARCH_PATH "$MPI_ARCH_PATH"
+
+CONTENT
+ elif [ -d "$configDir" ]
+ then
+ echo "Write $configDir/$FOAM_MPI" 1>&2
+ cat << CONTENT > "$configDir/$FOAM_MPI"
+# $configDir/$FOAM_MPI
+#
+# Packaging configured value for $FOAM_MPI
+
+setenv MPI_ARCH_PATH "$MPI_ARCH_PATH"
+#----
+CONTENT
+ else
+ echo "Cannot write $configDir/$FOAM_MPI - no directory" 1>&2
+ fi
+ ;;
+ esac
+ else
+ echo "Warning: $FOAM_MPI with bad MPI_ARCH_PATH: $MPI_ARCH_PATH" 1>&2
+ # TBD - remove old/bad entries?
+ #
+ # for file in "etc/config.sh/$FOAM_MPI" "etc/config.csh/$FOAM_MPI"
+ # do
+ # [ -f "$file" ] && rm -f "$file"
+ # done
+ fi
+}
+
+
+#------------------------------------------------------------------------------
+
+# Parse options
+while [ "$#" -gt 0 ]
+do
+ case "$1" in
+ -h | -help* | --help*)
+ printHelp
+ ;;
+ '')
+ # Discard empty arguments
+ ;;
+
+ -dry-run)
+ optDryRun=true
+ ;;
+
+ -no-mpicc)
+ unset useMpicc
+ ;;
+
+ -query-openmpi | -query-system-openmpi)
+ query_system_openmpi
+ exit $?
+ ;;
+
+ -write-openmpi | -write-system-openmpi)
+ if MPI_ARCH_PATH=$(query_system_openmpi)
+ then
+ FOAM_MPI="openmpi-system"
+ create_files
+ else
+ die "Failed query for system openmpi"
+ fi
+ ;;
+
+ -write)
+ create_files
+ ;;
+
+ *)
+ echo "Ignore unknown option/argument: '$1'" 1>&2
+ ;;
+ esac
+ shift
+done
+
+exit 0 # A clean exit, if we get this far
+
+# -----------------------------------------------------------------------------
diff --git a/bin/tools/foamConfigurePaths b/bin/tools/foamConfigurePaths
index f2d400ab2f..12ea3d36bc 100755
--- a/bin/tools/foamConfigurePaths
+++ b/bin/tools/foamConfigurePaths
@@ -29,18 +29,49 @@
#
#------------------------------------------------------------------------------
printHelp() {
- cat<&2
+ echo "Configuring OpenFOAM ($projectDir)" 1>&2
else
die "Please run from the OpenFOAM top-level installation directory" \
"No etc/bashrc or META-INFO/ found"
@@ -172,18 +201,22 @@ _inlineSed()
local replacement="$3"
local msg="$4"
local cmd='/^[^#]/s@'"$regexp"'@'"$replacement"'@'
+ local localFile
[ -f "$file" ] || {
echo "Missing file: $file"
exit 2 # Fatal
}
+ # Local filename (for reporting)
+ localFile="$(echo "$file" | sed -e "s#^$projectDir/##")"
+
grep -q "$regexp" "$file" && sed -i -e "$cmd" "$file" || { \
- echo "Failed: ${msg:-replacement} in $file"
+ echo "Failed: ${msg:-replacement} in $localFile"
return 1
}
- [ -n "$msg" ] && echo " $msg ($file)"
+ [ -n "$msg" ] && echo " $msg ($localFile)"
return 0
}
@@ -209,7 +242,7 @@ replace()
"$file" \
"$key=.*" \
"$key=$val" \
- "Replaced $key setting by '$val'"
+ "Replaced $key by '$val'"
done
}
@@ -232,9 +265,9 @@ replaceCsh()
_inlineSed \
"$file" \
- "setenv *$key [^ #]*" \
+ "setenv [ ]*$key [^ #]*" \
"setenv $key $val" \
- "Replaced $key setenv by '$val'"
+ "Replaced $key by '$val'"
done
}
@@ -323,7 +356,13 @@ unset adjusted optMpi
while [ "$#" -gt 0 ]
do
case "$1" in
- -h | -help* | --help*)
+ -help-c*) # Compat help
+ printHelp -compat
+ ;;
+ -help-f*) # Full help
+ printHelp -full
+ ;;
+ -h | -help*) # Short help
printHelp
;;
'')
@@ -516,12 +555,12 @@ CONFIG_CSH
_inlineSed $(_foamEtc config.sh/mpi) \
"FOAM_MPI=$expected" \
"FOAM_MPI=$optMpi" \
- "Replaced 'FOAM_MPI=$expected' setting by 'FOAM_MPI=$optMpi'"
+ "Replaced 'FOAM_MPI=$expected' by 'FOAM_MPI=$optMpi'"
_inlineSed $(_foamEtc config.csh/mpi) \
"FOAM_MPI $expected" \
"FOAM_MPI $optMpi" \
- "Replaced 'FOAM_MPI $expected' setting by 'FOAM_MPI $optMpi'"
+ "Replaced 'FOAM_MPI $expected' by 'FOAM_MPI $optMpi'"
replaceEtc bashrc WM_MPLIB OPENMPI
replaceEtcCsh cshrc WM_MPLIB OPENMPI
@@ -711,11 +750,11 @@ CONFIG_CSH
shift
;;
- -vtk)
- # Replace vtk_version=...
+ -llvm)
+ # Replace mesa_llvm=...
optionValue=$(getOptionValue "$@")
- replaceEtc config.sh/vtk vtk_version "$optionValue"
- replaceEtc config.csh/vtk vtk_version "$optionValue"
+ replaceEtc config.sh/vtk mesa_llvm "$optionValue"
+ replaceEtc config.csh/vtk mesa_llvm "$optionValue"
adjusted=true
shift
;;
@@ -729,6 +768,42 @@ CONFIG_CSH
shift
;;
+ -vtk)
+ # Replace vtk_version=...
+ optionValue=$(getOptionValue "$@")
+ replaceEtc config.sh/vtk vtk_version "$optionValue"
+ replaceEtc config.csh/vtk vtk_version "$optionValue"
+ adjusted=true
+ shift
+ ;;
+
+ -llvm-path)
+ # Replace LLVM_ARCH_PATH=...
+ optionValue=$(getOptionValue "$@")
+ replaceEtc config.sh/vtk LLVM_ARCH_PATH \""$optionValue\""
+ replaceEtcCsh config.csh/vtk LLVM_ARCH_PATH \""$optionValue\""
+ adjusted=true
+ shift
+ ;;
+
+ -mesa-path)
+ # Replace MESA_ARCH_PATH...
+ optionValue=$(getOptionValue "$@")
+ replaceEtc config.sh/vtk MESA_ARCH_PATH \""$optionValue\""
+ replaceEtcCsh config.csh/vtk MESA_ARCH_PATH \""$optionValue\""
+ adjusted=true
+ shift
+ ;;
+
+ -vtk-path)
+ # Replace VTK_DIR...
+ optionValue=$(getOptionValue "$@")
+ replaceEtc config.sh/vtk VTK_DIR \""$optionValue\""
+ replaceEtcCsh config.csh/vtk VTK_DIR \""$optionValue\""
+ adjusted=true
+ shift
+ ;;
+
## Misc ##
diff --git a/bin/tools/openfoam.in b/bin/tools/openfoam.in
index 39b1fe76fb..d712512d0c 100644
--- a/bin/tools/openfoam.in
+++ b/bin/tools/openfoam.in
@@ -1,4 +1,5 @@
#!/bin/sh
+exec "@PROJECT_DIR@"/etc/openfoam "$@"
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
@@ -11,16 +12,8 @@
# License
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
#
-# Script
-# openfoam [options] [args]
-#
# Description
-# Forwarding to the OpenFOAM etc/openfoam bash session script.
+# Forwarding to OpenFOAM etc/openfoam bash session script.
+# Uses a hard-code directory path (eg, generated with autoconfig).
#
#------------------------------------------------------------------------------
-# Hard-coded directory path (eg, autoconfig)
-projectDir="@PROJECT_DIR@"
-
-exec "$projectDir"/etc/openfoam "$@"
-
-#------------------------------------------------------------------------------
diff --git a/doc/modules/README b/doc/modules/README
new file mode 100644
index 0000000000..0d4c403061
--- /dev/null
+++ b/doc/modules/README
@@ -0,0 +1 @@
+Modules-related documents when collated for an installation package.
diff --git a/etc/config.sh/gperftools b/etc/config.sh/gperftools
index 80ea4c175c..ea58dc58ea 100644
--- a/etc/config.sh/gperftools
+++ b/etc/config.sh/gperftools
@@ -9,12 +9,11 @@
# Copyright (C) 2016-2018 OpenCFD Ltd.
#------------------------------------------------------------------------------
# License
-# This file is part of OpenFOAM, licensed under GNU General Public License
-# .
+# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
#
# File
# etc/config.sh/gperftools
-# - sourced by OpenFOAM-*/etc/bashrc
+# Not normally sourced by OpenFOAM-*/etc/bashrc
#
# Description
# Setup file for GPERFTOOLS binaries/libraries.
diff --git a/etc/config.sh/setup b/etc/config.sh/setup
index 407aa4cce6..48287d4f06 100644
--- a/etc/config.sh/setup
+++ b/etc/config.sh/setup
@@ -147,7 +147,6 @@ _foamEtc -config settings
_foamEtc -config mpi
_foamEtc -config paraview -- "$@" # Pass through for evaluation
_foamEtc -config vtk
-_foamEtc -config gperftools
_foamEtc -config adios2
_foamEtc -config CGAL
_foamEtc -config scotch
diff --git a/etc/openfoam b/etc/openfoam
index 7bbe622fe3..6db02bc688 100755
--- a/etc/openfoam
+++ b/etc/openfoam
@@ -35,7 +35,7 @@
# etc/openfoam -DWM_COMPILER=Clang
#
#------------------------------------------------------------------------------
-# Auto-detect from location
+# Auto-detect from location. Do not call from within the etc/directory itself!
projectDir="$(\cd "$(dirname "${0%/*}")" && \pwd -L)"
#------------------------------------------------------------------------------
@@ -56,6 +56,7 @@ options:
-show-api | -version Print META-INFO api value and exit
-show-patch Print META-INFO patch value and exit
-show-prefix Print project directory and exit
+ -test-tutorial Forward arguments to tutorials/AutoTest
-verbose Set FOAM_VERBOSE=true (interactive only)
-help Print the usage
@@ -93,6 +94,7 @@ getApiInfo()
# No inheritance of FOAM_SETTINGS
unset FOAM_SETTINGS
unset _foamEtcDir _foamSettings _foamScriptCommand
+unset optTestTut
# Parse options
while [ "$#" -gt 0 ]
@@ -114,6 +116,10 @@ do
exit $?
;;
+ -test-tutorial) # Run tutorials/AutoTest
+ optTestTut=true
+ ;;
+
-c) # Shell command
_foamScriptCommand="$2"
[ -n "$_foamScriptCommand" ] || {
@@ -196,7 +202,7 @@ fi
unset interactive
-if [ "$#" -eq 0 ] && [ -z "$_foamScriptCommand" ]
+if [ "$#" -eq 0 ] && [ -z "$_foamScriptCommand" ] && [ -z "$optTestTut" ]
then
# Interactive shell, chain off via a file
interactive=true
@@ -263,6 +269,15 @@ then
fi
+if [ -n "$optTestTut" ]
+then
+
+ sourceBashrc
+ exec "$WM_PROJECT_DIR/tutorials/AutoTest" "$@"
+ exit $? # Safety
+fi
+
+
# An application or a shell script
# It may actually be a script with a '#!/project-path/bin/openfoam',
diff --git a/tutorials/AutoTest b/tutorials/AutoTest
new file mode 100755
index 0000000000..3a3f41b66a
--- /dev/null
+++ b/tutorials/AutoTest
@@ -0,0 +1,199 @@
+#!/bin/sh
+#------------------------------------------------------------------------------
+# ========= |
+# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+# \\ / O peration |
+# \\ / A nd | www.openfoam.com
+# \\/ M anipulation |
+#------------------------------------------------------------------------------
+# Copyright (C) 2020 OpenCFD Ltd.
+#------------------------------------------------------------------------------
+# License
+# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
+#
+# Script
+# tutorials/AutoTest dir [.. dirN]
+#
+# Description
+# Run foamRunTutorials with specified tutorial directories
+# Creates/destroys a temporary directory for each test.
+#
+# Environment
+# Requires an initialized OpenFOAM environment.
+#
+# Note
+# Potentially useful for debian autopkgtest
+#
+#------------------------------------------------------------------------------
+# Auto-detect from location
+#Unused# projectDir="$(\cd "$(dirname "${0%/*}")" && \pwd -L)"
+
+#------------------------------------------------------------------------------
+printHelp() {
+ cat<&2
+ echo
+ echo "Error encountered:"
+ while [ "$#" -ge 1 ]; do echo " $1"; shift; done
+ echo
+ echo "See '${0##*/} -help' for usage"
+ echo
+ exit 1
+}
+
+#------------------------------------------------------------------------------
+
+unset optDebian optVerbose
+optRunLimit=1
+
+# Parse options
+while [ "$#" -gt 0 ]
+do
+ case "$1" in
+ -h*)
+ printHelp
+ ;;
+
+ -1)
+ optRunLimit="${1#-}"
+ ;;
+
+ -full)
+ unset optRunLimit
+ ;;
+
+ -debian)
+ # Redirect stderr to stdout, if autopkgtest (tests/control)
+ # does NOT use "Restrictions: allow-stderr"
+ exec 2>&1
+ ;;
+
+ --)
+ break
+ ;;
+
+ -*)
+ die "unknown option $1"
+ ;;
+
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+
+#------------------------------------------------------------------------------
+# Basic sanity checks
+
+[ -n "$FOAM_TUTORIALS" ] || export FOAM_TUTORIALS="$WM_PROJECT_DIR"/tutorials
+
+[ -d "${WM_PROJECT_DIR:?}" ] || die "No OpenFOAM environment: $WM_PROJECT_DIR"
+[ -d "$FOAM_TUTORIALS" ] || die "No OpenFOAM tutorials : $FOAM_TUTORIALS"
+
+
+#------------------------------------------------------------------------------
+
+#
+# Modify case controlDicts to run only one time step
+#
+modifyCaseControlDict()
+{
+ for dict in $(find . -name "controlDict*" -type f)
+ do
+ cp -f "${dict}" "${dict}.orig"
+ sed \
+ -e 's/\(startFrom[ \t]*\)\([A-Za-z]*\);/\1 latestTime;/' \
+ -e 's/\(stopAt[ \t]*\)\([A-Za-z]*\);/\1 nextWrite;/' \
+ -e 's/\(writeControl[ \t]*\)\([A-Za-z]*\);/\1 timeStep;/' \
+ -e 's/\(writeInterval[ \t]*\)\([-.0-9A-Za-z]*\);/\1 '"$optRunLimit"';/' \
+ "${dict}.orig" > "${dict}"
+ done
+}
+
+
+#------------------------------------------------------------------------------
+
+nTests="$#"
+nPassed=0
+
+for testdir in "$@"
+do
+ testdir="${testdir#tutorials/}"
+ testdir="$(echo "$testdir" | sed -e 's@^//*@@; s@//*$@@;')"
+ suffix="$(echo "$testdir" | sed -e 's@//*@_@g')"
+
+ if [ -n "$testdir" ] && [ -d "$FOAM_TUTORIALS/$testdir" ]
+ then
+ (
+ echo "Run test: $testdir"
+ set -e
+
+ TESTDIR="$(mktemp --directory --suffix=".$suffix")"
+ trap 'rm -rf $TESTDIR' 0 INT QUIT ABRT PIPE TERM
+
+ cp -r "$FOAM_TUTORIALS/$testdir"/* "$TESTDIR"/
+ cd "$TESTDIR"
+
+ if [ -n "$optRunLimit" ]
+ then
+ set +e
+ modifyCaseControlDict
+ set -e
+ fi
+
+ nInput="$(ls | wc -l)"
+ foamRunTutorials
+ nOutput="$(ls | wc -l)"
+
+ if [ "$nInput" = 0 ]
+ then
+ echo "No input for $testdir" 1>&2
+ exit 1
+ elif [ "$nOutput" = "$nInput" ]
+ then
+ echo "Run failure for $testdir" 1>&2
+ exit 1
+ else
+ echo "run: OK"
+ fi
+ ) && nPassed=$((nPassed + 1))
+
+ else
+ echo "No tutorial: $testdir" 1>&2
+ fi
+done
+
+
+if [ "$nTests" = 0 ]
+then
+ die "No tests specified"
+elif [ "$nPassed" = "$nTests" ]
+then
+ echo "Passed all $nTests tests"
+else
+ echo "Passed $nPassed/$nTests tests" 1>&2
+ exit 1
+fi
+
+#------------------------------------------------------------------------------
diff --git a/tutorials/modules/README b/tutorials/modules/README
new file mode 100644
index 0000000000..00e3d74590
--- /dev/null
+++ b/tutorials/modules/README
@@ -0,0 +1 @@
+Modules-related tutorials when collated for an installation package.
diff --git a/wmake/scripts/sysFunctions b/wmake/scripts/sysFunctions
index 2330bf6f59..fd7aba9642 100644
--- a/wmake/scripts/sysFunctions
+++ b/wmake/scripts/sysFunctions
@@ -23,6 +23,7 @@
# findSystemInclude
# findLibrary
# findExtLib
+# versionCompare
#
# Internal variables used
# extLibraries
@@ -318,6 +319,74 @@ then
return 2
}
+
+
+ # Compare version tuples with syntax similar to POSIX shell,
+ # but respecting dot separators.
+ #
+ # arg1 OP arg2
+ # OP is one of -eq, -ne, -lt, -le, -gt, or -ge.
+ # Returns true for a successful comparison.
+ # Arg1 and arg2 normally comprise positive integers, but leading content
+ # before a '-' is stripped.
+ # Missing digits are treated as '0'.
+ #
+ # Eg,
+ # versionCompare "software-1.2.3" -gt 1.1 && echo True
+ #
+ # Ad hoc handling of "git" version as always newest.
+ # "git" -gt "1.2.3" : True
+ # "1.2.3" -lt "git" : True
+ versionCompare()
+ {
+ [ "$#" -eq 3 ] || {
+ echo "Compare needs 3 arguments (was given $#)" 1>&2
+ return 2
+ }
+
+ local arg1="${1#*-}" # Strip leading prefix-
+ local op="${2}"
+ local arg2="${3#*-}" # Strip leading prefix-
+ local result='' # Empty represents 'equal'
+
+ arg1="${arg1:-0}."
+ arg2="${arg2:-0}."
+
+ if [ "$arg1" = "$arg2" ]; then unset arg1 arg2 # Identical
+ elif [ "${arg1#git}" != "$arg1" ]; then result='more' # (git > arg2)
+ elif [ "${arg2#git}" != "$arg2" ]; then result='less' # (arg1 < git)
+ fi
+
+ while [ -z "$result" ] && [ -n "${arg1}${arg2}" ]
+ do
+ local digits1="${arg1%%.*}"
+ local digits2="${arg2%%.*}"
+
+ arg1="${arg1#*.}"
+ arg2="${arg2#*.}"
+
+ : "${digits1:=0}"
+ : "${digits2:=0}"
+
+ # Other handling of non-integer values?
+ if [ "$digits1" -lt "$digits2" ]; then result='less'
+ elif [ "$digits1" -gt "$digits2" ]; then result='more'
+ fi
+ done
+
+ case "$op" in
+ (-eq | eq) [ -z "$result" ] ;;
+ (-ne | ne) [ -n "$result" ] ;;
+ (-lt | lt) [ 'less' = "$result" ] ;;
+ (-gt | gt) [ 'more' = "$result" ] ;;
+ (-le | le) [ 'less' = "${result:-less}" ] ;;
+ (-ge | ge) [ 'more' = "${result:-more}" ] ;;
+ (*)
+ echo "Unknown operator: '$op'" 1>&2
+ return 2
+ ;;
+ esac
+ }
fi