--- a/config/PETSc/options/sharedLibraries.py
+++ b/config/PETSc/options/sharedLibraries.py
@@ -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')
--- a/gmakefile
+++ b/gmakefile
@@ -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)
@@ -149,7 +149,7 @@
 	$(if $(findstring win_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))
--- a/config/PETSc/Configure.py
+++ b/config/PETSc/Configure.py
@@ -80,6 +80,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)
@@ -93,6 +94,10 @@
     self.fortran       = framework.require('config.compilersFortran',   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')
 
@@ -158,6 +163,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:
@@ -426,10 +435,17 @@
           i.include = [i.include]
         includes.extend(i.include)
         self.addMakeMacro(i.PACKAGE.replace('-','_')+'_INCLUDE',self.headers.toStringNoDupes(i.include))
+    if self.sharedLibraries.petsclibExt:
+      self.petsclibExt=self.sharedLibraries.petsclibExt
     if self.framework.argDB['with-single-library']:
       self.petsclib = '-lpetsc'
     else:
       self.petsclib = '-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys'
+    if self.petsclibExt:
+      petsclibs = ''
+      for mylib in self.petsclib.split():
+        petsclibs += mylib+self.petsclibExt+' '
+      self.petsclib = petsclibs.strip()
     self.complibs = self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split()
     self.PETSC_WITH_EXTERNAL_LIB = self.libraries.toStringNoDupes(['-L${PETSC_DIR}/${PETSC_ARCH}/lib', self.petsclib]+self.packagelibs+self.complibs)
     self.PETSC_EXTERNAL_LIB_BASIC = self.libraries.toStringNoDupes(self.packagelibs+self.complibs)
@@ -448,15 +464,18 @@
       self.addMakeMacro('PETSC_FC_INCLUDES_INSTALL',self.headers.toStringNoDupes(allincludes_install,modinc(allincludes_install)))
 
     self.addDefine('LIB_DIR','"'+os.path.join(self.installdir.dir,'lib')+'"')
+    if self.petsclibExt:
+      self.addMakeMacro('PETSC_LIB_EXT',self.petsclibExt)
+      self.addDefine('LIB_EXT','"'+self.petsclibExt+'"')
 
     if self.framework.argDB['with-single-library']:
       # overrides the values set in conf/variables
-      self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}')
-      self.addMakeMacro('SHLIBS','libpetsc')
-      self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc')
-      self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc')
-      self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc')
-      self.addMakeMacro('PETSC_TAO_LIB_BASIC','-lpetsc')
+      self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc'+self.petsclibExt+'.${AR_LIB_SUFFIX}')
+      self.addMakeMacro('SHLIBS','libpetsc'+self.petsclibExt)
+      self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc'+self.petsclibExt)
+      self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc'+self.petsclibExt)
+      self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc'+self.petsclibExt)
+      self.addMakeMacro('PETSC_TAO_LIB_BASIC','-lpetsc'+self.petsclibExt)
       self.addMakeMacro('PETSC_WITH_EXTERNAL_LIB',self.PETSC_WITH_EXTERNAL_LIB)
       self.addDefine('USE_SINGLE_LIBRARY', '1')
       if self.sharedlibraries.useShared:
--- a/lib/petsc/conf/rules.doc
+++ b/lib/petsc/conf/rules.doc
@@ -17,7 +17,7 @@
 #
 # Note that EXAMPLESALL is only used in the tutorial directories and SOURCED only in the non-tutorials and tests directories
 #
-LIBNAME     = ${INSTALL_LIB_DIR}/${LIBBASE}.${AR_LIB_SUFFIX}
+LIBNAME     = ${INSTALL_LIB_DIR}/${LIBBASE}${PETSC_LIB_EXT}.${AR_LIB_SUFFIX}
 SOURCE      = `ls *.c *.cxx *.F *.F90 *.cu *.cpp           2> /dev/null`
 SOURCEALL   = `ls *.c *.cxx *.F *.F90 *.cu *.cpp *.h *.hpp 2> /dev/null`
 SOURCED     = `ls *.c *.cxx           *.cu *.cpp *.h *.hpp 2> /dev/null`
--- a/src/sys/dll/reg.c
+++ b/src/sys/dll/reg.c
@@ -21,12 +21,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));
   }
--- a/src/ksp/ksp/tutorials/ex1.c
+++ b/src/ksp/ksp/tutorials/ex1.c
@@ -173,6 +173,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
 
