Removed all of the routines that generate compiled libraries from
individual files for various file formats (GDS, LEF, SPICE/CDL,
and verilog (liberty is unfinished and probably never will be), and
put the in individual files that can be either run separately from
the command line or included into the foundry_install.py script and
run internally.
diff --git a/common/create_gds_library.py b/common/create_gds_library.py
new file mode 100755
index 0000000..23b7553
--- /dev/null
+++ b/common/create_gds_library.py
@@ -0,0 +1,209 @@
+#!/usr/bin/env python3
+#
+# create_gds_library.py
+#
+#----------------------------------------------------------------------------
+# Given a destination directory holding individual GDS files of a number
+# of cells, create a single GDL library file named <alllibname> and place
+# it in the same directory.  This is done for the option "compile" if specified
+# for the "-gds" install.
+#----------------------------------------------------------------------------
+
+import os
+import sys
+import glob
+import fnmatch
+import subprocess
+
+#----------------------------------------------------------------------------
+
+def usage():
+    print('')
+    print('Usage:')
+    print('    create_gds_library <destlibdir> <destlib> <startup_script> ')
+    print('             [-compile-only] [-excludelist="file1,file2,..."] [-keep]')
+    print('')
+    print('Create a single GDS library from a set of individual GDS files.')
+    print('')
+    print('where:')
+    print('    <destlibdir>      is the directory containing the individual GDS files')
+    print('    <destlib>         is the root name of the library file')
+    print('    <startup_script>  is the full path to a magic startup script')
+    print('    -compile-only     removes the indidual files if specified')
+    print('    -excludelist=     is a comma-separated list of files to ignore')
+    print('    -keep             keep the Tcl script used to generate the library')
+    print('')
+
+#----------------------------------------------------------------------------
+
+def create_gds_library(destlibdir, destlib, startup_script, do_compile_only, excludelist, keep):
+
+    alllibname = destlibdir + '/' + destlib + '.gds'
+    if os.path.isfile(alllibname):
+        os.remove(alllibname)
+
+    glist = glob.glob(destlibdir + '/*.gds')
+    glist.extend(glob.glob(destlibdir + '/*.gdsii'))
+    glist.extend(glob.glob(destlibdir + '/*.gds2'))
+    if alllibname in glist:
+        glist.remove(alllibname)
+
+    # Create exclude list with glob-style matching using fnmatch
+    if len(glist) > 0:
+        glistnames = list(os.path.split(item)[1] for item in glist)
+        notglist = []
+        for exclude in excludelist:
+            notglist.extend(fnmatch.filter(glistnames, exclude))
+
+        # Apply exclude list
+        if len(notglist) > 0:
+            for file in glist[:]:
+                if os.path.split(file)[1] in notglist:
+                    glist.remove(file)
+
+    if len(glist) > 1:
+        print('New file is:  ' + alllibname)
+
+        if os.path.isfile(startup_script):
+            # If the symbolic link exists, remove it.
+            if os.path.isfile(destlibdir + '/.magicrc'):
+                os.remove(destlibdir + '/.magicrc')
+            os.symlink(startup_script, destlibdir + '/.magicrc')
+
+        # A GDS library is binary and requires handling in Magic
+        print('Creating magic generation script to generate GDS library.') 
+        with open(destlibdir + '/generate_magic.tcl', 'w') as ofile:
+            print('#!/usr/bin/env wish', file=ofile)
+            print('#--------------------------------------------', file=ofile)
+            print('# Script to generate .gds library from files   ', file=ofile)
+            print('#--------------------------------------------', file=ofile)
+            print('drc off', file=ofile)
+            print('gds readonly true', file=ofile)
+            print('gds flatten true', file=ofile)
+            print('gds rescale false', file=ofile)
+            print('tech unlock *', file=ofile)
+
+            for gdsfile in glist:
+                print('gds read ' + gdsfile, file=ofile)
+
+            print('puts stdout "Creating cell ' + destlib + '"', file=ofile)
+            print('load ' + destlib, file=ofile)
+            print('puts stdout "Adding cells to library"', file=ofile)
+            print('box values 0 0 0 0', file=ofile)
+            for gdsfile in glist:
+                gdsroot = os.path.split(gdsfile)[1]
+                gdsname = os.path.splitext(gdsroot)[0]
+                print('getcell ' + gdsname, file=ofile)
+                # Could properly make space for the cell here. . . 
+                print('box move e 200', file=ofile)
+                                
+            print('puts stdout "Writing GDS library ' + destlib + '"', file=ofile)
+            print('gds library true', file=ofile)
+            print('gds write ' + destlib, file=ofile)
+            print('puts stdout "Done."', file=ofile)
+            print('quit -noprompt', file=ofile)
+
+        # Run magic to read in the individual GDS files and
+        # write out the consolidated GDS library
+
+        print('Running magic to create GDS library.')
+        sys.stdout.flush()
+
+        mproc = subprocess.run(['magic', '-dnull', '-noconsole',
+			destlibdir + '/generate_magic.tcl'],
+			stdin = subprocess.DEVNULL,
+			stdout = subprocess.PIPE,
+			stderr = subprocess.PIPE, cwd = destlibdir,
+			universal_newlines = True)
+
+        if mproc.stdout:
+            for line in mproc.stdout.splitlines():
+                print(line)
+        if mproc.stderr:
+            print('Error message output from magic:')
+            for line in mproc.stderr.splitlines():
+                print(line)
+        if mproc.returncode != 0:
+            print('ERROR:  Magic exited with status ' + str(mproc.returncode))
+        if do_compile_only == True:
+            print('Compile-only:  Removing individual GDS files')
+            for gfile in glist:
+                if os.path.isfile(gfile):
+                    os.remove(gfile)
+            if newname:
+                if os.path.isfile(newname):
+                    os.remove(newname)
+        if not keep:
+            os.remove(destlibdir + '/generate_magic.tcl')
+    else:
+        print('Only one file (' + str(glist) + ');  ignoring "compile" option.')
+
+#----------------------------------------------------------------------------
+
+if __name__ == '__main__':
+
+    if len(sys.argv) == 1:
+        usage()
+        sys.exit(0)
+
+    argumentlist = []
+
+    # Defaults
+    do_compile_only = False
+    keep = False
+    excludelist = []
+
+    # Break arguments into groups where the first word begins with "-".
+    # All following words not beginning with "-" are appended to the
+    # same list (optionlist).  Then each optionlist is processed.
+    # Note that the first entry in optionlist has the '-' removed.
+
+    for option in sys.argv[1:]:
+        if option.find('-', 0) == 0:
+            keyval = option[1:].split('=')
+            if keyval[0] == 'compile-only':
+                if len(keyval) > 0:
+                    if keyval[1].tolower() == 'true' or keyval[1] == 'yes' or keyval[1] == '1':
+                        do_compile_only = True
+                else:
+                    do_compile_only = True
+            elif keyval[1] == 'exclude' or key == 'excludelist':
+                if len(keyval) > 0:
+                    excludelist = keyval[1].trim('"').split(',')
+                else:
+                    print("No items in exclude list (ignoring).")
+            elif keyval[1] == 'keep':
+                keep = True
+            else:
+                print("Unknown option '" + keyval[0] + "' (ignoring).")
+        else:
+            argumentlist.append(option)
+
+    if len(argumentlist) < 3: 
+        print("Not enough arguments given to create_gds_library.py.")
+        usage()
+        sys.exit(1)
+
+    destlibdir = argumentlist[0]
+    destlib = argumentlist[1]
+    startup_script = argumentlist[2]
+
+    print('')
+    print('Create GDS library from files:')
+    print('')
+    print('Path to files: ' + destlibdir)
+    print('Name of compiled library: ' + destlib + '.gds')
+    print('Path to magic startup script: ' + startup_script)
+    print('Remove individual files: ' + 'Yes' if do_compile_only else 'No')
+    if len(excludelist) > 0:
+        print('List of files to exclude: ')
+        for file in excludelist:
+            print(file)
+    print('Keep generating script: ' + 'Yes' if keep else 'No')
+    print('')
+
+    create_gds_library(destlibdir, destlib, startup_script, do_compile_only, excludelist, keep)
+    print('Done.')
+    sys.exit(0)
+
+#----------------------------------------------------------------------------
diff --git a/common/create_lef_library.py b/common/create_lef_library.py
new file mode 100755
index 0000000..2b76f9a
--- /dev/null
+++ b/common/create_lef_library.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python3
+#
+# create_lef_library.py
+#
+#----------------------------------------------------------------------------
+# Given a destination directory holding individual LEF files of a number
+# of cells, create a single LEF library file named <alllibname> and place
+# it in the same directory.  This is done for the option "compile" if specified
+# for the "-lef" install.
+#----------------------------------------------------------------------------
+
+import sys
+import os
+import glob
+import fnmatch
+
+def usage():
+    print('')
+    print('Usage:')
+    print('    create_lef_library <destlibdir> <destlib> [-compile-only]')
+    print('            [-excludelist="file1,file2,..."]')
+    print('')
+    print('Create a single LEF library from a set of individual LEF files.')
+    print('')
+    print('where:')
+    print('    <destlibdir>      is the directory containing the individual LEF files')
+    print('    <destlib>         is the root name of the library file')
+    print('    -compile-only     remove the indidual files if specified')
+    print('    -excludelist=     is a comma-separated list of files to ignore')
+    print('')
+
+def create_lef_library(destlibdir, destlib, do_compile_only, excludelist):
+
+    alllibname = destlibdir + '/' + destlib + '.lef'
+    if os.path.isfile(alllibname):
+        os.remove(alllibname)
+
+    print('Diagnostic:  Creating consolidated LEF library ' + destlib + '.lef')
+    llist = glob.glob(destlibdir + '/*.lef')
+    if alllibname in llist:
+        llist.remove(alllibname)
+
+    # Create exclude list with glob-style matching using fnmatch
+    if len(llist) > 0:
+        llistnames = list(os.path.split(item)[1] for item in llist)
+        notllist = []
+        for exclude in excludelist:
+            notllist.extend(fnmatch.filter(llistnames, exclude))
+
+        # Apply exclude list
+        if len(notllist) > 0:
+            for file in llist[:]:
+                if os.path.split(file)[1] in notllist:
+                    llist.remove(file)
+
+    if len(llist) > 1:
+        print('New file is:  ' + alllibname)
+        with open(alllibname, 'w') as ofile:
+            headerdone = False
+            for lfile in llist:
+                with open(lfile, 'r') as ifile:
+                    # print('Adding ' + lfile + ' to library.')
+                    ltext = ifile.read()
+                    llines = ltext.splitlines()
+                    headerseen = False
+                    for lline in llines:
+                        if headerdone:
+                            if not headerseen:
+                                if not lline.startswith('MACRO'):
+                                    continue
+                                else:
+                                    headerseen = True
+                        ltok = lline.split()
+                        if ltok[0] == 'END' and ltok[1] == 'LIBRARY':
+                            # Remove "END LIBRARY" line from individual files
+                            pass
+                        else:
+                            print(lline, file=ofile)
+                    headerdone = True
+                print('#--------EOF---------\n', file=ofile)
+
+        if do_compile_only == True:
+            print('Compile-only:  Removing individual LEF files')
+            for lfile in llist:
+                if os.path.isfile(lfile):
+                    os.remove(lfile)
+            if newname:
+                if os.path.isfile(newname):
+                    os.remove(newname)
+    else:
+        print('Only one file (' + str(llist) + ');  ignoring "compile" option.')
+
+#----------------------------------------------------------------------------
+
+if __name__ == '__main__':
+
+    if len(sys.argv) == 1:
+        usage()
+        sys.exit(0)
+
+    argumentlist = []
+
+    # Defaults
+    do_compile_only = False
+    excludelist = []
+
+    # Break arguments into groups where the first word begins with "-".
+    # All following words not beginning with "-" are appended to the
+    # same list (optionlist).  Then each optionlist is processed.
+    # Note that the first entry in optionlist has the '-' removed.
+
+    for option in sys.argv[1:]:
+        if option.find('-', 0) == 0:
+            keyval = option[1:].split('=')
+            if keyval[0] == 'compile-only':
+                if len(keyval) > 0:
+                    if keyval[1].tolower() == 'true' or keyval[1] == 'yes' or keyval[1] == '1':
+                        do_compile_only = True
+                else:
+                    do_compile_only = True
+            elif keyval[1] == 'exclude' or key == 'excludelist':
+                if len(keyval) > 0:
+                    excludelist = keyval[1].trim('"').split(',')
+                else:
+                    print("No items in exclude list (ignoring).")
+            else:
+                print("Unknown option '" + keyval[0] + "' (ignoring).")
+        else:
+            argumentlist.append(option)
+
+    if len(argumentlist) < 2: 
+        print("Not enough arguments given to create_lef_library.py.")
+        usage()
+        sys.exit(1)
+
+    destlibdir = argumentlist[0]
+    destlib = argumentlist[1]
+
+    print('')
+    print('Create LEF library from files:')
+    print('')
+    print('Path to files: ' + destlibdir)
+    print('Name of compiled library: ' + destlib + '.lef')
+    print('Remove individual files: ' + 'Yes' if do_compile_only else 'No')
+    if len(excludelist) > 0:
+        print('List of files to exclude: ')
+        for file in excludelist:
+            print(file)
+    print('')
+
+    create_lef_library(destlibdir, destlib, do_compile_only, excludelist)
+    print('Done.')
+    sys.exit(0)
+
+#----------------------------------------------------------------------------
diff --git a/common/create_lib_library.py b/common/create_lib_library.py
new file mode 100755
index 0000000..8f9a39f
--- /dev/null
+++ b/common/create_lib_library.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python3
+#
+# create_lib_library.py
+#
+#----------------------------------------------------------------------------
+# Given a destination directory holding individual liberty files of a number
+# of cells, create a single liberty library file named <alllibname> and place
+# it in the same directory.  This is done for the option "compile" if specified
+# for the "-lib" install.
+#----------------------------------------------------------------------------
+
+import sys
+import os
+import glob
+import fnmatch
+
+def usage():
+    print('')
+    print('Usage:')
+    print('    create_lib_library <destlibdir> <destlib> [-compile-only] ')
+    print('             [-excludelist="file1,file2,..."]')
+    print('')
+    print('Create a single liberty library from a set of individual liberty files.')
+    print('')
+    print('where:')
+    print('    <destlibdir>      is the directory containing the individual liberty files')
+    print('    <destlib>         is the root name of the library file')
+    print('    -compile-only     remove the indidual files if specified')
+    print('    -excludelist=     is a comma-separated list of files to ignore')
+    print('')
+
+# Warning:  This script is unfinished.  Needs to parse the library header
+# in each cell and generate a new library header combining the contents of
+# all cell headers.  Also:  The library name in the header needs to be
+# changed to the full library name.  Also:  There is no mechanism for
+# collecting all files belonging to a single process corner/temperature/
+# voltage.
+
+def create_lib_library(destlibdir, destlib, do_compile_only, excludelist):
+
+    alllibname = destlibdir + '/' + destlib + '.lib'
+    if os.path.isfile(alllibname):
+        os.remove(alllibname)
+
+    print('Diagnostic:  Creating consolidated liberty library ' + destlib + '.lib')
+
+    # Create exclude list with glob-style matching using fnmatch
+    if len(llist) > 0:
+        llistnames = list(os.path.split(item)[1] for item in llist)
+        notllist = []
+        for exclude in excludelist:
+            notllist.extend(fnmatch.filter(llistnames, exclude))
+
+        # Apply exclude list
+        if len(notllist) > 0:
+            for file in llist[:]:
+                if os.path.split(file)[1] in notllist:
+                    llist.remove(file)
+
+    if len(llist) > 1:
+        print('New file is:  ' + alllibname)
+        with open(alllibname, 'w') as ofile:
+            headerdone = False
+            for lfile in llist:
+                with open(lfile, 'r') as ifile:
+                    # print('Adding ' + lfile + ' to library.')
+                    ltext = ifile.read()
+                    llines = ltext.splitlines()
+                    headerseen = False
+                    for lline in llines:
+                        if headerdone:
+                            if not headerseen:
+                                if not lline.split()[0] == 'cell':
+                                    continue
+                                else:
+                                    headerseen = True
+                        print(lline, file=ofile)
+                    headerdone = True
+                print('/*--------EOF---------*/\n', file=ofile)
+
+        if do_compile_only == True:
+            print('Compile-only:  Removing individual LEF files')
+            for lfile in llist:
+                if os.path.isfile(lfile):
+                    os.remove(lfile)
+            if newname:
+                if os.path.isfile(newname):
+                    os.remove(newname)
+    else:
+        print('Only one file (' + str(llist) + ');  ignoring "compile" option.')
+
+#----------------------------------------------------------------------------
+
+if __name__ == '__main__':
+
+    if len(sys.argv) == 1:
+        usage()
+        sys.exit(0)
+
+    argumentlist = []
+
+    # Defaults
+    do_compile_only = False
+    excludelist = []
+
+    # Break arguments into groups where the first word begins with "-".
+    # All following words not beginning with "-" are appended to the
+    # same list (optionlist).  Then each optionlist is processed.
+    # Note that the first entry in optionlist has the '-' removed.
+
+    for option in sys.argv[1:]:
+        if option.find('-', 0) == 0:
+            keyval = option[1:].split('=')
+            if keyval[0] == 'compile-only':
+                if len(keyval) > 0:
+                    if keyval[1].tolower() == 'true' or keyval[1] == 'yes' or keyval[1] == '1':
+                        do_compile_only = True
+                else:
+                    do_compile_only = True
+            elif keyval[1] == 'exclude' or key == 'excludelist':
+                if len(keyval) > 0:
+                    excludelist = keyval[1].trim('"').split(',')
+                else:
+                    print("No items in exclude list (ignoring).")
+            else:
+                print("Unknown option '" + keyval[0] + "' (ignoring).")
+        else:
+            argumentlist.append(option)
+
+    if len(argumentlist) < 3: 
+        print("Not enough arguments given to create_lib_library.py.")
+        usage()
+        sys.exit(1)
+
+    destlibdir = argumentlist[0]
+    destlib = argumentlist[1]
+    startup_script = argumentlist[2]
+
+    print('')
+    print('Create liberty library from files:')
+    print('')
+    print('Path to files: ' + destlibdir)
+    print('Name of compiled library: ' + destlib + '.lib')
+    print('Remove individual files: ' + 'Yes' if do_compile_only else 'No')
+    if len(excludelist) > 0:
+        print('List of files to exclude: ')
+        for file in excludelist:
+            print(file)
+    print('')
+
+    create_lib_library(destlibdir, destlib, do_compile_only, excludelist)
+    print('Done.')
+    sys.exit(0)
+
+#----------------------------------------------------------------------------
diff --git a/common/create_spice_library.py b/common/create_spice_library.py
new file mode 100755
index 0000000..6b8aa83
--- /dev/null
+++ b/common/create_spice_library.py
@@ -0,0 +1,213 @@
+#!/usr/bin/env python3
+#
+# create_spice_library.py
+#
+#----------------------------------------------------------------------------
+# Given a destination directory holding individual SPICE netlists of a number
+# of cells, create a single SPICE library file named <alllibname> and place
+# it in the same directory.  This is done for the option "compile" if specified
+# for the "-spice" install.
+#----------------------------------------------------------------------------
+
+import sys
+import os
+import re
+import glob
+import fnmatch
+
+#----------------------------------------------------------------------------
+
+def usage():
+    print('')
+    print('Usage:')
+    print('    create_spice_library <destlibdir> <destlib> <spiext>')
+    print('            [-compile-only] [-stub] [-excludelist="file1,file2,..."]')
+    print('')
+    print('Create a single SPICE or CDL library from a set of individual files.')
+    print('')
+    print('where:')
+    print('    <destlibdir>      is the directory containing the individual files')
+    print('    <destlib>         is the root name of the library file')
+    print('    <spiext>          is the extension used (with ".") by the SPICE or CDL files')
+    print('    -compile-only     remove the indidual files if specified')
+    print('    -stub             generate only .subckt ... .ends for each cell')
+    print('    -excludelist=     is a comma-separated list of files to ignore')
+    print('')
+
+#----------------------------------------------------------------------------
+
+def create_spice_library(destlibdir, destlib, spiext, do_compile_only, do_stub, excludelist):
+
+    fformat = 'CDL' if spiext == '.cdl' else 'SPICE'
+
+    allstubname = destlibdir + '/stub' + spiext
+    alllibname = destlibdir + '/' + destlib + spiext
+    if do_stub:
+        outputname = allstubname
+    else:
+        outputname = alllibname
+
+    print('Diagnostic:  Creating consolidated ' + fformat + ' library ' + outputname)
+
+    if os.path.isfile(outputname):
+        os.remove(outputname)
+
+    if fformat == 'CDL':
+        slist = glob.glob(destlibdir + '/*.cdl')
+    else:
+        # Sadly, there is no consensus on what a SPICE file extension should be.
+        slist = glob.glob(destlibdir + '/*.spc')
+        slist.extend(glob.glob(destlibdir + '/*.spice'))
+        slist.extend(glob.glob(destlibdir + '/*.spi'))
+        slist.extend(glob.glob(destlibdir + '/*.ckt'))
+        slist.extend(glob.glob(destlibdir + '/*.cir'))
+        slist.extend(glob.glob(destlibdir + '/*' + spiext))
+
+    if alllibname in slist:
+        slist.remove(alllibname)
+
+    if allstubname in slist:
+        slist.remove(allstubname)
+
+    # Create exclude list with glob-style matching using fnmatch
+    if len(slist) > 0:
+        slistnames = list(os.path.split(item)[1] for item in slist)
+        notslist = []
+        for exclude in excludelist:
+            notslist.extend(fnmatch.filter(slistnames, exclude))
+
+        # Apply exclude list
+        if len(notslist) > 0:
+            for file in slist[:]:
+                if os.path.split(file)[1] in notslist:
+                    slist.remove(file)
+
+    if len(slist) > 1:
+        with open(outputname, 'w') as ofile:
+            allsubckts = []
+            for sfile in slist:
+                with open(sfile, 'r') as ifile:
+                    # print('Adding ' + sfile + ' to library.')
+                    stext = ifile.read()
+                    subckts = re.findall(r'\.subckt[ \t]+([^ \t\n]+)', stext, flags=re.IGNORECASE)
+                    sseen = list(item for item in subckts if item in allsubckts)
+                    allsubckts.extend(list(item for item in subckts if item not in allsubckts))
+                    sfilter = remove_redundant_subckts(stext, allsubckts, sseen)
+                    print(sfilter, file=ofile)
+                print('\n******* EOF\n', file=ofile)
+
+        if do_compile_only == True:
+            print('Compile-only:  Removing individual SPICE files')
+            for sfile in slist:
+                if os.path.isfile(sfile):
+                    os.remove(sfile)
+                elif os.path.islink(sfile):
+                    os.unlink(sfile)
+    else:
+        print('Only one file (' + str(slist) + ');  ignoring "compile" option.')
+
+#----------------------------------------------------------------------------
+# Remove redundant subcircuit entries from a SPICE or CDL netlist file.  "sseen"
+# is a list of subcircuit names gleaned from all previously read files using
+# re.findall(). "slist" is a list of subcircuits including those in "ntext".
+# If a subcircuit is defined outside of "ntext", then remove all occurrences in
+# "ntext".  Otherwise, if a subcircuit is defined more than once in "ntext",
+# remove all but one copy.  The reason for doing this is that some netlists will
+# include primitive device definitions used by all the standard cell subcircuits.
+#
+# It may be necessary to remove redundant .include statements and redundant .model
+# and/or .option statements as well.
+#----------------------------------------------------------------------------
+
+def remove_redundant_subckts(ntext, slist, sseen):
+    updated = ntext
+    for subckt in slist:
+        if subckt in sseen:
+            # Remove all occurrences of subckt
+            updated = re.sub(r'\n\.subckt[ \t]+' + subckt + '[ \t\n]+.*\n\.ends[ \t\n]+', '\n', updated, flags=re.IGNORECASE | re.DOTALL)
+
+        else:
+            # Determine the number of times the subcircuit appears in the text
+            n = len(re.findall(r'\n\.subckt[ \t]+' + subckt + '[ \t\n]+.*\n\.ends[ \t\n]+', updated, flags=re.IGNORECASE | re.DOTALL))
+            # Optimization:  Just keep original text if n < 2
+            if n < 2:
+                continue
+
+            # Remove all but one
+            updated = re.sub(r'\n\.subckt[ \t]+' + subckt + '[ \t\n]+.*\n\.ends[ \t\n]+', '\n', n - 1, updated, flags=re.IGNORECASE | re.DOTALL)
+    return updated
+
+#----------------------------------------------------------------------------
+
+if __name__ == '__main__':
+
+    if len(sys.argv) == 1:
+        usage()
+        sys.exit(0)
+
+    argumentlist = []
+
+    # Defaults
+    do_compile_only = False
+    do_stub = False
+    excludelist = []
+
+    # Break arguments into groups where the first word begins with "-".
+    # All following words not beginning with "-" are appended to the
+    # same list (optionlist).  Then each optionlist is processed.
+    # Note that the first entry in optionlist has the '-' removed.
+
+    for option in sys.argv[1:]:
+        if option.find('-', 0) == 0:
+            keyval = option[1:].split('=')
+            if keyval[0] == 'compile-only':
+                if len(keyval) > 0:
+                    if keyval[1].tolower() == 'true' or keyval[1].tolower() == 'yes' or keyval[1] == '1':
+                        do_compile_only = True
+                else:
+                    do_compile_only = True
+            elif keyval[1] == 'exclude' or key == 'excludelist':
+                if len(keyval) > 0:
+                    excludelist = keyval[1].trim('"').split(',')
+                else:
+                    print("No items in exclude list (ignoring).")
+            elif keyval[1] == 'stub':
+                if len(keyval) > 0:
+                    if keyval[1].tolower() == 'true' or keyval[1].tolower() == 'yes' or keyval[1] == '1':
+                        do_stub = True
+                else:
+                    do_stub = True
+            else:
+                print("Unknown option '" + keyval[0] + "' (ignoring).")
+        else:
+            argumentlist.append(option)
+
+    if len(argumentlist) < 3: 
+        print("Not enough arguments given to create_spice_library.py.")
+        usage()
+        sys.exit(1)
+
+    destlibdir = argumentlist[0]
+    destlib = argumentlist[1]
+    startup_script = argumentlist[2]
+
+    print('')
+    if spiext == '.cdl':
+        print('Create CDL library from files:')
+    else:
+        print('Create SPICE library from files:')
+    print('')
+    print('Path to files: ' + destlibdir)
+    print('Name of compiled library: ' + destlib + spiext)
+    print('Remove individual files: ' + 'Yes' if do_compile_only else 'No')
+    if len(excludelist) > 0:
+        print('List of files to exclude: ')
+        for file in excludelist:
+            print(file)
+    print('')
+
+    create_spice_library(destlibdir, destlib, spiext, do_compile_only, do_stub, excludelist)
+    print('Done.')
+    sys.exit(0)
+
+#----------------------------------------------------------------------------
diff --git a/common/create_verilog_library.py b/common/create_verilog_library.py
new file mode 100755
index 0000000..d8565f4
--- /dev/null
+++ b/common/create_verilog_library.py
@@ -0,0 +1,190 @@
+#!/usr/bin/env python3
+#
+# create_verilog_library.py
+#
+#----------------------------------------------------------------------------
+# Given a destination directory holding individual verilog files of a number
+# of modules, create a single verilog library file named <alllibname> and place
+# it in the same directory.  This is done for the option "compile" if specified
+# for the "-verilog" install.
+#----------------------------------------------------------------------------
+
+import sys
+import os
+import re
+import glob
+import fnmatch
+
+#----------------------------------------------------------------------------
+
+def usage():
+    print('')
+    print('Usage:')
+    print('    create_verilog_library <destlibdir> <destlib> [-compile-only]')
+    print('            [-stub] [-excludelist="file1,file2,..."]')
+    print('')
+    print('Create a single verilog library from a set of individual verilog files.')
+    print('')
+    print('where:')
+    print('    <destlibdir>      is the directory containing the individual files')
+    print('    <destlib>         is the root name of the library file')
+    print('    -compile-only     remove the indidual files if specified')
+    print('    -stub             generate only the module headers for each cell')
+    print('    -excludelist=     is a comma-separated list of files to ignore')
+    print('')
+
+#----------------------------------------------------------------------------
+
+def create_verilog_library(destlibdir, destlib, do_compile_only, do_stub, excludelist):
+
+    alllibname = destlibdir + '/' + destlib + '.v'
+    if os.path.isfile(alllibname):
+        os.remove(alllibname)
+
+    print('Diagnostic:  Creating consolidated verilog library ' + destlib + '.v')
+    vlist = glob.glob(destlibdir + '/*.v')
+    if alllibname in vlist:
+        vlist.remove(alllibname)
+
+    # Create exclude list with glob-style matching using fnmatch
+    if len(vlist) > 0:
+        vlistnames = list(os.path.split(item)[1] for item in vlist)
+        notvlist = []
+        for exclude in excludelist:
+            notvlist.extend(fnmatch.filter(vlistnames, exclude))
+
+        # Apply exclude list
+        if len(notvlist) > 0:
+            for file in vlist[:]:
+                if os.path.split(file)[1] in notvlist:
+                    vlist.remove(file)
+
+    if len(vlist) > 1:
+        print('New file is:  ' + alllibname)
+        with open(alllibname, 'w') as ofile:
+            allmodules = []
+            for vfile in vlist:
+                with open(vfile, 'r') as ifile:
+                    # print('Adding ' + vfile + ' to library.')
+                    vtext = ifile.read()
+                    modules = re.findall(r'[ \t\n]module[ \t]+([^ \t\n\(]+)', vtext)
+                    mseen = list(item for item in modules if item in allmodules)
+                    allmodules.extend(list(item for item in modules if item not in allmodules))
+                    vfilter = remove_redundant_modules(vtext, allmodules, mseen)
+                    # NOTE:  The following workaround resolves an issue with iverilog,
+                    # which does not properly parse specify timing paths that are not in
+                    # parentheses.  Easy to work around
+                    vlines = re.sub(r'\)[ \t]*=[ \t]*([01]:[01]:[01])[ \t]*;', r') = ( \1 ) ;', vfilter)
+                    print(vlines, file=ofile)
+                print('\n//--------EOF---------\n', file=ofile)
+
+        if do_compile_only == True:
+            print('Compile-only:  Removing individual verilog files')
+            for vfile in vlist:
+                if os.path.isfile(vfile):
+                    os.remove(vfile)
+                elif os.path.islink(vfile):
+                    os.unlink(vfile)
+    else:
+        print('Only one file (' + str(vlist) + ');  ignoring "compile" option.')
+
+#----------------------------------------------------------------------------
+# Remove redundant module entries from a verilog file.  "m2list" is a list of
+# module names gleaned from all previously read files using re.findall().
+# "mlist" is a list of all module names including those in "ntext".
+# The reason for doing this is that some verilog files may includes modules used
+# by all the files, and if included more than once, then iverilog complains.
+#----------------------------------------------------------------------------
+
+def remove_redundant_modules(ntext, mlist, m2list):
+    updated = ntext
+    for module in mlist:
+        # Determine the number of times the module appears in the text
+        if module in m2list:
+            # This module seen before outside of ntext, so remove all occurrances in ntext
+            new = re.sub(r'[ \t\n]+module[ \t]+' + module + '[ \t\n\(]+.*[ \t\n]endmodule', '\n', updated, flags=re.DOTALL)
+            updated = new
+
+        else:
+            n = len(re.findall(r'[ \t\n]module[ \t]+' + module + '[ \t\n\(]+.*[ \t\n]endmodule', updated, flags=re.DOTALL))
+            # This module defined more than once inside ntext, so remove all but one
+            # Optimization:  Just keep original text if n < 2
+            if n < 2:
+                continue
+
+            # Remove all but one
+            updated = re.sub(r'[ \t\n]+module[ \t]+' + module + '[ \t\n]+.*[ \t\n]endmodule', '\n', n - 1, updated, flags=re.IGNORECASE | re.DOTALL)
+    return updated
+
+#----------------------------------------------------------------------------
+
+if __name__ == '__main__':
+
+    if len(sys.argv) == 1:
+        usage()
+        sys.exit(0)
+
+    argumentlist = []
+
+    # Defaults
+    do_compile_only = False
+    do_stub = False
+    excludelist = []
+
+    # Break arguments into groups where the first word begins with "-".
+    # All following words not beginning with "-" are appended to the
+    # same list (optionlist).  Then each optionlist is processed.
+    # Note that the first entry in optionlist has the '-' removed.
+
+    for option in sys.argv[1:]:
+        if option.find('-', 0) == 0:
+            keyval = option[1:].split('=')
+            if keyval[0] == 'compile-only':
+                if len(keyval) > 0:
+                    if keyval[1].tolower() == 'true' or keyval[1].tolower() == 'yes' or keyval[1] == '1':
+                        do_compile_only = True
+                else:
+                    do_compile_only = True
+            elif keyval[1] == 'exclude' or key == 'excludelist':
+                if len(keyval) > 0:
+                    excludelist = keyval[1].trim('"').split(',')
+                else:
+                    print("No items in exclude list (ignoring).")
+            elif keyval[0] == 'stub':
+                if len(keyval) > 0:
+                    if keyval[1].tolower() == 'true' or keyval[1].tolower() == 'yes' or keyval[1] == '1':
+                        do_stub = True
+                else:
+                    do_stub = True
+            else:
+                print("Unknown option '" + keyval[0] + "' (ignoring).")
+        else:
+            argumentlist.append(option)
+
+    if len(argumentlist) < 3: 
+        print("Not enough arguments given to create_verilog_library.py.")
+        usage()
+        sys.exit(1)
+
+    destlibdir = argumentlist[0]
+    destlib = argumentlist[1]
+    startup_script = argumentlist[2]
+
+    print('')
+    print('Create verilog library from files:')
+    print('')
+    print('Path to files: ' + destlibdir)
+    print('Name of compiled library: ' + destlib + '.v')
+    print('Path to magic startup script: ' + startup_script)
+    print('Remove individual files: ' + 'Yes' if do_compile_only else 'No')
+    if len(excludelist) > 0:
+        print('List of files to exclude: ')
+        for file in excludelist:
+            print(file)
+    print('')
+
+    create_verilog_library(destlibdir, destlib, startup_script, do_compile_only, do_stub, excludelist)
+    print('Done.')
+    sys.exit(0)
+
+#----------------------------------------------------------------------------
diff --git a/common/foundry_install.py b/common/foundry_install.py
index 149c21f..267342b 100755
--- a/common/foundry_install.py
+++ b/common/foundry_install.py
@@ -116,6 +116,13 @@
 import fnmatch
 import subprocess
 
+# Import local routines
+from create_gds_library import create_gds_library
+from create_spice_library import create_spice_library
+from create_lef_library import create_lef_library
+from create_lib_library import create_lib_library
+from create_verilog_library import create_verilog_library
+
 def usage():
     print("foundry_install.py [options...]")
     print("   -copy             Copy files from source to target (default)")
@@ -327,438 +334,6 @@
                         print(line)
 
 #----------------------------------------------------------------------------
-# Given a destination directory holding individual verilog files of a number
-# of modules, create a single verilog library file named <alllibname> and place
-# it in the same directory.  This is done for the option "compile" if specified
-# for the "-verilog" install.
-#----------------------------------------------------------------------------
-
-def create_verilog_library(destlibdir, destlib, do_compile_only, do_stub, excludelist):
-
-    alllibname = destlibdir + '/' + destlib + '.v'
-    if os.path.isfile(alllibname):
-        os.remove(alllibname)
-
-    print('Diagnostic:  Creating consolidated verilog library ' + destlib + '.v')
-    vlist = glob.glob(destlibdir + '/*.v')
-    if alllibname in vlist:
-        vlist.remove(alllibname)
-
-    # Create exclude list with glob-style matching using fnmatch
-    if len(vlist) > 0:
-        vlistnames = list(os.path.split(item)[1] for item in vlist)
-        notvlist = []
-        for exclude in excludelist:
-            notvlist.extend(fnmatch.filter(vlistnames, exclude))
-
-        # Apply exclude list
-        if len(notvlist) > 0:
-            for file in vlist[:]:
-                if os.path.split(file)[1] in notvlist:
-                    vlist.remove(file)
-
-    if len(vlist) > 1:
-        print('New file is:  ' + alllibname)
-        with open(alllibname, 'w') as ofile:
-            allmodules = []
-            for vfile in vlist:
-                with open(vfile, 'r') as ifile:
-                    # print('Adding ' + vfile + ' to library.')
-                    vtext = ifile.read()
-                    modules = re.findall(r'[ \t\n]module[ \t]+([^ \t\n\(]+)', vtext)
-                    mseen = list(item for item in modules if item in allmodules)
-                    allmodules.extend(list(item for item in modules if item not in allmodules))
-                    vfilter = remove_redundant_modules(vtext, allmodules, mseen)
-                    # NOTE:  The following workaround resolves an issue with iverilog,
-                    # which does not properly parse specify timing paths that are not in
-                    # parentheses.  Easy to work around
-                    vlines = re.sub(r'\)[ \t]*=[ \t]*([01]:[01]:[01])[ \t]*;', r') = ( \1 ) ;', vfilter)
-                    print(vlines, file=ofile)
-                print('\n//--------EOF---------\n', file=ofile)
-
-        if do_compile_only == True:
-            print('Compile-only:  Removing individual verilog files')
-            for vfile in vlist:
-                if os.path.isfile(vfile):
-                    os.remove(vfile)
-                elif os.path.islink(vfile):
-                    os.unlink(vfile)
-    else:
-        print('Only one file (' + str(vlist) + ');  ignoring "compile" option.')
-
-#----------------------------------------------------------------------------
-# Remove redundant module entries from a verilog file.  "m2list" is a list of
-# module names gleaned from all previously read files using re.findall().
-# "mlist" is a list of all module names including those in "ntext".
-# The reason for doing this is that some verilog files may includes modules used
-# by all the files, and if included more than once, then iverilog complains.
-#----------------------------------------------------------------------------
-
-def remove_redundant_modules(ntext, mlist, m2list):
-    updated = ntext
-    for module in mlist:
-        # Determine the number of times the module appears in the text
-        if module in m2list:
-            # This module seen before outside of ntext, so remove all occurrances in ntext
-            new = re.sub(r'[ \t\n]+module[ \t]+' + module + '[ \t\n\(]+.*[ \t\n]endmodule', '\n', updated, flags=re.DOTALL)
-            updated = new
-
-        else:
-            n = len(re.findall(r'[ \t\n]module[ \t]+' + module + '[ \t\n\(]+.*[ \t\n]endmodule', updated, flags=re.DOTALL))
-            # This module defined more than once inside ntext, so remove all but one
-            # Optimization:  Just keep original text if n < 2
-            if n < 2:
-                continue
-
-            # Remove all but one
-            updated = re.sub(r'[ \t\n]+module[ \t]+' + module + '[ \t\n]+.*[ \t\n]endmodule', '\n', n - 1, updated, flags=re.IGNORECASE | re.DOTALL)
-    return updated
-
-#----------------------------------------------------------------------------
-# Given a destination directory holding individual LEF files of a number
-# of cells, create a single LEF library file named <alllibname> and place
-# it in the same directory.  This is done for the option "compile" if specified
-# for the "-lef" install.
-#----------------------------------------------------------------------------
-
-def create_lef_library(destlibdir, destlib, do_compile_only, excludelist):
-
-    alllibname = destlibdir + '/' + destlib + '.lef'
-    if os.path.isfile(alllibname):
-        os.remove(alllibname)
-
-    print('Diagnostic:  Creating consolidated LEF library ' + destlib + '.lef')
-    llist = glob.glob(destlibdir + '/*.lef')
-    if alllibname in llist:
-        llist.remove(alllibname)
-
-    # Create exclude list with glob-style matching using fnmatch
-    if len(llist) > 0:
-        llistnames = list(os.path.split(item)[1] for item in llist)
-        notllist = []
-        for exclude in excludelist:
-            notllist.extend(fnmatch.filter(llistnames, exclude))
-
-        # Apply exclude list
-        if len(notllist) > 0:
-            for file in llist[:]:
-                if os.path.split(file)[1] in notllist:
-                    llist.remove(file)
-
-    if len(llist) > 1:
-        print('New file is:  ' + alllibname)
-        with open(alllibname, 'w') as ofile:
-            headerdone = False
-            for lfile in llist:
-                with open(lfile, 'r') as ifile:
-                    # print('Adding ' + lfile + ' to library.')
-                    ltext = ifile.read()
-                    llines = ltext.splitlines()
-                    headerseen = False
-                    for lline in llines:
-                        if headerdone:
-                            if not headerseen:
-                                if not lline.startswith('MACRO'):
-                                    continue
-                                else:
-                                    headerseen = True
-                        print(lline, file=ofile)
-                    headerdone = True
-                print('#--------EOF---------\n', file=ofile)
-
-        if do_compile_only == True:
-            print('Compile-only:  Removing individual LEF files')
-            for lfile in llist:
-                if os.path.isfile(lfile):
-                    os.remove(lfile)
-            if newname:
-                if os.path.isfile(newname):
-                    os.remove(newname)
-    else:
-        print('Only one file (' + str(llist) + ');  ignoring "compile" option.')
-
-#----------------------------------------------------------------------------
-# Given a destination directory holding individual liberty files of a number
-# of cells, create a single liberty library file named <alllibname> and place
-# it in the same directory.  This is done for the option "compile" if specified
-# for the "-lib" install.
-#----------------------------------------------------------------------------
-
-# Warning:  This script is unfinished.  Needs to parse the library header
-# in each cell and generate a new library header combining the contents of
-# all cell headers.  Also:  The library name in the header needs to be
-# changed to the full library name.  Also:  There is no mechanism for
-# collecting all files belonging to a single process corner/temperature/
-# voltage.
-
-def create_lib_library(destlibdir, destlib, do_compile_only, excludelist):
-
-    alllibname = destlibdir + '/' + destlib + '.lib'
-    if os.path.isfile(alllibname):
-        os.remove(alllibname)
-
-    print('Diagnostic:  Creating consolidated liberty library ' + destlib + '.lib')
-
-    # Create exclude list with glob-style matching using fnmatch
-    if len(llist) > 0:
-        llistnames = list(os.path.split(item)[1] for item in llist)
-        notllist = []
-        for exclude in excludelist:
-            notllist.extend(fnmatch.filter(llistnames, exclude))
-
-        # Apply exclude list
-        if len(notllist) > 0:
-            for file in llist[:]:
-                if os.path.split(file)[1] in notllist:
-                    llist.remove(file)
-
-    if len(llist) > 1:
-        print('New file is:  ' + alllibname)
-        with open(alllibname, 'w') as ofile:
-            headerdone = False
-            for lfile in llist:
-                with open(lfile, 'r') as ifile:
-                    # print('Adding ' + lfile + ' to library.')
-                    ltext = ifile.read()
-                    llines = ltext.splitlines()
-                    headerseen = False
-                    for lline in llines:
-                        if headerdone:
-                            if not headerseen:
-                                if not lline.split()[0] == 'cell':
-                                    continue
-                                else:
-                                    headerseen = True
-                        print(lline, file=ofile)
-                    headerdone = True
-                print('/*--------EOF---------*/\n', file=ofile)
-
-        if do_compile_only == True:
-            print('Compile-only:  Removing individual LEF files')
-            for lfile in llist:
-                if os.path.isfile(lfile):
-                    os.remove(lfile)
-            if newname:
-                if os.path.isfile(newname):
-                    os.remove(newname)
-    else:
-        print('Only one file (' + str(llist) + ');  ignoring "compile" option.')
-
-#----------------------------------------------------------------------------
-# Given a destination directory holding individual GDS files of a number
-# of cells, create a single GDL library file named <alllibname> and place
-# it in the same directory.  This is done for the option "compile" if specified
-# for the "-gds" install.
-#----------------------------------------------------------------------------
-
-def create_gds_library(destlibdir, destlib, startup_script, do_compile_only, excludelist):
-
-    alllibname = destlibdir + '/' + destlib + '.gds'
-    if os.path.isfile(alllibname):
-        os.remove(alllibname)
-
-    print('Diagnostic:  Creating consolidated GDS library ' + destlib + '.gds')
-    glist = glob.glob(destlibdir + '/*.gds')
-    glist.extend(glob.glob(destlibdir + '/*.gdsii'))
-    glist.extend(glob.glob(destlibdir + '/*.gds2'))
-    if alllibname in glist:
-        glist.remove(alllibname)
-
-    # Create exclude list with glob-style matching using fnmatch
-    if len(glist) > 0:
-        glistnames = list(os.path.split(item)[1] for item in glist)
-        notglist = []
-        for exclude in excludelist:
-            notglist.extend(fnmatch.filter(glistnames, exclude))
-
-        # Apply exclude list
-        if len(notglist) > 0:
-            for file in glist[:]:
-                if os.path.split(file)[1] in notglist:
-                    glist.remove(file)
-
-    if len(glist) > 1:
-        print('New file is:  ' + alllibname)
-
-        if os.path.isfile(startup_script):
-            # If the symbolic link exists, remove it.
-            if os.path.isfile(destlibdir + '/.magicrc'):
-                os.remove(destlibdir + '/.magicrc')
-            os.symlink(startup_script, destlibdir + '/.magicrc')
-
-        # A GDS library is binary and requires handling in Magic
-        print('Creating magic generation script to generate GDS library.') 
-        with open(destlibdir + '/generate_magic.tcl', 'w') as ofile:
-            print('#!/usr/bin/env wish', file=ofile)
-            print('#--------------------------------------------', file=ofile)
-            print('# Script to generate .gds library from files   ', file=ofile)
-            print('#--------------------------------------------', file=ofile)
-            print('drc off', file=ofile)
-            print('gds readonly true', file=ofile)
-            print('gds flatten true', file=ofile)
-            print('gds rescale false', file=ofile)
-            print('tech unlock *', file=ofile)
-
-            for gdsfile in glist:
-                print('gds read ' + gdsfile, file=ofile)
-
-            print('puts stdout "Creating cell ' + destlib + '"', file=ofile)
-            print('load ' + destlib, file=ofile)
-            print('puts stdout "Adding cells to library"', file=ofile)
-            print('box values 0 0 0 0', file=ofile)
-            for gdsfile in glist:
-                gdsroot = os.path.split(gdsfile)[1]
-                gdsname = os.path.splitext(gdsroot)[0]
-                print('getcell ' + gdsname, file=ofile)
-                # Could properly make space for the cell here. . . 
-                print('box move e 200', file=ofile)
-                                
-            print('puts stdout "Writing GDS library ' + destlib + '"', file=ofile)
-            print('gds library', file=ofile)
-            print('gds write ' + destlib, file=ofile)
-            print('puts stdout "Done."', file=ofile)
-            print('quit -noprompt', file=ofile)
-
-        # Run magic to read in the individual GDS files and
-        # write out the consolidated GDS library
-
-        print('Running magic to create GDS library.')
-        sys.stdout.flush()
-
-        mproc = subprocess.run(['magic', '-dnull', '-noconsole',
-			destlibdir + '/generate_magic.tcl'],
-			stdin = subprocess.DEVNULL,
-			stdout = subprocess.PIPE,
-			stderr = subprocess.PIPE, cwd = destlibdir,
-			universal_newlines = True)
-
-        if mproc.stdout:
-            for line in mproc.stdout.splitlines():
-                print(line)
-        if mproc.stderr:
-            print('Error message output from magic:')
-            for line in mproc.stderr.splitlines():
-                print(line)
-        if mproc.returncode != 0:
-            print('ERROR:  Magic exited with status ' + str(mproc.returncode))
-        if do_compile_only == True:
-            print('Compile-only:  Removing individual GDS files')
-            for gfile in glist:
-                if os.path.isfile(gfile):
-                    os.remove(gfile)
-            if newname:
-                if os.path.isfile(newname):
-                    os.remove(newname)
-    else:
-        print('Only one file (' + str(glist) + ');  ignoring "compile" option.')
-
-#----------------------------------------------------------------------------
-# Given a destination directory holding individual SPICE netlists of a number
-# of cells, create a single SPICE library file named <alllibname> and place
-# it in the same directory.  This is done for the option "compile" if specified
-# for the "-spice" install.
-#----------------------------------------------------------------------------
-
-def create_spice_library(destlibdir, destlib, spiext, do_compile_only, do_stub, excludelist):
-
-    fformat = 'CDL' if spiext == '.cdl' else 'SPICE'
-
-    allstubname = destlibdir + '/stub' + spiext
-    alllibname = destlibdir + '/' + destlib + spiext
-    if do_stub:
-        outputname = allstubname
-    else:
-        outputname = alllibname
-
-    print('Diagnostic:  Creating consolidated ' + fformat + ' library ' + outputname)
-
-    if os.path.isfile(outputname):
-        os.remove(outputname)
-
-    if fformat == 'CDL':
-        slist = glob.glob(destlibdir + '/*.cdl')
-    else:
-        # Sadly, there is no consensus on what a SPICE file extension should be.
-        slist = glob.glob(destlibdir + '/*.spc')
-        slist.extend(glob.glob(destlibdir + '/*.spice'))
-        slist.extend(glob.glob(destlibdir + '/*.spi'))
-        slist.extend(glob.glob(destlibdir + '/*.ckt'))
-
-    if alllibname in slist:
-        slist.remove(alllibname)
-
-    if allstubname in slist:
-        slist.remove(allstubname)
-
-    # Create exclude list with glob-style matching using fnmatch
-    if len(slist) > 0:
-        slistnames = list(os.path.split(item)[1] for item in slist)
-        notslist = []
-        for exclude in excludelist:
-            notslist.extend(fnmatch.filter(slistnames, exclude))
-
-        # Apply exclude list
-        if len(notslist) > 0:
-            for file in slist[:]:
-                if os.path.split(file)[1] in notslist:
-                    slist.remove(file)
-
-    if len(slist) > 1:
-        with open(outputname, 'w') as ofile:
-            allsubckts = []
-            for sfile in slist:
-                with open(sfile, 'r') as ifile:
-                    # print('Adding ' + sfile + ' to library.')
-                    stext = ifile.read()
-                    subckts = re.findall(r'\.subckt[ \t]+([^ \t\n]+)', stext, flags=re.IGNORECASE)
-                    sseen = list(item for item in subckts if item in allsubckts)
-                    allsubckts.extend(list(item for item in subckts if item not in allsubckts))
-                    sfilter = remove_redundant_subckts(stext, allsubckts, sseen)
-                    print(sfilter, file=ofile)
-                print('\n******* EOF\n', file=ofile)
-
-        if do_compile_only == True:
-            print('Compile-only:  Removing individual SPICE files')
-            for sfile in slist:
-                if os.path.isfile(sfile):
-                    os.remove(sfile)
-                elif os.path.islink(sfile):
-                    os.unlink(sfile)
-    else:
-        print('Only one file (' + str(slist) + ');  ignoring "compile" option.')
-
-#----------------------------------------------------------------------------
-# Remove redundant subcircuit entries from a SPICE or CDL netlist file.  "sseen"
-# is a list of subcircuit names gleaned from all previously read files using
-# re.findall(). "slist" is a list of subcircuits including those in "ntext".
-# If a subcircuit is defined outside of "ntext", then remove all occurrences in
-# "ntext".  Otherwise, if a subcircuit is defined more than once in "ntext",
-# remove all but one copy.  The reason for doing this is that some netlists will
-# include primitive device definitions used by all the standard cell subcircuits.
-#
-# It may be necessary to remove redundant .include statements and redundant .model
-# and/or .option statements as well.
-#----------------------------------------------------------------------------
-
-def remove_redundant_subckts(ntext, slist, sseen):
-    updated = ntext
-    for subckt in slist:
-        if subckt in sseen:
-            # Remove all occurrences of subckt
-            updated = re.sub(r'\n\.subckt[ \t]+' + subckt + '[ \t\n]+.*\n\.ends[ \t\n]+', '\n', updated, flags=re.IGNORECASE | re.DOTALL)
-
-        else:
-            # Determine the number of times the subcircuit appears in the text
-            n = len(re.findall(r'\n\.subckt[ \t]+' + subckt + '[ \t\n]+.*\n\.ends[ \t\n]+', updated, flags=re.IGNORECASE | re.DOTALL))
-            # Optimization:  Just keep original text if n < 2
-            if n < 2:
-                continue
-
-            # Remove all but one
-            updated = re.sub(r'\n\.subckt[ \t]+' + subckt + '[ \t\n]+.*\n\.ends[ \t\n]+', '\n', n - 1, updated, flags=re.IGNORECASE | re.DOTALL)
-    return updated
-
-#----------------------------------------------------------------------------
 # This is the main entry point for the foundry install script.
 #----------------------------------------------------------------------------