diff --git a/src/OSspecific/MSwindows/MSwindows.C b/src/OSspecific/MSwindows/MSwindows.C
index 4516c6a7fbe1d0a0ad9626e6aa0650dea499ef26..9ea78be68090af92e8c3770e83076232087d2f71 100644
--- a/src/OSspecific/MSwindows/MSwindows.C
+++ b/src/OSspecific/MSwindows/MSwindows.C
@@ -47,6 +47,8 @@ License
 #include <io.h>     // For _close
 #include <windows.h>
 
+#define EXT_SO  "dll"
+
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -1190,14 +1192,21 @@ void* Foam::dlOpen(const fileName& libName, const bool check)
             << " : dlopen of " << libName << std::endl;
     }
 
-    // Map "libXX.so" and "libXX" to "libXX.dll"
+    // Always remap "libXX.so" and "libXX" to "libXX.dll"
+    fileName libso(libName.lessExt().ext(EXT_SO));
+
+    void* handle = ::LoadLibrary(libso.c_str());
 
-    fileName winLibName(libName.lessExt().ext("dll"));
-    void* handle = ::LoadLibrary(winLibName.c_str());
+    if (!handle && !libso.startsWith("lib"))
+    {
+        // Try with 'lib' prefix
+        libso = "lib" + libso;
+        handle = ::LoadLibrary(libso.c_str());
+    }
 
     if (handle)
     {
-        libsLoaded[handle] = libName.lessExt();
+        libsLoaded[handle] = libso.lessExt();
     }
     else if (check)
     {
@@ -1218,6 +1227,26 @@ void* Foam::dlOpen(const fileName& libName, const bool check)
 }
 
 
+Foam::label Foam::dlOpen
+(
+    std::initializer_list<fileName> libNames,
+    const bool check
+)
+{
+    label nLoaded = 0;
+
+    for (const fileName& libName : libNames)
+    {
+        if (Foam::dlOpen(libName, check))
+        {
+            ++nLoaded;
+        }
+    }
+
+    return nLoaded;
+}
+
+
 bool Foam::dlClose(void* const handle)
 {
     if (MSwindows::debug)
diff --git a/src/OSspecific/POSIX/POSIX.C b/src/OSspecific/POSIX/POSIX.C
index 7ac75e90a452ca170e083439abcd8035bdee9303..e7ad0f456579716dcc4c03cf7681b25f1fd42475 100644
--- a/src/OSspecific/POSIX/POSIX.C
+++ b/src/OSspecific/POSIX/POSIX.C
@@ -61,8 +61,10 @@ Description
 #include <dlfcn.h>
 
 #ifdef __APPLE__
+    #define EXT_SO  "dylib"
     #include <mach-o/dyld.h>
 #else
+    #define EXT_SO  "so"
 
     // PGI does not have __int128_t
     #ifdef __PGIC__
@@ -1653,22 +1655,40 @@ int Foam::system(const Foam::UList<Foam::string>& command, const bool bg)
 
 void* Foam::dlOpen(const fileName& libName, const bool check)
 {
+    constexpr int ldflags = (RTLD_LAZY|RTLD_GLOBAL);
+
     if (POSIX::debug)
     {
         std::cout
             << "dlOpen(const fileName&)"
             << " : dlopen of " << libName << std::endl;
     }
-    void* handle = ::dlopen(libName.c_str(), RTLD_LAZY|RTLD_GLOBAL);
 
-    #ifdef __APPLE__
-    // Re-try "libXX.so" as "libXX.dylib"
-    if (!handle && libName.hasExt("so"))
+    void* handle = ::dlopen(libName.c_str(), ldflags);
+
+    if (!handle)
     {
-        const fileName dylibName(libName.lessExt().ext("dylib"));
-        handle = ::dlopen(dylibName.c_str(), RTLD_LAZY|RTLD_GLOBAL);
+        fileName libso;
+
+        if (!libName.startsWith("lib"))
+        {
+            // Try with 'lib' prefix
+            libso = "lib" + libName;
+            handle = ::dlopen(libso.c_str(), ldflags);
+        }
+        else
+        {
+            libso = libName;
+        }
+
+        // With canonical library extension ("so" or "dylib"), which remaps
+        // "libXX" to "libXX.so" as well as "libXX.so" -> "libXX.dylib"
+        if (!handle && !libso.hasExt(EXT_SO))
+        {
+            libso = libso.lessExt().ext(EXT_SO);
+            handle = ::dlopen(libso.c_str(), ldflags);
+        }
     }
-    #endif
 
     if (!handle && check)
     {
@@ -1689,6 +1709,26 @@ void* Foam::dlOpen(const fileName& libName, const bool check)
 }
 
 
+Foam::label Foam::dlOpen
+(
+    std::initializer_list<fileName> libNames,
+    const bool check
+)
+{
+    label nLoaded = 0;
+
+    for (const fileName& libName : libNames)
+    {
+        if (Foam::dlOpen(libName, check))
+        {
+            ++nLoaded;
+        }
+    }
+
+    return nLoaded;
+}
+
+
 bool Foam::dlClose(void* handle)
 {
     if (POSIX::debug)
diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C
index 0c5d105c935342fa1e6722073013976eb6d1d002..e20b4ebd99c1b76d14e08d14fcdcb3280d774141 100644
--- a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C
+++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C
@@ -36,7 +36,6 @@ License
 #include "dictionary.H"
 #include "foamVersion.H"
 
-#undef EXT_SO
 #ifdef __APPLE__
     #define EXT_SO  ".dylib"
 #elif defined _WIN32
diff --git a/src/OpenFOAM/include/OSspecific.H b/src/OpenFOAM/include/OSspecific.H
index 2f568d6bab50b21a0839d525f5b37d7de8421310..a2e906e14770b3161c8bb72a5018c73d5fb48774 100644
--- a/src/OpenFOAM/include/OSspecific.H
+++ b/src/OpenFOAM/include/OSspecific.H
@@ -253,8 +253,14 @@ int system(const UList<string>& command, const bool bg = false);
 int system(const CStringList& command, const bool bg = false);
 
 //- Open a shared library and return handle to library.
-//  Print error message if library cannot be loaded (suppress with check=true)
-void* dlOpen(const fileName& lib, const bool check = true);
+//  A leading "lib" and ".so" suffix are added silently as required.
+//  Prints warning if a library cannot be loaded (suppress with check=false)
+void* dlOpen(const fileName& libName, const bool check=true);
+
+//- Open shared libraries and return number of libraries loaded.
+//  A leading "lib" and ".so" suffix are added silently as required.
+//  Prints warning if a library cannot be loaded (suppress with check=false)
+label dlOpen(std::initializer_list<fileName> libNames, const bool check=true);
 
 //- Close a dlopened library using handle. Return true if successful
 bool dlClose(void* handle);
diff --git a/tutorials/IO/systemCall/system/systemCall b/tutorials/IO/systemCall/system/systemCall
index f8d4debf5c7d628e1d1304c4318b17b060aa5b0e..91a9fe441f368bc325bbeba3c4f581cf73ebfffc 100644
--- a/tutorials/IO/systemCall/system/systemCall
+++ b/tutorials/IO/systemCall/system/systemCall
@@ -3,7 +3,7 @@
 system
 {
     type    systemCall;
-    libs    ("libutilityFunctionObjects.so");
+    libs    ("utilityFunctionObjects");
 
     // Execute on the master process only
     master  true;