Index: petsc/config/PETSc/options/sharedLibraries.py
===================================================================
--- petsc.orig/config/PETSc/options/sharedLibraries.py	2024-08-30 16:21:39.382407542 +0200
+++ petsc/config/PETSc/options/sharedLibraries.py	2024-08-30 16:21:39.370407445 +0200
@@ -7,16 +7,20 @@
     self.headerPrefix = ''
     self.substPrefix  = ''
     self.useShared    = 0
+    self.petsclibExt  = ''
     return
 
   def __str1__(self):
     txt =  '  Single library: %s\n' % ('yes' if self.framework.argDB['with-single-library'] else 'no')
     txt += '  Shared libraries: %s\n' % ('yes' if self.useShared else 'no')
+    if self.petsclibExt:
+      txt += '  shared library extension: ' + self.petsclibExt + '\n'
     return txt
 
   def setupHelp(self, help):
     import nargs
     help.addArgument('PETSc', '-with-shared-libraries=<bool>', nargs.ArgBool(None, 1, 'Make PETSc libraries shared -- libpetsc.so (Unix/Linux) or libpetsc.dylib (Mac)'))
+    help.addArgument('PETSc', '-shared-library-extension=<string>', nargs.Arg(None, None, 'Extension to name of shared library'))
     help.addArgument('PETSc', '-with-serialize-functions=<bool>', nargs.ArgBool(None, 0, 'Allows function pointers to be serialized to binary files with string representations'))
     return
 
@@ -62,6 +66,12 @@
       #else:
       #  self.addMakeRule('shared_arch','shared_'+self.arch.hostOsBase)
 
+      # define library extension at configure time with --shared-library-extension=<ext>
+      # This is added the shared library name and soname to allow for installation multiple configurations
+      # e.g. --shared-library-extension=Complex generates libpetscComplex.so instead of libpetsc.so
+      if 'shared-library-extension' in self.framework.argDB:
+        self.petsclibExt=self.framework.argDB['shared-library-extension']
+
       # Linux is the default
       if self.setCompilers.isDarwin(self.log):
         self.addMakeRule('shared_arch','shared_darwin')
Index: petsc/gmakefile
===================================================================
--- petsc.orig/gmakefile	2024-08-30 16:21:39.382407542 +0200
+++ petsc/gmakefile	2024-08-30 16:21:39.370407445 +0200
@@ -27,14 +27,14 @@
 absbasename_all = $(basename $(basename $(basename $(basename $(abspath $(1))))))# arch/lib/libpetsc.so.3.8.0 -> /path/to/arch/lib/libpetsc
 sl_linker_args = $(call SL_LINKER_FUNCTION,$(call absbasename_all,$@),$(libpetsc_abi_version),$(libpetsc_lib_version))
 
-libpetsc_shared  := $(LIBDIR)/libpetsc.$(SL_LINKER_SUFFIX)
-libpetsc_soname  := $(call soname_function,$(LIBDIR)/libpetsc)
-libpetsc_libname := $(call libname_function,$(LIBDIR)/libpetsc)
-libpetsc_static  := $(LIBDIR)/libpetsc.$(AR_LIB_SUFFIX)
-libpetscpkgs_shared  := $(foreach pkg, $(pkgs), $(LIBDIR)/libpetsc$(pkg).$(SL_LINKER_SUFFIX))
-libpetscpkgs_soname  := $(foreach pkg, $(pkgs), $(call soname_function,$(LIBDIR)/libpetsc$(pkg)))
-libpetscpkgs_libname := $(foreach pkg, $(pkgs), $(call libname_function,$(LIBDIR)/libpetsc$(pkg)))
-libpetscpkgs_static  := $(foreach pkg, $(pkgs), $(LIBDIR)/libpetsc$(pkg).$(AR_LIB_SUFFIX))
+libpetsc_shared  := $(LIBDIR)/libpetsc$(PETSC_LIB_EXT).$(SL_LINKER_SUFFIX)
+libpetsc_soname  := $(call soname_function,$(LIBDIR)/libpetsc$(PETSC_LIB_EXT))
+libpetsc_libname := $(call libname_function,$(LIBDIR)/libpetsc$(PETSC_LIB_EXT))
+libpetsc_static  := $(LIBDIR)/libpetsc$(PETSC_LIB_EXT).$(AR_LIB_SUFFIX)
+libpetscpkgs_shared  := $(foreach pkg, $(pkgs), $(LIBDIR)/libpetsc$(pkg)$(PETSC_LIB_EXT).$(SL_LINKER_SUFFIX))
+libpetscpkgs_soname  := $(foreach pkg, $(pkgs), $(call soname_function,$(LIBDIR)/libpetsc$(pkg)$(PETSC_LIB_EXT)))
+libpetscpkgs_libname := $(foreach pkg, $(pkgs), $(call libname_function,$(LIBDIR)/libpetsc$(pkg)$(PETSC_LIB_EXT)))
+libpetscpkgs_static  := $(foreach pkg, $(pkgs), $(LIBDIR)/libpetsc$(pkg)$(PETSC_LIB_EXT).$(AR_LIB_SUFFIX))
 
 ifeq ($(PETSC_WITH_EXTERNAL_LIB),)
   libpetscall_shared  := $(libpetscpkgs_shared)
@@ -151,7 +151,7 @@
 	$(if $(findstring win32fe_lib,$(AR)),$(ARCHIVE_RECIPE_WIN32FE_LIB),$(if $(findstring yes,$(AR_ARGFILE)),$(if $(GMAKE4),$(ARCHIVE_RECIPE_ARGFILE),$(ARCHIVE_RECIPE_DEFAULT)),$(ARCHIVE_RECIPE_DEFAULT)))
 
 # with-single-library=0
-libpkg = $(foreach pkg, $1, $(LIBDIR)/libpetsc$(pkg).$(SL_LINKER_SUFFIX))
+libpkg = $(foreach pkg, $1, $(LIBDIR)/libpetsc$(pkg)$(PETSC_LIB_EXT).$(SL_LINKER_SUFFIX))
 define pkg_template
   $(LIBDIR)/libpetsc$(1).$(AR_LIB_SUFFIX)  : $(call concatlang,$(1))
   $(call libname_function,$(LIBDIR)/libpetsc$(1)) : $(call concatlang,$(1))
Index: petsc/config/PETSc/Configure.py
===================================================================
--- petsc.orig/config/PETSc/Configure.py	2024-08-30 16:21:39.382407542 +0200
+++ petsc/config/PETSc/Configure.py	2024-08-30 16:21:39.370407445 +0200
@@ -82,6 +82,7 @@
     self.dataFilesPath = framework.require('PETSc.options.dataFilesPath',self)
     self.scalartypes   = framework.require('PETSc.options.scalarTypes', self)
     self.indexTypes    = framework.require('PETSc.options.indexTypes',  self)
+    self.sharedLibraries = framework.require('PETSc.options.sharedLibraries',  self)
     self.languages     = framework.require('PETSc.options.languages',   self.setCompilers)
     self.indexTypes    = framework.require('PETSc.options.indexTypes',  self.compilers)
     self.types         = framework.require('config.types',              self)
@@ -96,6 +97,10 @@
     self.ftncmdline    = framework.require('config.utilities.fortranCommandLine',self)
     self.externalpackagesdir = framework.require('PETSc.options.externalpackagesdir',self)
 
+    self.petsclibExt=''
+    if self.sharedLibraries.petsclibExt:
+      self.petsclibExt=self.sharedLibraries.petsclibExt
+
     for utility in sorted(os.listdir(os.path.join('config','PETSc','options'))):
       self.registerPythonFile(utility,'PETSc.options')
 
@@ -161,6 +166,10 @@
 
   def DumpPkgconfig(self, petsc_pc):
     ''' Create a pkg-config file '''
+
+    if self.sharedLibraries.petsclibExt:
+      self.petsclibExt=self.sharedLibraries.petsclibExt
+
     if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')):
       os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig'))
     with open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig',petsc_pc),'w') as fd:
@@ -448,17 +457,22 @@
       self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(allincludes,modinc(allincludes)))
       self.addMakeMacro('PETSC_FC_INCLUDES_INSTALL',self.headers.toStringNoDupes(allincludes_install,modinc(allincludes_install)))
 
+    self.petsclibExt = self.sharedLibraries.petsclibExt if self.sharedLibraries.petsclibExt else ''
+
     LIB_DIR = os.path.join(self.installdir.dir,'lib')
     self.addDefine('LIB_DIR','"'+LIB_DIR+'"')
     # Use build dir here for 'make check' to work before 'make install'
     PREINSTALL_LIB_DIR = os.path.join(self.petscdir.dir,self.arch.arch,'lib')
+    if self.petsclibExt:
+      self.addMakeMacro('PETSC_LIB_EXT',self.petsclibExt)
+      self.addDefine('LIB_EXT','"'+self.petsclibExt+'"')
 
     if self.framework.argDB['with-single-library']:
-      self.petsclib = '-lpetsc'
+      self.petsclib = f'-lpetsc{self.petsclibExt}'
       self.addDefine('USE_SINGLE_LIBRARY', '1')
-      self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}')
-      self.addMakeMacro('SHLIBS','libpetsc')
-      self.addMakeMacro('PETSC_WITH_EXTERNAL_LIB',self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR, '-lpetsc']+self.packagelibs+self.complibs))
+      self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc'+self.petsclibExt+'.${AR_LIB_SUFFIX}')
+      self.addMakeMacro('SHLIBS',f'libpetsc{self.petsclibExt}')
+      self.addMakeMacro('PETSC_WITH_EXTERNAL_LIB',self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR, f'-lpetsc{self.petsclibExt}']+self.packagelibs+self.complibs))
       self.addMakeMacro('PETSC_SYS_LIB','${PETSC_WITH_EXTERNAL_LIB}')
       self.addMakeMacro('PETSC_VEC_LIB','${PETSC_WITH_EXTERNAL_LIB}')
       self.addMakeMacro('PETSC_MAT_LIB','${PETSC_WITH_EXTERNAL_LIB}')
@@ -469,14 +483,19 @@
       self.addMakeMacro('PETSC_TAO_LIB','${PETSC_WITH_EXTERNAL_LIB}')
     else:
       self.petsclib = '-lpetsctao -lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys'
-      self.addMakeMacro('PETSC_SYS_LIB', self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,'-lpetscsys']+self.packagelibs+self.complibs))
-      self.addMakeMacro('PETSC_VEC_LIB', self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,'-lpetscvec','-lpetscsys']+self.packagelibs+self.complibs))
-      self.addMakeMacro('PETSC_MAT_LIB', self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,'-lpetscmat','-lpetscvec','-lpetscsys']+self.packagelibs+self.complibs))
-      self.addMakeMacro('PETSC_DM_LIB',  self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,'-lpetscdm','-lpetscmat','-lpetscvec','-lpetscsys']+self.packagelibs+self.complibs))
-      self.addMakeMacro('PETSC_KSP_LIB', self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,'-lpetscksp','-lpetscdm','-lpetscmat','-lpetscvec','-lpetscsys']+self.packagelibs+self.complibs))
-      self.addMakeMacro('PETSC_SNES_LIB',self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,'-lpetscsnes','-lpetscksp','-lpetscdm','-lpetscmat','-lpetscvec','-lpetscsys']+self.packagelibs+self.complibs))
-      self.addMakeMacro('PETSC_TS_LIB',  self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,'-lpetscts','-lpetscsnes','-lpetscksp','-lpetscdm','-lpetscmat','-lpetscvec','-lpetscsys']+self.packagelibs+self.complibs))
-      self.addMakeMacro('PETSC_TAO_LIB', self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,'-lpetsctao','-lpetscts','-lpetscsnes','-lpetscksp','-lpetscdm','-lpetscmat','-lpetscvec','-lpetscsys']+self.packagelibs+self.complibs))
+      if self.petsclibExt:
+        petsclibs = ''
+        for mylib in self.petsclib.split():
+          petsclibs += mylib+self.petsclibExt+' '
+        self.petsclib = petsclibs.strip()
+      self.addMakeMacro('PETSC_SYS_LIB', self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,f'-lpetscsys{self.petsclibExt}']+self.packagelibs+self.complibs))
+      self.addMakeMacro('PETSC_VEC_LIB', self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,f'-lpetscvec{self.petsclibExt}',f'-lpetscsys{self.petsclibExt}']+self.packagelibs+self.complibs))
+      self.addMakeMacro('PETSC_MAT_LIB', self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,f'-lpetscmat{self.petsclibExt}',f'-lpetscvec{self.petsclibExt}',f'-lpetscsys{self.petsclibExt}']+self.packagelibs+self.complibs))
+      self.addMakeMacro('PETSC_DM_LIB',  self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,f'-lpetscdm{self.petsclibExt}',f'-lpetscmat{self.petsclibExt}{self.petsclibExt}',f'-lpetscvec{self.petsclibExt}',f'-lpetscsys{self.petsclibExt}']+self.packagelibs+self.complibs))
+      self.addMakeMacro('PETSC_KSP_LIB', self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,f'-lpetscksp{self.petsclibExt}{self.petsclibExt}',f'-lpetscdm{self.petsclibExt}',f'-lpetscmat{self.petsclibExt}',f'-lpetscvec{self.petsclibExt}',f'-lpetscsys{self.petsclibExt}']+self.packagelibs+self.complibs))
+      self.addMakeMacro('PETSC_SNES_LIB',self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,f'-lpetscsnes{self.petsclibExt}{self.petsclibExt}',f'-lpetscksp{self.petsclibExt}',f'-lpetscdm{self.petsclibExt}',f'-lpetscmat{self.petsclibExt}',f'-lpetscvec{self.petsclibExt}',f'-lpetscsys{self.petsclibExt}']+self.packagelibs+self.complibs))
+      self.addMakeMacro('PETSC_TS_LIB',  self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,f'-lpetscts{self.petsclibExt}{self.petsclibExt}',f'-lpetscsnes{self.petsclibExt}',f'-lpetscksp{self.petsclibExt}',f'-lpetscdm{self.petsclibExt}',f'-lpetscmat{self.petsclibExt}',f'-lpetscvec{self.petsclibExt}',f'-lpetscsys{self.petsclibExt}']+self.packagelibs+self.complibs))
+      self.addMakeMacro('PETSC_TAO_LIB', self.libraries.toStringNoDupes(['-L'+PREINSTALL_LIB_DIR,f'-lpetsctao{self.petsclibExt}{self.petsclibExt}',f'-lpetscts{self.petsclibExt}',f'-lpetscsnes{self.petsclibExt}',f'-lpetscksp{self.petsclibExt}',f'-lpetscdm{self.petsclibExt}',f'-lpetscmat{self.petsclibExt}',f'-lpetscvec{self.petsclibExt}',f'-lpetscsys{self.petsclibExt}']+self.packagelibs+self.complibs))
     self.addMakeMacro('PETSC_LIB','${PETSC_TAO_LIB}')
     self.addMakeMacro('PETSC_LIB_BASIC',self.petsclib)
 
Index: petsc/src/sys/dll/reg.c
===================================================================
--- petsc.orig/src/sys/dll/reg.c	2024-08-30 16:21:39.382407542 +0200
+++ petsc/src/sys/dll/reg.c	2024-08-30 16:21:39.370407445 +0200
@@ -20,12 +20,18 @@
   PetscFunctionBegin;
   PetscCall(PetscStrncpy(libs, "${PETSC_LIB_DIR}/libpetsc", sizeof(libs)));
   PetscCall(PetscStrlcat(libs, name, sizeof(libs)));
+  #if defined(PETSC_LIB_EXT)
+  PetscCall(PetscStrlcat(libs, PETSC_LIB_EXT, sizeof(libs)));
+  #endif
   PetscCall(PetscDLLibraryRetrieve(PETSC_COMM_WORLD, libs, dlib, 1024, found));
   if (*found) {
     PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, dlib));
   } else {
     PetscCall(PetscStrncpy(libs, "${PETSC_DIR}/${PETSC_ARCH}/lib/libpetsc", sizeof(libs)));
     PetscCall(PetscStrlcat(libs, name, sizeof(libs)));
+    #if defined(PETSC_LIB_EXT)
+    PetscCall(PetscStrlcat(libs, PETSC_LIB_EXT, sizeof(libs)));
+    #endif
     PetscCall(PetscDLLibraryRetrieve(PETSC_COMM_WORLD, libs, dlib, 1024, found));
     if (*found) PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, dlib));
   }
Index: petsc/src/ksp/ksp/tutorials/ex1.c
===================================================================
--- petsc.orig/src/ksp/ksp/tutorials/ex1.c	2024-08-30 16:21:39.382407542 +0200
+++ petsc/src/ksp/ksp/tutorials/ex1.c	2024-08-30 16:21:39.374407478 +0200
@@ -178,6 +178,10 @@
       args: -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always
 
    test:
+      suffix: library_preload
+      args: -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always -library_preload
+
+   test:
       suffix: 2
       args: -pc_type sor -pc_sor_symmetric -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always
 
