diff --git a/bin/foamCleanTutorials b/bin/foamCleanTutorials
index d2d1eeb153f6f73a158aaed588471fd006aeafbc..39eb05dc2d9cb0492ea16d645c4bc9db2ba81973 100755
--- a/bin/foamCleanTutorials
+++ b/bin/foamCleanTutorials
@@ -20,7 +20,7 @@
 #     and all its subdirectories.
 #
 #------------------------------------------------------------------------------
-. $WM_PROJECT_DIR/bin/tools/CleanFunctions  # Tutorial clean functions
+. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions  # Tutorial clean functions
 
 thisScript="$0"
 if [ "/${thisScript#/}" != "$thisScript" ]
@@ -41,6 +41,7 @@ options:
 
 Recursively clean an OpenFOAM case directory.
 By default uses Allclean, Allwclean when present.
+The -skipFirst option is the same as -self.
 
 USAGE
    exit 0  # clean exit
@@ -80,7 +81,7 @@ then
             exit 2
         }
         ;;
-    -self*)
+    -self* | -skipFirst)
         skipSelf=true
         ;;
     --)
@@ -133,7 +134,7 @@ else
     # Recurse into subdirectories
     for caseName in *
     do
-        ( cd $caseName 2>/dev/null && "$thisScript" )
+        ( cd "$caseName" 2>/dev/null && "$thisScript" )
     done
 fi
 
diff --git a/bin/foamRunTutorials b/bin/foamRunTutorials
index 27553b651d22e163c415464dda53c9a077f8803b..d64576ce8ab92ea6b2f9fecc60af661ea1ea25c4 100755
--- a/bin/foamRunTutorials
+++ b/bin/foamRunTutorials
@@ -41,12 +41,13 @@ printHelp() {
 Usage: ${0##*/} [OPTION]
 options:
   -case <dir>       specify starting directory, default is cwd
-  -self | -skipFirst avoid Allrun, Alltest script (prevent infinite recursion)
+  -self             avoid Allrun, Alltest script (prevent infinite recursion)
   -test             prefer Alltest script, pass -test argument to scripts
   -help             print the usage
 
 Recursively run Allrun/Alltest or blockMesh+application,
 starting with the current directory or the specified -case directory.
+The -skipFirst option is the same as -self.
 
 USAGE
    exit 0  # clean exit
diff --git a/modules/Allwmake b/modules/Allwmake
index cd8a2106249004d5e3fabf0f9390a22a7f5aaa12..1a6ca9486759c29330e101a1422bacb610364fe5 100755
--- a/modules/Allwmake
+++ b/modules/Allwmake
@@ -10,29 +10,8 @@ targetType=libso
 : "${FOAM_MODULE_PREFIX:=${FOAM_LIBBIN%/*}}"
 export FOAM_MODULE_PREFIX
 
-
-#------------------------------------------------------------------------------
-
-# Skip some directory names
-filterDir() {
-    case "$1" in
-    (build | platforms | doc)
-        echo ""
-        ;;
-    (*)
-        echo "$1"
-        ;;
-    esac
-}
-
-
-# Build each first-level directory with an Allwmake* file
-for moduleName in \
-    $(find . -mindepth 2 -maxdepth 2 -name 'Allwmake*' -print | \
-      sed -e 's@^\./@@; s@/.*$@@;' | sort | uniq)
+for moduleName in $(./list-modules)
 do
-    moduleName="$(filterDir "$moduleName")"
-
     if [ -d "$moduleName" ]
     then
         ( cd "$moduleName" && wmake -all $targetType )
diff --git a/modules/list-modules b/modules/list-modules
new file mode 100755
index 0000000000000000000000000000000000000000..c41c57d4662b25d8eeda711299e4630e1ed0de0f
--- /dev/null
+++ b/modules/list-modules
@@ -0,0 +1,84 @@
+#!/bin/sh
+#------------------------------------------------------------------------------
+# =========                 |
+# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+#  \\    /   O peration     |
+#   \\  /    A nd           | www.openfoam.com
+#    \\/     M anipulation  |
+#------------------------------------------------------------------------------
+#     SPDX-License-Identifier: (GPL-3.0+)
+#     Copyright (C) 2020 OpenCFD Ltd.
+#------------------------------------------------------------------------------
+# Script
+#     list-modules
+#
+# Description
+#     List module directories
+#     - each first-level directory with an Allwmake file
+#
+#------------------------------------------------------------------------------
+cd "${0%/*}" || exit                            # Run from this directory
+
+printHelp() {
+    cat<< HELP 1>&2
+
+Usage: ${0##*/} [OPTION]
+options:
+  -help             Display help and exit
+
+List module directories - each first-level directory with an Allwmake file
+
+HELP
+
+    exit 0  # A clean exit
+}
+
+# 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
+}
+
+#------------------------------------------------------------------------------
+
+# Parse options
+while [ "$#" -gt 0 ]
+do
+    case "$1" in
+    -h | -help*)  # Short help
+        printHelp
+        ;;
+
+    *)
+        die "Unknown option/argument: '$1'"
+        ;;
+    esac
+    shift
+done
+
+
+# Each first-level directory with an Allwmake file
+for moduleName in *
+do
+    if [ -f "$moduleName/Allwmake" ]
+    then
+        case "$moduleName" in
+        # Skip some directory names
+        (build | doc | platform*)
+            ;;
+        (*)
+            echo "$moduleName"
+            ;;
+        esac
+    fi
+done
+
+
+#------------------------------------------------------------------------------
diff --git a/wmake/scripts/have_adios2 b/wmake/scripts/have_adios2
index 3f9635392c20f9e35a15e5d99e5a288b15507d9b..2283006b4d716fb570ff06ac44f0dba4c8564031 100644
--- a/wmake/scripts/have_adios2
+++ b/wmake/scripts/have_adios2
@@ -45,9 +45,9 @@ no_adios2()
 echo_adios2()
 {
     echo "adios2=${HAVE_ADIOS2:-false}"
-    echo "root=$ADIOS2_ARCH_PATH"
-    echo "include=$ADIOS2_INC_DIR"
-    echo "library=$ADIOS2_LIB_DIR"
+    echo "root=\"$ADIOS2_ARCH_PATH\""
+    echo "include=\"$ADIOS2_INC_DIR\""
+    echo "library=\"$ADIOS2_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/have_boost b/wmake/scripts/have_boost
index 301d2c3be6fa5e9f9470237871c32e0bf6c36591..95886c82c1b3f1414afc482f278bc343fc470856 100644
--- a/wmake/scripts/have_boost
+++ b/wmake/scripts/have_boost
@@ -45,9 +45,9 @@ no_boost()
 echo_boost()
 {
     echo "boost=${HAVE_BOOST:-false}"
-    echo "root=$BOOST_ARCH_PATH"
-    echo "include=$BOOST_INC_DIR"
-    echo "library=$BOOST_LIB_DIR"
+    echo "root=\"$BOOST_ARCH_PATH\""
+    echo "include=\"$BOOST_INC_DIR\""
+    echo "library=\"$BOOST_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/have_ccmio b/wmake/scripts/have_ccmio
index badeee322c5e76e7f0388c9478d21b35bee76ea9..68050081dbcb92f92fa6d2306474b79c767789b2 100644
--- a/wmake/scripts/have_ccmio
+++ b/wmake/scripts/have_ccmio
@@ -44,9 +44,9 @@ no_ccmio()
 echo_ccmio()
 {
     echo "ccmio=${HAVE_CCMIO:-false}"
-    echo "root=$CCMIO_ARCH_PATH"
-    echo "include=$CCMIO_INC_DIR"
-    echo "library=$CCMIO_LIB_DIR"
+    echo "root=\"$CCMIO_ARCH_PATH\""
+    echo "include=\"$CCMIO_INC_DIR\""
+    echo "library=\"$CCMIO_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/have_cgal b/wmake/scripts/have_cgal
index 94a247ab3c8ccc0dae40f94289fb6451ba9e8209..eaf19731037ff1eaa55be913e2bdb321dca462eb 100644
--- a/wmake/scripts/have_cgal
+++ b/wmake/scripts/have_cgal
@@ -50,9 +50,9 @@ echo_cgal()
 {
     echo "cgal=${HAVE_CGAL:-false}"
     echo "flavour=$CGAL_FLAVOUR"
-    echo "root=$CGAL_ARCH_PATH"
-    echo "include=$CGAL_INC_DIR"
-    echo "library=$CGAL_LIB_DIR"
+    echo "root=\"$CGAL_ARCH_PATH\""
+    echo "include=\"$CGAL_INC_DIR\""
+    echo "library=\"$CGAL_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/have_fftw b/wmake/scripts/have_fftw
index 634e2af8083299700405193eec6767c0edd09d5d..281669c248b1bf403142e839183aa32ebc25eaf9 100644
--- a/wmake/scripts/have_fftw
+++ b/wmake/scripts/have_fftw
@@ -45,9 +45,9 @@ no_fftw()
 echo_fftw()
 {
     echo "fftw=${HAVE_FFTW:-false}"
-    echo "root=$FFTW_ARCH_PATH"
-    echo "include=$FFTW_INC_DIR"
-    echo "library=$FFTW_LIB_DIR"
+    echo "root=\"$FFTW_ARCH_PATH\""
+    echo "include=\"$FFTW_INC_DIR\""
+    echo "library=\"$FFTW_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/have_hypre b/wmake/scripts/have_hypre
index cf456b847def5472a9e3d828768f7d6e1d68e7a0..bfe4c9a76633beee5b2afe6cd567f9448b9908c6 100644
--- a/wmake/scripts/have_hypre
+++ b/wmake/scripts/have_hypre
@@ -45,9 +45,9 @@ no_hypre()
 echo_hypre()
 {
     echo "hypre=${HAVE_HYPRE:-false}"
-    echo "root=$HYPRE_ARCH_PATH"
-    echo "include=$HYPRE_INC_DIR"
-    echo "library=$HYPRE_LIB_DIR"
+    echo "root=\"$HYPRE_ARCH_PATH\""
+    echo "include=\"$HYPRE_INC_DIR\""
+    echo "library=\"$HYPRE_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/have_kahip b/wmake/scripts/have_kahip
index 0f5da3a254b1f1e18692f7c59e5038b7b8187d75..04ccc8643e19361c3c97a1787a9f4e2c9f3a7660 100644
--- a/wmake/scripts/have_kahip
+++ b/wmake/scripts/have_kahip
@@ -45,9 +45,9 @@ no_kahip()
 echo_kahip()
 {
     echo "kahip=${HAVE_KAHIP:-false}"
-    echo "root=$KAHIP_ARCH_PATH"
-    echo "include=$KAHIP_INC_DIR"
-    echo "library=$KAHIP_LIB_DIR"
+    echo "root=\"$KAHIP_ARCH_PATH\""
+    echo "include=\"$KAHIP_INC_DIR\""
+    echo "library=\"$KAHIP_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/have_metis b/wmake/scripts/have_metis
index 8da19e4a82d542e259b78c77836fa64c5aca1569..7b545d9064f6d9beaf3ee2891cb91b3246893178 100644
--- a/wmake/scripts/have_metis
+++ b/wmake/scripts/have_metis
@@ -45,9 +45,9 @@ no_metis()
 echo_metis()
 {
     echo "metis=${HAVE_METIS:-false}"
-    echo "root=$METIS_ARCH_PATH"
-    echo "include=$METIS_INC_DIR"
-    echo "library=$METIS_LIB_DIR"
+    echo "root=\"$METIS_ARCH_PATH\""
+    echo "include=\"$METIS_INC_DIR\""
+    echo "library=\"$METIS_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/have_mgridgen b/wmake/scripts/have_mgridgen
index f374e7c375a4879b78fc4f5c97600d279f40c394..6c00f401e01fedfdc34191fca576f45dfbadc6d8 100644
--- a/wmake/scripts/have_mgridgen
+++ b/wmake/scripts/have_mgridgen
@@ -45,9 +45,9 @@ no_mgridgen()
 echo_mgridgen()
 {
     echo "mgridgen=${HAVE_MGRIDGEN:-false}"
-    echo "root=$MGRIDGEN_ARCH_PATH"
-    echo "include=$MGRIDGEN_INC_DIR"
-    echo "library=$MGRIDGEN_LIB_DIR"
+    echo "root=\"$MGRIDGEN_ARCH_PATH\""
+    echo "include=\"$MGRIDGEN_INC_DIR\""
+    echo "library=\"$MGRIDGEN_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/have_petsc b/wmake/scripts/have_petsc
index e6690f029952eca74811cafa4e81a8713ddb84cc..2524523c75a34f2d9a66ff393622708d0b428f01 100644
--- a/wmake/scripts/have_petsc
+++ b/wmake/scripts/have_petsc
@@ -46,9 +46,9 @@ no_petsc()
 echo_petsc()
 {
     echo "petsc=${HAVE_PETSC:-false}"
-    echo "root=$PETSC_ARCH_PATH"
-    echo "include=$PETSC_INC_DIR"
-    echo "library=$PETSC_LIB_DIR"
+    echo "root=\"$PETSC_ARCH_PATH\""
+    echo "include=\"$PETSC_INC_DIR\""
+    echo "library=\"$PETSC_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/have_readline b/wmake/scripts/have_readline
index 2b3ab9edfa6dd2a3d5c138a4bb21c7a890887c43..16b0bba5e42148473177b819079eff2a5ee54ade 100644
--- a/wmake/scripts/have_readline
+++ b/wmake/scripts/have_readline
@@ -43,8 +43,8 @@ no_readline()
 echo_readline()
 {
     echo "readline=${HAVE_LIBREADLINE:-false}"
-    echo "include=$READLINE_INC_DIR"
-    echo "library=$READLINE_LIB_DIR"
+    echo "include=\"$READLINE_INC_DIR\""
+    echo "library=\"$READLINE_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/have_scotch b/wmake/scripts/have_scotch
index 8f8a33d3dd90a6a0bf6dd095c3bff7d9a6831dce..ca00bba6fc2c562e32d2bb7554829c980090fb29 100644
--- a/wmake/scripts/have_scotch
+++ b/wmake/scripts/have_scotch
@@ -55,14 +55,14 @@ no_scotch()
 echo_scotch()
 {
     echo "scotch=${HAVE_SCOTCH:-false}"
-    echo "root=$SCOTCH_ARCH_PATH"
-    echo "include=$SCOTCH_INC_DIR"
-    echo "library=$SCOTCH_LIB_DIR"
+    echo "root=\"$SCOTCH_ARCH_PATH\""
+    echo "include=\"$SCOTCH_INC_DIR\""
+    echo "library=\"$SCOTCH_LIB_DIR\""
     echo
     echo "ptscotch=${HAVE_PTSCOTCH:-false}"
-    echo "root=$PTSCOTCH_ARCH_PATH"
-    echo "include=$PTSCOTCH_INC_DIR"
-    echo "library=$PTSCOTCH_LIB_DIR"
+    echo "root=\"$PTSCOTCH_ARCH_PATH\""
+    echo "include=\"$PTSCOTCH_INC_DIR\""
+    echo "library=\"$PTSCOTCH_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/have_zoltan b/wmake/scripts/have_zoltan
index d212eb12ba9f1530456592a3863eb3836e6ef833..b78fcbcdaf3a8b8b9452c3f01df3a9616f07693b 100644
--- a/wmake/scripts/have_zoltan
+++ b/wmake/scripts/have_zoltan
@@ -44,9 +44,9 @@ no_zoltan()
 echo_zoltan()
 {
     echo "zoltan=${HAVE_ZOLTAN:-false}"
-    echo "root=$ZOLTAN_ARCH_PATH"
-    echo "include=$ZOLTAN_INC_DIR"
-    echo "library=$ZOLTAN_LIB_DIR"
+    echo "root=\"$ZOLTAN_ARCH_PATH\""
+    echo "include=\"$ZOLTAN_INC_DIR\""
+    echo "library=\"$ZOLTAN_LIB_DIR\""
 }
 
 
diff --git a/wmake/scripts/paraviewFunctions b/wmake/scripts/paraviewFunctions
index dc80705975e2a3c0af48083560aad91ea6508d76..1791ce500425a5a3694ec730e0531aef3e3d4b67 100644
--- a/wmake/scripts/paraviewFunctions
+++ b/wmake/scripts/paraviewFunctions
@@ -53,9 +53,9 @@ no_paraview()
 echo_paraview()
 {
     echo "paraview=${HAVE_PVPLUGIN_SUPPORT:-false}"
-    echo "root=$ParaView_DIR"
-    echo "include=$PARAVIEW_INC_DIR"
-    echo "plugin=$FOAM_PV_PLUGIN_LIBBIN"
+    echo "root=\"$ParaView_DIR\""
+    echo "include=\"$PARAVIEW_INC_DIR\""
+    echo "plugin=\"$FOAM_PV_PLUGIN_LIBBIN\""
     echo "api=$PARAVIEW_API"
 }