diff --git a/bin/tools/install-dirs b/bin/tools/install-dirs
new file mode 100755
index 0000000000000000000000000000000000000000..a8c2ccb4bd97ea4e0bfd8973b7f7fea31b0b72b9
--- /dev/null
+++ b/bin/tools/install-dirs
@@ -0,0 +1,430 @@
+#!/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
+#     install-dirs
+#
+# Example usage
+#     install-dirs -prefix=/opt/openfoam/openfoamVER -core
+#
+# Description
+#     Simple installer to copy architecture-independent directories.
+#
+#------------------------------------------------------------------------------
+printHelp() {
+    cat<<USAGE
+
+Usage: ${0##*/} [OPTION]
+
+input options:
+  -source=SOURCE          Source directory
+                          [\$WM_PROJECT_DIR ${WM_PROJECT_DIR:-''}]
+  -platform=PLATFORM      OpenFOAM platform name [\$WM_OPTIONS ${WM_OPTIONS:-''}]
+  -foam-mpi=FOAM_MPI      OpenFOAM mpi name [\$FOAM_MPI ${FOAM_MPI:-''}]
+
+target options:
+  -prefix=PREFIX          Top-level installation directory in PREFIX ['']
+
+selections:
+  -[no-]common            [do not] install (bin, etc, META-INFO)
+  -[no-]devel             [do not] install (applications, src, wmake)
+  -[no-]doc               [do not] install (doc)
+  -[no-]tut               [do not] install (tutorials)
+  -no-app, -no-apps       do not install (applications)
+  -no-src                 do not install (src)
+  -no-wmake               do not install (wmake)
+
+bundled selections:
+  -core                   Select: -common -devel
+  -default                Select: -common -devel -doc -tut
+
+tuning options:
+  -collate                Collate modules (doc, tutorials)
+  -collate-doc            Collate modules (doc) into doc/modules
+  -collate-tut            Collate modules (tutorials) into tutorials/modules
+
+general options:
+  -dry-run, -n            Do not perform any operations
+  -force, -f              Ignored
+  -verbose, -v            Additional verbosity
+  -help                   Print the help and exit
+
+
+Simple installer to copy OpenFOAM non-binary directories.
+
+Example,
+    ${0##*/} -prefix=/opt/openfoamVER
+
+USAGE
+    exit 0  # A clean exit
+}
+
+unset optDryRun hadError
+# Report error and exit
+die()
+{
+    exec 1>&2
+    echo
+    echo "Error encountered:"
+    while [ "$#" -ge 1 ]; do echo "    $1"; shift; done
+    echo
+    echo "See '${0##*/} -help' for usage"
+    echo
+    exit 1
+}
+
+# Report error and exit
+warnOrDie()
+{
+    if [ -n "$optDryRun" ]
+    then
+        hadError=true
+        while [ "$#" -ge 1 ]; do echo "Error: $1" 1>&2; shift; done
+    else
+        die "$@"
+    fi
+}
+
+
+# Get the option's value (argument), or die on missing or empty value
+# $1 option=value
+getOptionValue()
+{
+    local value="${1#*=}"
+    # Remove any surrounding double quotes
+    value="${value%\"}"
+    value="${value#\"}"
+
+    [ -n "$value" ] || die "'${1%=}' option requires a value"
+    echo "$value"
+}
+
+# Test for '-no-' or '-without-' prefix. Return "false" or "true"
+# $1 option
+# [$2] truth value <true>
+getBoolOption()
+{
+    case "$1" in
+    (-no-* | -without-*) echo "false" ;;
+    (*) echo "${2:-true}" ;;
+    esac
+}
+
+
+#-------------------------------------------------------------------------------
+# Defaults from current OpenFOAM environment
+sourceDir="$WM_PROJECT_DIR"
+platform="$WM_OPTIONS"
+foam_mpi="$FOAM_MPI"
+
+unset install_common install_devel
+unset install_app install_src install_wmake
+unset install_doc optCollate_doc
+unset install_tut optCollate_tut
+unset optCollate
+
+unset prefix exec_prefix bindir libdir libdir_mpi optVerbose
+
+# Parse options
+while [ "$#" -gt 0 ]
+do
+    case "$1" in
+    -h | -help*)    printHelp ;;
+    -n | -dry-run)  optDryRun="(dry-run) " ;;
+    -v | -verbose)  optVerbose=true ;;
+    -f | -force)    echo "Ignored option: ${1%%=*}" 1>&2 ;;
+
+    # Inputs
+    -source=*)      sourceDir="$(getOptionValue "$1")" ;;
+    -platform=*)    echo "Ignored option: ${1%%=*}" 1>&2 ;;
+    -foam-mpi=*)    echo "Ignored option: ${1%%=*}" 1>&2 ;;
+
+    # Targets
+    -prefix=*)      prefix="$(getOptionValue "$1")" ;;
+    -exec-prefix=*) echo "Ignored option: ${1%%=*}" 1>&2 ;;
+
+    # Selections
+    -common | -no-common)   install_common="$(getBoolOption "$1")" ;;
+    -devel | -no-devel)     install_devel="$(getBoolOption "$1")" ;;
+    -doc | -no-doc)         install_doc="$(getBoolOption "$1")" ;;
+    -tut | -no-tut)         install_tut="$(getBoolOption "$1")" ;;
+    -no-app | -no-apps)     install_app="$(getBoolOption "$1")" ;;
+    -no-src)                install_src="$(getBoolOption "$1")" ;;
+    -no-wmake)              install_wmake="$(getBoolOption "$1")" ;;
+
+    -core)
+        install_common=true
+        install_devel=true
+        ;;
+
+    -default | -all)
+        [ "$1" = "-all" ] && echo "Compat: treat $1 like -default" 1>&2
+        install_common=true
+        install_devel=true
+        install_doc=true
+        install_tut=true
+        ;;
+
+    -collate | -no-collate)
+        optCollate="$(getBoolOption "$1")"
+        if [ "${optCollate:-false}" = false ]
+        then
+            unset optCollate optCollate_doc optCollate_tut
+        fi
+        ;;
+    -collate-doc)   optCollate_doc=true ;;
+    -collate-tut)   optCollate_tut=true ;;
+
+    (*)  die "Unknown option/argument: $1" ;;
+    esac
+    shift
+done
+
+#-------------------------------------------------------------------------------
+
+[ "${install_common:-false}" = false ] && unset install_common
+if [ "${install_devel:-false}" = false ]
+then
+    unset install_devel install_app install_src install_wmake
+fi
+
+if [ "${install_doc:-false}" = false ]
+then
+    unset install_doc
+elif [ "$optCollate_doc" = true ] || [ "$optCollate" = true ]
+then
+    install_doc=collate
+fi
+
+if [ "${install_tut:-false}" = false ]
+then
+    unset install_tut
+elif [ "$optCollate_tut" = true ] || [ "$optCollate" = true ]
+then
+    install_tut=collate
+fi
+
+
+# Input checks
+[ -d "$sourceDir" ] || warnOrDie "Invalid -source directory: $sourceDir"
+
+# Installation sanity check
+[ -n "$prefix" ] || warnOrDie "Must specify -prefix"
+
+if [ -n "$hadError" ]
+then
+    echo "Errors encounters in dry-run. Stopping" 1>&2
+    exit 1
+fi
+
+if [ -z "${install_common}${install_devel}${install_doc}${install_tut}" ]
+then
+    exec 1>&2
+    echo "Nothing specified to install"
+    echo
+    echo "See '${0##*/} -help' for usage"
+    echo
+    exit 0  # Treat as not an error
+fi
+
+# Report settings
+echo "Preparing install with the following parameters" 1>&2
+echo "source:" 1>&2
+echo "    directory   $sourceDir" 1>&2
+echo 1>&2
+echo "target" 1>&2
+echo "    prefix      ${prefix-[]}" 1>&2
+##echo "    binary      ${install_binary:-[disabled]}" 1>&2
+echo "    common      ${install_common:-[disabled]}" 1>&2
+echo -n "    devel       " 1>&2
+if [ -n "$install_devel" ]
+then
+    echo -n "true" 1>&2
+    [ "$install_app" = false ] && echo -n " [app=disabled]" 1>&2
+    [ "$install_src" = false ] && echo -n " [src=disabled]" 1>&2
+    [ "$install_wmake" = false ] && echo -n " [wmake=disabled]" 1>&2
+    echo 1>&2
+else
+    echo "[disabled]" 1>&2
+fi
+echo "    doc         ${install_doc:-[disabled]}" 1>&2
+echo "    tut         ${install_tut:-[disabled]}" 1>&2
+echo 1>&2
+
+
+#------------------------------------------------------------------------------
+# Proper umask
+umask 022
+
+# The commands
+copy_cmd="cp -a ${optVerbose:+-v}"
+mkdir_cmd="mkdir -p"
+
+if [ -n "$optDryRun" ]
+then
+    if [ -n "$optVerbose" ]
+    then
+        copy_cmd="echo cp -a"
+        mkdir_cmd="echo mkdir -p"
+    else
+        copy_cmd="true"
+        mkdir_cmd="true"
+    fi
+fi
+
+
+# Copy file or directory to <prefix>
+doCopy()
+{
+    $mkdir_cmd "$prefix" 2>/dev/null
+
+    for i in "$@"
+    do
+        if [ -e "$sourceDir/$i" ]
+        then
+            $copy_cmd "$sourceDir/$i" "$prefix"
+            nCopied="x$nCopied"
+        else
+            echo "Missing? $sourceDir/$i" 1>&2
+        fi
+    done
+    echo "${optDryRun}${#nCopied} items copied" 1>&2
+}
+
+
+
+# Collate (doc | tutorials)
+# Eg,
+#    modules/{NAME}/tutorials
+# => tutorials/modules/{NAME}
+collateModuleFiles()
+{
+    local subDir="$1"
+    local subTarget="$prefix/$subDir/modules"
+
+    if [ -d "$sourceDir/modules" ]
+    then
+    (
+        cd "$sourceDir/modules" || exit
+
+        $mkdir_cmd "$subTarget"
+
+        for i in $(find . -mindepth 2 -maxdepth 2 -name "$subDir" -type d)
+        do
+            $mkdir_cmd "$subTarget/${i%/*}"
+            $copy_cmd "$i"/*  "$subTarget/${i%/*}"
+        done
+    )
+    fi
+}
+
+
+#------------------------------------------------------------------------------
+
+# common
+# ----
+message="${optDryRun}Install common:"
+if [ -n "$install_common" ]
+then
+    echo "${message} bin etc META-INFO" 1>&2
+    doCopy bin etc META-INFO
+else
+    echo "${message} [disabled]" 1>&2
+fi
+# ----
+
+
+# develop (or source)
+# ----
+message="${optDryRun}Install devel:" 1>&2
+unset dirNames blockMessage
+if [ -n "$install_devel" ]
+then
+    if [ "$install_wmake" = false ]
+    then
+        blockMessage="$blockMessage [wmake=disabled]"
+    else
+        dirNames="$dirNames wmake"
+    fi
+    if [ "$install_src" = false ]
+    then
+        blockMessage="$blockMessage [src=disabled]"
+    else
+        dirNames="$dirNames src"
+    fi
+    if [ "$install_app" = false ]
+    then
+        blockMessage="$blockMessage [app=disabled]"
+    else
+        dirNames="$dirNames applications"
+    fi
+fi
+
+if [ -n "$dirNames" ]
+then
+    echo "${message}${dirNames}${blockMessage}" 1>&2
+    doCopy $dirNames  # Unquoted - uses word splitting
+else
+    echo "${message} [disabled]" 1>&2
+fi
+# ----
+
+
+# doc
+# ----
+message="${optDryRun}Install doc:" 1>&2
+if [ -n "$install_doc" ]
+then
+    echo "${message}" 1>&2
+    doCopy doc
+
+    if [ "$install_doc" = collate ]
+    then
+        echo "${optDryRun}Collate module doc:" 1>&2
+        collateModuleFiles doc
+    fi
+else
+    echo "${message} [disabled]" 1>&2
+fi
+# ----
+
+
+# tutorials
+# ----
+message="${optDryRun}Install tutorials:" 1>&2
+if [ -n "$install_tut" ]
+then
+    echo "${message}" 1>&2
+    doCopy tutorials
+
+    if [ "$install_tut" = collate ]
+    then
+        echo "${optDryRun}Collate module tutorials:" 1>&2
+        collateModuleFiles tutorials
+    fi
+else
+    echo "${message} [disabled]" 1>&2
+fi
+# ----
+
+
+if [ -n "$optDryRun" ]
+then
+    [ -n "$optVerbose" ] && echo 1>&2
+    echo "${optDryRun}Done" 1>&2
+fi
+
+
+exit 0 # clean exit
+
+#------------------------------------------------------------------------------
diff --git a/bin/tools/install-platform b/bin/tools/install-platform
new file mode 100755
index 0000000000000000000000000000000000000000..e55ab8c445f4d9f15ac1f91804324927e4875c1b
--- /dev/null
+++ b/bin/tools/install-platform
@@ -0,0 +1,375 @@
+#!/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
+#     install-platform
+#
+# Example usage
+#     install-platform -prefix=/opt/openfoam/openfoamVER
+#
+# Description
+#     Simple installer to copy OpenFOAM binary bin/, lib/ (platforms)
+#     directories.
+#
+# Note
+#     The platforms/tools directory still must be handled separately
+#
+# Layout of OpenFOAM platforms
+#
+#     platforms
+#     |-- <WM_OPTIONS>
+#         |-- bin
+#         |   |-- ...
+#         `-- lib
+#             |-- ...
+#             |-- dummy
+#             |   `-- ...
+#             |-- sys-openmpi
+#             |   |-- libPstream.so
+#             |   `-- libptscotchDecomp.so
+#             `-- paraview-MAJ.MIN
+#                 `-- ...
+#
+#------------------------------------------------------------------------------
+printHelp() {
+    cat<<USAGE
+
+Usage: ${0##*/} [OPTION]
+
+input options:
+  -source=SOURCE          Source directory
+                          [\$WM_PROJECT_DIR ${WM_PROJECT_DIR:-''}]
+  -platform=PLATFORM      OpenFOAM platform name [\$WM_OPTIONS ${WM_OPTIONS:-''}]
+  -foam-mpi=FOAM_MPI      OpenFOAM mpi name [\$FOAM_MPI ${FOAM_MPI:-''}]
+
+target options:
+  -prefix=PREFIX          Top-level installation directory in PREFIX ['']
+  -exec-prefix=EPREFIX    Architecture-dependent in EPREFIX
+                          [PREFIX/platforms/PLATFORM]
+  -bindir=DIR             bin directory [EPREFIX/bin]
+  -libdir=DIR             lib directory [EPREFIX/lib]
+  -mpi-libdir=DIR         mpi libdir [<libdir>/FOAM_MPI]
+
+tuning options:
+  -no-bin                 Do not install bin directory
+  -no-lib                 Do not install lib directory
+  -no-mpi                 Do not install mpi lib directory
+  -mpi-only               Only install mpi lib directory
+  -mpi-mkdir              Create foam-mpi directory within libdir
+
+general options:
+  -dry-run, -n            Do not perform any operations
+  -force, -f              Ignored
+  -verbose, -v            Additional verbosity
+  -help                   Print the help and exit
+
+
+Simple installer to copy OpenFOAM binary bin/, lib/ (platforms) directories.
+
+Example,
+    ${0##*/} -prefix=/opt/openfoamVER
+
+USAGE
+    exit 0  # A clean exit
+}
+
+unset optDryRun hadError
+# Report error and exit
+die()
+{
+    exec 1>&2
+    echo
+    echo "Error encountered:"
+    while [ "$#" -ge 1 ]; do echo "    $1"; shift; done
+    echo
+    echo "See '${0##*/} -help' for usage"
+    echo
+    exit 1
+}
+
+# Report error and exit
+warnOrDie()
+{
+    if [ -n "$optDryRun" ]
+    then
+        hadError=true
+        while [ "$#" -ge 1 ]; do echo "Error: $1" 1>&2; shift; done
+    else
+        die "$@"
+    fi
+}
+
+
+# Get the option's value (argument), or die on missing or empty value
+# $1 option=value
+getOptionValue()
+{
+    local value="${1#*=}"
+    # Remove any surrounding double quotes
+    value="${value%\"}"
+    value="${value#\"}"
+
+    [ -n "$value" ] || die "'${1%=}' option requires a value"
+    echo "$value"
+}
+
+
+# Test for '-no-' or '-without-' prefix. Return "false" or "true"
+# $1 option
+# [$2] truth value <true>
+getBoolOption()
+{
+    case "$1" in
+    (-no-* | -without-*) echo "false" ;;
+    (*) echo "${2:-true}" ;;
+    esac
+}
+
+
+#-------------------------------------------------------------------------------
+# Defaults from current OpenFOAM environment
+sourceDir="$WM_PROJECT_DIR"
+platform="$WM_OPTIONS"
+foam_mpi="$FOAM_MPI"
+
+unset install_bin install_lib
+unset optMkdir_mpi
+install_mpi=true
+
+unset prefix exec_prefix bindir libdir libdir_mpi optVerbose
+
+# Parse options
+while [ "$#" -gt 0 ]
+do
+    case "$1" in
+    -h | -help*)    printHelp ;;
+    -n | -dry-run)  optDryRun="(dry-run) " ;;
+    -v | -verbose)  optVerbose=true ;;
+    -f | -force)    echo "Ignored option: ${1%%=*}" 1>&2 ;;
+
+    # Inputs
+    -source=*)      sourceDir="$(getOptionValue "$1")" ;;
+    -platform=*)    platform="$(getOptionValue "$1")" ;;
+    -foam-mpi=*)    foam_mpi="$(getOptionValue "$1")" ;;
+
+    # Targets
+    -prefix=*)      prefix="$(getOptionValue "$1")" ;;
+    -exec-prefix=*) exec_prefix="$(getOptionValue "$1")" ;;
+
+    -bindir=*)      bindir="$(getOptionValue "$1")" ;;
+    -libdir=*)      libdir="$(getOptionValue "$1")" ;;
+    -mpi-libdir=*)  libdir_mpi="$(getOptionValue "$1")" ;;
+
+    -no-bin)        install_bin=false ;;
+    -no-lib)        install_lib=false ;;
+    -no-mpi)        install_mpi=false ;;
+    -mpi-only)      install_mpi=exclusive ;;
+    -mpi-mkdir)     optMkdir_mpi=true ;;
+
+    (*)  die "Unknown option/argument: $1" ;;
+    esac
+    shift
+done
+
+#-------------------------------------------------------------------------------
+
+# Default <exec_prefix> based on <prefix>
+if [ -z "$exec_prefix" ] && [ -n "$prefix" ]
+then
+    exec_prefix="$prefix/platforms/$platform"
+fi
+
+# Default <bindir>, <libdir> based on <exec_prefix>
+if [ -n "$exec_prefix" ]
+then
+    [ -n "$bindir" ] || bindir="$exec_prefix/bin"
+    [ -n "$libdir" ] || libdir="$exec_prefix/lib"
+fi
+
+# Default <mpi-libdir> based on <libdir> and <foam-mpi>
+if [ -z "$libdir_mpi" ] && [ -n "$libdir" ]
+then
+    libdir_mpi="$libdir/$foam_mpi"
+fi
+
+# Exclusions
+if [ "$install_bin" = false ] || [ "$install_mpi" = exclusive ]
+then
+    unset bindir
+fi
+if [ "$install_lib" = false ] || [ "$install_mpi" = exclusive ]
+then
+    unset libdir
+fi
+if [ "$install_mpi" = false ]
+then
+    unset libdir_mpi
+fi
+
+
+# Input checks
+
+sourcePlatform="$sourceDir/platforms/$platform"
+
+[ -d "$sourceDir" ] || warnOrDie "Invalid -source directory: $sourceDir"
+[ -n "$platform" ] || warnOrDie "No -platform detected or specified"
+[ -n "$foam_mpi" ] || warnOrDie "No -foam-mpi detected or specified"
+
+[ -d "$sourcePlatform" ] || \
+    warnOrDie "Missing platforms directory for: $platform"
+
+
+# Installation sanity check
+[ -n "$bindir$libdir$libdir_mpi" ] || \
+    warnOrDie "Must specify at least one of -prefix, -exec-prefix, -bindir, -libdir, -mpi-libdir"
+
+
+if [ -n "$hadError" ]
+then
+    echo "Errors encounters in dry-run. Stopping" 1>&2
+    exit 1
+fi
+
+# Report settings
+echo "Preparing install with the following parameters" 1>&2
+echo "source:" 1>&2
+echo "    directory   $sourceDir" 1>&2
+echo "    platform    $platform" 1>&2
+echo "    foam-mpi    $foam_mpi" 1>&2
+echo 1>&2
+echo "target (mpi-install: $install_mpi)" 1>&2
+echo "    prefix      ${prefix-[]}" 1>&2
+echo "    exec-prefix ${exec_prefix:-[]}" 1>&2
+echo "    bindir      ${bindir:-[]}" 1>&2
+echo "    libdir      ${libdir:-[]}" 1>&2
+echo "    libdir(mpi) ${libdir_mpi:-[]}" 1>&2
+echo 1>&2
+
+
+#------------------------------------------------------------------------------
+# Proper umask
+umask 022
+
+# The commands
+copy_cmd="cp -a ${optVerbose:+-v}"
+mkdir_cmd="mkdir -p"
+
+if [ -n "$optDryRun" ]
+then
+    if [ -n "$optVerbose" ]
+    then
+        copy_cmd="echo cp -a"
+        mkdir_cmd="echo mkdir -p"
+    else
+        copy_cmd="true"
+        mkdir_cmd="true"
+    fi
+fi
+
+
+# bin/
+# ----
+message="${optDryRun}Install bindir:"
+if [ -n "$bindir" ]
+then
+    input="$sourcePlatform/bin"
+
+    echo "From $input" 1>&2
+    echo "${message} $bindir" 1>&2
+
+    $mkdir_cmd "$bindir" 2>/dev/null
+
+    for i in "$input/"*
+    do
+        if [ -e "$i" ]
+        then
+            $copy_cmd "$i" "$bindir"
+        fi
+    done
+else
+    echo "${message} [disabled]" 1>&2
+fi
+# ----
+
+
+# lib/ without mpi
+# ----
+message="${optDryRun}Install libdir(non-mpi):"
+if [ -n "$libdir" ]
+then
+    input="$sourcePlatform/lib"
+
+    echo "From $input" 1>&2
+    echo "${message} $libdir" 1>&2
+
+    $mkdir_cmd "$libdir" 2>/dev/null
+
+    for i in "$input/"*
+    do
+        if [ "${i##*/}" = "$foam_mpi" ]
+        then
+            if [ "$optMkdir_mpi" = true ]
+            then
+                $mkdir_cmd "$libdir/$foam_mpi"
+            fi
+        elif [ -e "$i" ]
+        then
+            $copy_cmd "$i" "$libdir"
+        else
+            echo "bogus lib entry? $i" 1>&2
+        fi
+    done
+else
+    echo "${message} [disabled]" 1>&2
+fi
+# ----
+
+
+# lib/mpi
+# ----
+message="${optDryRun}Install libdir(mpi):"
+if [ -n "$libdir_mpi" ]
+then
+    input="$sourcePlatform/lib/$foam_mpi"
+
+    echo "From $input" 1>&2
+    echo "${message} $libdir_mpi" 1>&2
+
+    $mkdir_cmd "$libdir_mpi" 2>/dev/null
+
+    for i in "$input"/*
+    do
+        if [ -e "$i" ]
+        then
+            # Always verbose (not many files anyhow)
+            $copy_cmd -v "$i" "$libdir_mpi"
+        else
+            echo "bogus mpi-lib entry? $i" 1>&2
+        fi
+    done
+else
+    echo "${message} [disabled]" 1>&2
+fi
+# ----
+
+
+if [ -n "$optDryRun" ]
+then
+    [ -n "$optVerbose" ] && echo 1>&2
+    echo "${optDryRun}Done" 1>&2
+fi
+
+
+exit 0  # A clean exit
+
+#------------------------------------------------------------------------------
diff --git a/bin/tools/update-mpi-links.in b/bin/tools/update-mpi-links.in
new file mode 100644
index 0000000000000000000000000000000000000000..377c0f39af1f0d6635b15a81d07c0e77139d21e3
--- /dev/null
+++ b/bin/tools/update-mpi-links.in
@@ -0,0 +1,75 @@
+#!/bin/sh
+FOAM_MPI="@FOAM_MPI@"
+FOAM_SYSTEM_MPI_LIBBIN="@FOAM_SYSTEM_MPI_LIBBIN@"
+#------------------------------------------------------------------------------
+# =========                 |
+# \\      /  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.
+#
+# Description
+#     Update of links from system mpi lib/ to local lib/mpi-name
+#
+# Note
+#     Normally located as a trigger within the platforms/ directory
+#     Uses hard-coded values (eg, generated with autoconfig).
+#
+#------------------------------------------------------------------------------
+cd "${0%/*}" || exit                                # Run from this directory
+
+# Local values
+FOAM_LIBBIN="$(pwd -P)/lib"
+FOAM_MPI_LIBBIN="$FOAM_LIBBIN/$FOAM_MPI"
+
+#------------------------------------------------------------------------------
+echo "Link OpenFOAM ($FOAM_MPI) from system locations"
+echo "Target: $FOAM_MPI_LIBBIN"
+echo "Source: $FOAM_SYSTEM_MPI_LIBBIN"
+
+if [ -z "$FOAM_MPI" ]
+then
+    echo "FOAM_MPI not defined - skipping"
+    exit 0
+fi
+if [ -z "$FOAM_SYSTEM_MPI_LIBBIN" ]
+then
+    echo "FOAM_SYSTEM_MPI_LIBBIN not defined - skipping"
+    exit 0
+fi
+if [ ! -d "$FOAM_SYSTEM_MPI_LIBBIN" ]
+then
+    echo "No system mpi lib: $FOAM_SYSTEM_MPI_LIBBIN"
+    echo "... not updating"
+    exit 0
+fi
+if [ ! -d "$FOAM_LIBBIN" ]
+then
+    echo "Missing $FOAM_LIBBIN"
+    exit 0
+fi
+
+#------------------------------------------------------------------------------
+mkdir -p "$FOAM_MPI_LIBBIN"
+
+# Create symlinks
+(
+    cd "$FOAM_MPI_LIBBIN" || exit
+
+    for i in "$FOAM_SYSTEM_MPI_LIBBIN"/*
+    do
+        if [ -f "$i" ]
+        then
+            ln -svf "$i" "${i##*/}"
+        fi
+    done
+)
+
+exit 0  # clean exit
+
+#------------------------------------------------------------------------------
diff --git a/wmake/scripts/AllwmakeParseArguments b/wmake/scripts/AllwmakeParseArguments
index 80da8a5b75be06e741e96e07da02cb000577ad5a..9eeeba595b5c2f3993ed3b10da26836dd84c60fc 100644
--- a/wmake/scripts/AllwmakeParseArguments
+++ b/wmake/scripts/AllwmakeParseArguments
@@ -6,11 +6,10 @@
 #    \\/     M anipulation  |
 #------------------------------------------------------------------------------
 #     Copyright (C) 2014-2017 OpenFOAM Foundation
-#     Copyright (C) 2019 OpenCFD Ltd.
+#     Copyright (C) 2019-2020 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM, licensed under GNU General Public License
-#     <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # File
 #     wmake/scripts/AllwmakeParseArguments
@@ -22,14 +21,35 @@
 #     # Parse the arguments by sourcing this script
 #     . ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments
 #
+# Parsed options (make)
+#     -k | -keep-going | -non-stop
+#     -j | -jN | -j N
+#
+# Parsed options (wmake)
+#     -debug
+#     -q | -queue
+#     -module-prefix=...
+#         Exports FOAM_MODULE_PREFIX value.
+#         Unsets FOAM_MODULE_APPBIN, FOAM_MODULE_LIBBIN.
+#         Handles (user|group|openfoam) or (u|g|o) as per foamEtcFile,
+#         or absolute/relative paths
+#
+# Parsed options (special)
+#     -l | -log | -log=FILE
+#     -prefix=...   same as -module-prefix=...
+#
 #------------------------------------------------------------------------------
-
-if [ -z "$WM_PROJECT_DIR" ]
-then
-    echo "$Script error: The OpenFOAM environment is not set."
-    echo "    Check the OpenFOAM entries in your dot-files and source them."
+# Check environment
+[ -d "$WM_PROJECT_DIR" ] || {
+    exec 1>&2
+    echo "$0"
+    echo "Error encountered:"
+    echo "    The OpenFOAM environment not set or incorrect."
+    echo "    Check your setup."
+    echo
     exit 1
-fi
+}
+
 usage() {
     exec 1>&2
     while [ "$#" -ge 1 ]; do echo "$1"; shift; done
@@ -40,13 +60,18 @@ Executing ${0##*/} is equivalent to
 
    wmake -all [OPTIONS]
 
-With these additional options:
-   -l | -log | -log=name
+With additional options:
+    -l | -log       Tee output to log.\$WM_OPTIONS
+    -log=FILE       Tee output to given filename
+    -prefix=...     Define FOAM_MODULE_PREFIX (same as wmake -module-prefix)
+    -no-recursion   Prevent recursive call (do NOT call 'wmake -all')
+    -fromWmake      Same as -no-recursion
 
-USAGE
+See
+    wmake -help (or wmake -help-full)
 
-    wmake -help
-    exit 0
+USAGE
+    exit 0  # clean exit
 }
 
 
@@ -54,7 +79,8 @@ USAGE
 # Parse the arguments and options
 #------------------------------------------------------------------------------
 
-unset fromWmake optDebug optLog optQueue
+unset optDebug optLog optNonRecursive optQueue
+unset optWmakeFrontend
 
 for arg in "$@"
 do
@@ -65,41 +91,81 @@ do
     -h | -help*)
         usage
         ;;
-    -fromWmake)
-        # If called from wmake (to avoid recursion)
-        fromWmake=true
+
+    -no-recurs* | -fromWmake)
+        # Avoid recursion (eg, if called from wmake)
+        optNonRecursive=true
+        # Pass onwards to other Allwmake scripts
+        ;;
+
+    -module-prefix=* | -prefix=* | --prefix=*)
+        # As per setModulePrefix (wmakeFunctions)
+        export FOAM_MODULE_PREFIX="${arg#*=}"
+        case "$FOAM_MODULE_PREFIX" in
+        # Prefix: user
+        (u | user)      FOAM_MODULE_PREFIX="${FOAM_USER_LIBBIN%/*}" ;;
+
+        # Prefix: group
+        (g | group)     FOAM_MODULE_PREFIX="${FOAM_SITE_LIBBIN%/*}" ;;
+
+        # Prefix: openfoam (other)
+        (o | openfoam)  FOAM_MODULE_PREFIX="${FOAM_LIBBIN%/*}" ;;
+
+        # Prefix: false (ie, 'disabled')
+        (false) FOAM_MODULE_PREFIX=false ;;
+
+        # Prefix: directory (absolute or relative)
+        (*)
+            : "${FOAM_MODULE_PREFIX:=/usr/local}"  # Fallback (autoconf-like)
+
+            # Require absolute path
+            [ "${FOAM_MODULE_PREFIX#/}" != "${FOAM_MODULE_PREFIX}" ] || \
+                FOAM_MODULE_PREFIX="${PWD}/${FOAM_MODULE_PREFIX}"
+            ;;
+        esac
+
+        # Avoid potential conflicts
+        unset FOAM_MODULE_APPBIN FOAM_MODULE_LIBBIN
+        echo "Module prefix = ${FOAM_MODULE_PREFIX:-[]}" 1>&2
+        continue    # Argument handled, remove it
         ;;
+
     -k | -keep-going | -non-stop)
         # Keep going, ignoring errors
         export WM_CONTINUE_ON_ERROR=true
-        continue    # Permanently remove arg
+        continue    # Argument handled, remove it
         ;;
+
     -l | -log)
-        optLog="log.${WM_OPTIONS:-Allwmake}"
-        continue    # Permanently remove arg
+        optLog="log.${WM_OPTIONS:-build}"
+        continue    # Argument handled, remove it
         ;;
+
     -log=*)
         optLog="${arg##*=}"
         if [ -d "$optLog" ]
         then
-            optLog="${optLog%/}/log.${WM_OPTIONS:-Allwmake}"
+            optLog="${optLog%/}/log.${WM_OPTIONS:-build}"
         elif [ -z "$optLog" ]
         then
-            optLog="log.${WM_OPTIONS:-Allwmake}"
+            optLog="log.${WM_OPTIONS:-build}"
         fi
-        continue    # Permanently remove arg
+        continue    # Argument handled, remove it
         ;;
+
     -debug)
         optDebug="-debug"
-        continue    # Permanently remove arg
+        continue    # Argument handled, remove it
         ;;
+
     -q | -queue)
         optQueue="-queue"
-        continue    # Permanently remove arg
+        continue    # Argument handled, remove it
         ;;
+
     lib | libo | libso | dep | objects)
         # Target type
-        targetType=$arg
+        targetType="$arg"
         ;;
     esac
 
@@ -112,20 +178,22 @@ done
 # Execute wmake -all if not called from wmake
 #------------------------------------------------------------------------------
 
-if [ -z "$fromWmake" ]
+if [ -z "$optNonRecursive" ]
 then
     if [ -z "$optLog" ]
     then
-        exec wmake -all $optQueue $*
+        exec wmake $optWmakeFrontend -all \
+            $optDebug $optQueue $*
         exit $? # Unneeded, but just in case something went wrong
     else
         echo "Logging wmake -all output to '$optLog'" 1>&2
         echo 1>&2
-        exec wmake -all $optDebug $optQueue $* 2>&1 | /usr/bin/tee $optLog
+        exec wmake $optWmakeFrontend -all \
+            $optDebug $optQueue $* 2>&1 | /usr/bin/tee $optLog
         # Need to cleanup after the tee
         rc=$? # Error code from tee (not wmake), but not entirely important
         echo "Done logging to '$optLog'" 1>&2
-        exit $rc
+        exit "$rc"
     fi
 fi
 
@@ -144,7 +212,8 @@ fi
 # Cleanup local variables and functions
 #------------------------------------------------------------------------------
 
-unset fromWmake optDebug optLog optQueue
+unset optWmakeFrontend
+unset optNonRecursive optDebug optLog optQueue
 unset -f usage