#!/usr/bin/env python3
#
# foundry_install.py
#
# This file generates the local directory structure and populates the
# directories with foundry vendor data.  The local directory (target)
# should be a staging area, not a place where files are kept permanently.
#
# Options:
#    -ef_format		Use efabless naming (libs.ref/techLEF),
#			otherwise use generic naming (libs.tech/lef)
#    -clean		Clear out and remove target directory before starting
#    -source <path>	Path to source data top level directory
#    -target <path>	Path to target (staging) top level directory
#
# All other options represent paths to vendor files.  They may all be
# wildcarded with "*", or with specific escapes like "%l" for library
# name or "%v" for version number (see below for a complete list of escape
# sequences).
#
# Note only one of "-spice" or "-cdl" need be specified.  Since the
# open source tools use ngspice, CDL files are converted to ngspice
# syntax when needed.
#
#	-techlef <path>	Path to technology LEF file
#	-doc <path>	Path to technology documentation
#	-lef <path>	Path to LEF file
#	-spice <path>	Path to SPICE netlists
#	-cdl <path>	Path to CDL netlists
#	-models <path>	Path to SPICE (primitive device) models
#	-liberty <path>	Path to Liberty timing files
#	-gds <path>	Path to GDS data
#	-verilog <path>	Path to verilog models
#
#	-library <type> <name> [<target>]	See below
#
# For the "-library" option, any number of libraries may be supported, and
# one "-library" option should be provided for each supported library.
# <type> is one of:  "digital", "primitive", or "general".  Analog and I/O
# libraries fall under the category "general", as they are all treated the
# same way.  <name> is the vendor name of the library.  [<target>] is the
# (optional) local name of the library.  If omitted, then the vendor name
# is used for the target (there is no particular reason to specify a
# different local name for a library).
#
# In special cases using options (see below), path may be "-", indicating
# that there are no source files, but only to run compilations or conversions
# on the files in the target directory.
#
# All options "-lef", "-spice", etc., can take the additional arguments
# 	up  <number>
#
# to indicate that the source hierarchy should be copied from <number>
# levels above the files.  For example, if liberty files are kept in
# multiple directories according to voltage level, then
#
# 	-liberty x/y/z/PVT_*/*.lib
#
# would install all .lib files directly into libs.ref/<libname>/liberty/*.lib
# (if "-ef_format" option specified, then: libs.ref/<libname>/liberty/*.lib)
# while
#
# 	-liberty x/y/z/PVT_*/*.lib up 1
#
# would install all .lib files into libs.ref/liberty/<libname>/PVT_*/*.lib
# (if "-ef_format" option specified, then: libs.ref/<libname>/liberty/PVT_*/*.lib)
#
# Please note that the INSTALL variable in the Makefile starts with "set -f"
# to suppress the OS from doing wildcard substitution;  otherwise the
# wildcards in the install options will get expanded by the OS before
# being passed to the install script.
#
# Other library-specific arguments are:
#
#	nospec	:  Remove timing specification before installing
#		    (used with verilog files;  needs to be extended to
#		    liberty files)
#	compile :  Create a single library from all components.  Used
#		    when a foundry library has inconveniently split
#		    an IP library (LEF, CDL, verilog, etc.) into
#		    individual files.
#	compile-only:	Like "compile" except that the individual
#		    files are removed after the library file has been
#		    created.
#
#	stub :	   Remove contents of subcircuits from CDL or SPICE
#		    netlist files.
#
#	priv :	   Mark the contents being installed as privleged, and
#		    put them in a separate root directory libs.priv
#		    where they can be given additional read/write
#		    restrictions.
#
#	exclude :  Followed by "=" and a comma-separated list of names.
#		    exclude these files/modules/subcircuits.  Names may
#		    also be wildcarded in "glob" format.
#
#	rename :   Followed by "=" and an alternative name.  For any
#		    file that is a single entry, change the name of
#		    the file in the target directory to this (To-do:
#		    take regexps for multiple files).  When used with
#		    "compile" or "compile-only", this refers to the
# 		    name of the target compiled file.
#
#	filter:	   Followed by "=" and the name of a script.
#		    Each file is passed through the filter script
#		    before writing into the staging area.
#
#	sort:	   Followed by "=" and the name of a script.
#		    The list of files to process (after applying items
#		    from "exclude") will be written to a file
#		    "filelist.txt", which will be used by the
#		    library compile routines, if present.  The sort
#		    script will rewrite the file with the order in
#		    which entries should appear in the compiled library.
#		    Only useful when used with "compile" or "compile-only".
#		    If not specified, files are sorted by "natural sort"
#		    order.
#
#	noconvert : Install only; do not attempt to convert to other
#		    formats (applies only to GDS, CDL, and LEF).
#
# NOTE:  This script can be called once for all libraries if all file
# types (gds, cdl, lef, etc.) happen to all work with the same wildcards.
# However, it is more likely that it will be called several times for the
# same PDK, once to install I/O cells, once to install digital, and so
# forth, as made possible by the wild-carding.

import re
import os
import sys
import glob
import stat
import shutil
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)")
    print("   -ef_format        Use efabless naming conventions for local directories")
    print("")
    print("   -source <path>    Path to top of source directory tree")
    print("   -target <path>    Path to top of target directory tree")
    print("")
    print("   -techlef <path>   Path to technology LEF file")
    print("   -doc <path>       Path to technology documentation")
    print("   -lef <path>       Path to LEF file")
    print("   -spice <path>     Path to SPICE netlists")
    print("   -cdl <path>       Path to CDL netlists")
    print("   -models <path>    Path to SPICE (primitive device) models")
    print("   -lib <path>       Path to Liberty timing files")
    print("   -liberty <path>       Path to Liberty timing files")
    print("   -gds <path>       Path to GDS data")
    print("   -verilog <path>   Path to verilog models")
    print("   -library <type> <name> [<target>]	 See below")
    print("")
    print(" All <path> names may be wild-carded with '*' ('glob'-style wild-cards)")
    print("")
    print(" All options with <path> other than source and target may take the additional")
    print(" arguments 'up <number>', where <number> indicates the number of levels of")
    print(" hierarchy of the source path to include when copying to the target.")
    print("")
    print(" Library <type> may be one of:")
    print("    digital		Digital standard cell library")
    print("    primitive	Primitive device library")
    print("    general		All other library types (I/O, analog, etc.)")
    print("")
    print(" If <target> is unspecified then <name> is used for the target.")

# Return a list of files after glob-style substituting into pathname.  This
# mostly relies on glob.glob(), but uses the additional substitutions with
# escape strings:
#
#   %v :  Match a version number in the form "major[.minor[.rev]]"
#   %l :  substitute the library name
#   %% :  substitute the percent character verbatim

from distutils.version import LooseVersion

#----------------------------------------------------------------------------
#----------------------------------------------------------------------------

def makeuserwritable(filepath):
    if os.path.exists(filepath):
        st = os.stat(filepath)
        os.chmod(filepath, st.st_mode | stat.S_IWUSR)

#----------------------------------------------------------------------------
#----------------------------------------------------------------------------

def substitute(pathname, library):
    if library:
        # Do %l substitution
        newpathname = re.sub('%l', library, pathname)
    else:
        newpathname = pathname

    if '%v' in newpathname:
        vglob = re.sub('%v.*', '*', newpathname)
        vlibs = glob.glob(vglob)
        try:
            vstr = vlibs[0][len(vglob)-1:]
        except IndexError:
            pass
        else:
            for vlib in vlibs[1:]:
                vtest = vlib[len(vglob)-1:]
                if LooseVersion(vtest) > LooseVersion(vstr):
                    vstr = vtest
            newpathname = re.sub('%v', vstr, newpathname)

    if '%%' in newpathname:
        newpathname = re.sub('%%', '%', newpathname)

    return newpathname

#----------------------------------------------------------------------------
#----------------------------------------------------------------------------

def get_gds_properties(magfile):
    proprex = re.compile('^[ \t]*string[ \t]+(GDS_[^ \t]+)[ \t]+([^ \t]+)$')
    proplines = []
    if os.path.isfile(magfile):
        with open(magfile, 'r') as ifile:
            magtext = ifile.read().splitlines()
            for line in magtext:
                lmatch = proprex.match(line)
                if lmatch:
                    propline = lmatch.group(1) + ' ' + lmatch.group(2)
                    proplines.append(propline)
    return proplines

#----------------------------------------------------------------------------
# Read subcircuit ports from a CDL file, given a subcircuit name that should
# appear in the file as a subcircuit entry, and return a dictionary of ports
# and their indexes in the subcircuit line.
#----------------------------------------------------------------------------

def get_subckt_ports(cdlfile, subname):
    portdict = {}
    pidx = 1
    portrex = re.compile('^\.subckt[ \t]+([^ \t]+)[ \t]+(.*)$', flags=re.IGNORECASE)
    with open(cdlfile, 'r') as ifile:
        cdltext = ifile.read()
        cdllines = cdltext.replace('\n+', ' ').splitlines()
        for line in cdllines:
            lmatch = portrex.match(line)
            if lmatch:
                if lmatch.group(1).lower() == subname.lower():
                    ports = lmatch.group(2).split()
                    for port in ports:
                        portdict[port.lower()] = pidx
                        pidx += 1
                    break
    return portdict

#----------------------------------------------------------------------------
# Filter a verilog file to remove any backslash continuation lines, which
# iverilog does not parse.  If targetroot is a directory, then find and
# process all files in the path of targetroot.  If any file to be processed
# is unmodified (has no backslash continuation lines), then ignore it.  If
# any file is a symbolic link and gets modified, then remove the symbolic
# link before overwriting with the modified file.
#----------------------------------------------------------------------------

def vfilefilter(vfile):
    modified = False
    with open(vfile, 'r') as ifile:
        vtext = ifile.read()

    # Remove backslash-followed-by-newline and absorb initial whitespace.  It
    # is unclear what initial whitespace means in this context, as the use-
    # case that has been seen seems to work under the assumption that leading
    # whitespace is ignored up to the amount used by the last indentation.

    vlines = re.sub('\\\\\n[ \t]*', '', vtext)

    if vlines != vtext:
        # File contents have been modified, so if this file was a symbolic
        # link, then remove it.  Otherwise, overwrite the file with the
        # modified contents.
        if os.path.islink(vfile):
            os.unlink(vfile)
        with open(vfile, 'w') as ofile:
            ofile.write(vlines)

#----------------------------------------------------------------------------
# Run a filter on verilog files that cleans up known syntax issues.
# This is embedded in the foundry_install script and is not a custom
# filter largely because the issue is in the tool, not the PDK.
#----------------------------------------------------------------------------

def vfilter(targetroot):
    if os.path.isfile(targetroot):
        vfilefilter(targetroot)
    else:
        vlist = glob.glob(targetroot + '/*')
        for vfile in vlist:
            if os.path.isfile(vfile):
                vfilefilter(vfile)

#----------------------------------------------------------------------------
# For issues that are PDK-specific, a script can be written and put in
# the PDK's custom/scripts/ directory, and passed to the foundry_install
# script using the "filter" option.
#----------------------------------------------------------------------------

def tfilter(targetroot, filterscript, outfile=[]):
    filterroot = os.path.split(filterscript)[1]
    if os.path.isfile(targetroot):
        print('   Filtering file ' + targetroot + ' with ' + filterroot)
        sys.stdout.flush()
        if not outfile:
            outfile = targetroot
        else:
            # Make sure this file is writable (as the original may not be)
            makeuserwritable(outfile)

        fproc = subprocess.run([filterscript, targetroot, outfile],
			stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
			stderr = subprocess.PIPE, universal_newlines = True)
        if fproc.stdout:
            for line in fproc.stdout.splitlines():
                print(line)
        if fproc.stderr:
            print('Error message output from filter script:')
            for line in fproc.stderr.splitlines():
                print(line)

    else:
        tlist = glob.glob(targetroot + '/*')
        for tfile in tlist:
            if os.path.isfile(tfile):
                print('   Filtering file ' + tfile + ' with ' + filterroot)
                sys.stdout.flush()
                fproc = subprocess.run([filterscript, tfile, tfile],
			stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
			stderr = subprocess.PIPE, universal_newlines = True)
                if fproc.stdout:
                    for line in fproc.stdout.splitlines():
                        print(line)
                if fproc.stderr:
                    print('Error message output from filter script:')
                    for line in fproc.stderr.splitlines():
                        print(line)

#----------------------------------------------------------------------------
# This is the main entry point for the foundry install script.
#----------------------------------------------------------------------------

if __name__ == '__main__':

    if len(sys.argv) == 1:
        print("No options given to foundry_install.py.")
        usage()
        sys.exit(0)
    
    optionlist = []
    newopt = []

    sourcedir = None
    targetdir = None

    ef_format = False
    do_clean = False

    have_lef = False
    have_techlef = False
    have_lefanno = False
    have_gds = False
    have_spice = False
    have_cdl = False
    have_verilog = False
    have_lib = False

    # 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:
            if newopt != []:
                optionlist.append(newopt)
                newopt = []
            newopt.append(option[1:])
        else:
            newopt.append(option)

    if newopt != []:
        optionlist.append(newopt)

    # Pull library names from optionlist
    libraries = []
    for option in optionlist[:]:
        if option[0] == 'library':
            optionlist.remove(option)
            libraries.append(option[1:]) 

    # Check for option "ef_format" or "std_format" or "clean"
    for option in optionlist[:]:
        if option[0] == 'ef_naming' or option[0] == 'ef_names' or option[0] == 'ef_format':
            optionlist.remove(option)
            ef_format = True
        elif option[0] == 'std_naming' or option[0] == 'std_names' or option[0] == 'std_format':
            optionlist.remove(option)
            ef_format = False
        elif option[0] == 'clean':
            do_clean = True

    # Check for options "source" and "target"
    for option in optionlist[:]:
        if option[0] == 'source':
            optionlist.remove(option)
            sourcedir = option[1]
        elif option[0] == 'target':
            optionlist.remove(option)
            targetdir = option[1]

    if not targetdir:
        print("No target directory specified.  Exiting.")
        sys.exit(1)

    # Take the target PDK name from the target path last component
    pdkname = os.path.split(targetdir)[1]

    # If targetdir (the staging area) exists, make sure it's empty.

    if os.path.isdir(targetdir):
        # Error if targetdir exists but is not writeable
        if not os.access(targetdir, os.W_OK):
            print("Target installation directory " + targetdir + " is not writable.")
            sys.exit(1)

        # Clear out the staging directory if specified
        if do_clean:
            shutil.rmtree(targetdir)
    elif os.path.exists(targetdir):
        print("Target installation directory " + targetdir + " is not a directory.")
        sys.exit(1)

    # Error if no source or dest specified unless "-clean" was specified
    if not sourcedir:
        if do_clean:
            print("Done removing staging area.")
            sys.exit(0)
        else:
            print("No source directory specified.  Exiting.")
            sys.exit(1)

    # Create the target directory
    os.makedirs(targetdir, exist_ok=True)

    # Here's where common scripts are found:
    scriptdir = os.path.split(os.getcwd())[0] + '/common'

    #----------------------------------------------------------------
    # Installation part 1:  Install files into the staging directory
    #----------------------------------------------------------------

    # Diagnostic
    print("Installing in target (staging) directory " + targetdir)

    # Create the top-level directories

    os.makedirs(targetdir + '/libs.tech', exist_ok=True)
    os.makedirs(targetdir + '/libs.ref', exist_ok=True)

    # Path to magic techfile depends on ef_format

    if ef_format == True:
        mag_current = '/libs.tech/magic/current/'
    else:
        mag_current = '/libs.tech/magic/'

    # Check for magic version and set flag if it does not exist or if
    # it has the wrong version.
    have_mag_8_2 = False
    try:
        mproc = subprocess.run(['magic', '--version'],
		stdout = subprocess.PIPE,
		stderr = subprocess.PIPE,
		universal_newlines = True)
        if mproc.stdout:
            mag_version = mproc.stdout.splitlines()[0]
            mag_version_info = mag_version.split('.')
            try:
                if int(mag_version_info[0]) > 8:
                    have_mag_8_2 = True
                elif int(mag_version_info[0]) == 8:
                    if int(mag_version_info[1]) >= 2:
                        have_mag_8_2 = True
                        print('Magic version 8.2 available on the system.')
            except ValueError:
                print('Error: "magic --version" did not return valid version number.')
    except FileNotFoundError:
        print('Error: Failed to find executable for magic in standard search path.')

    if not have_mag_8_2:
        print('WARNING:  Magic version 8.2 cannot be executed from the standard executable search path.')
        print('Please install or correct the search path.')
        print('Magic database files will not be created, and other missing file formats may not be generated.')

    # Populate any targets that do not specify a library, or where the library is
    # specified as "primitive".  

    # Populate the techLEF and SPICE models, if specified.  Also, this section can add
    # to any directory in libs.tech/ as given by the option;  e.g., "-ngspice" will
    # install into libs.tech/ngspice/.

    if libraries == [] or 'primitive' in libraries[0]:

        for option in optionlist[:]:

            # Legacy behavior is to put libs.tech models and techLEF files in
            # the same grouping as files for the primdev library (which go in
            # libs.ref).  Current behavior is to put all libs.tech files in
            # a grouping with no library, with unrestricted ability to write
            # into any subdirectory of libs.tech/.  Therefore, need to restrict
            # legacy use to just 'techlef' and 'models'.

            if len(libraries) > 0 and 'primitive' in libraries[0]:
                if option[0] != 'techlef' and option[0] != 'techLEF' and option[0] != 'models':
                    continue
  
            # Normally technology LEF files are associated with IP libraries.
            # However, if no library is specified or the library is 'primitive'
            # (legacy behavior), then put in the techLEF directory with no subdirectory.

            filter_scripts = []
            if option[0] == 'techlef' or option[0] == 'techLEF':
                for item in option:
                    if item.split('=')[0] == 'filter':
                        filter_scripts.append(item.split('=')[1])
                        break

                if ef_format:
                    techlefdir = targetdir + '/libs.ref/' + 'techLEF'
                else:
                    techlefdir = targetdir + '/libs.tech/lef'

                os.makedirs(techlefdir, exist_ok=True)
                # All techlef files should be copied, so use "glob" on the wildcards
                techlist = glob.glob(substitute(sourcedir + '/' + option[1], None))

                for lefname in techlist:
                    leffile = os.path.split(lefname)[1]
                    targname = techlefdir + '/' + leffile

                    if os.path.isfile(lefname):
                        shutil.copy(lefname, targname)
                    else:
                        shutil.copytree(lefname, targname)

                    for filter_script in filter_scripts:
                        # Apply filter script to all files in the target directory
                        tfilter(targname, filter_script)

                optionlist.remove(option)

            # All remaining options will refer to specific tools (e.g., -ngspice, -magic)
            # although generic names (.e.g, -models) are acceptable if the tools know
            # where to find the files.  Currently, most tools have their own formats
            # and standards for setup, and so generally each install directory will be
            # unique to one EDA tool.

            else:
                filter_scripts = []
                for item in option:
                    if item.split('=')[0] == 'filter':
                        filter_scripts.append(item.split('=')[1])
                        break

                print('Diagnostic:  installing to ' + option[0] + '.')
                tooldir = targetdir + '/libs.tech/' + option[0]
                os.makedirs(tooldir, exist_ok=True)

                # All files should be linked or copied, so use "glob" on
                # the wildcards.  Copy each file and recursively copy each
                # directory.
                toollist = glob.glob(substitute(sourcedir + '/' + option[1], None))

                for toolname in toollist:
                    toolfile = os.path.split(toolname)[1]
                    targname = tooldir + '/' + toolfile

                    print('    installing from ' + toolfile + ' to ' + targname)

                    if os.path.isdir(toolname):
                        # Remove any existing directory, and its contents
                        if os.path.isdir(targname):
                            shutil.rmtree(targname)
                        os.makedirs(targname)
    
                        # Recursively find and copy or link the whole directory
                        # tree from this point.

                        alltoollist = glob.glob(toolname + '/**', recursive=True)
                        commonpart = os.path.commonpath(alltoollist)
                        for subtoolname in alltoollist:
                            # Get the path part that is not common between toollist and
                            # alltoollist.
                            subpart = os.path.relpath(subtoolname, commonpart)
                            subtargname = targname + '/' + subpart

                            if os.path.isfile(subtoolname):
                                os.makedirs(os.path.split(subtargname)[0], exist_ok=True)
                                shutil.copy(subtoolname, subtargname)
                            else:
                                print('   copy tree from ' + subtoolname + ' to ' + subtargname)
                                # emulate Python3.8 dirs_exist_ok option
                                try:
                                    shutil.copytree(subtoolname, subtargname)
                                except FileExistsError:
                                    pass

                            for filter_script in filter_scripts:
                                # Apply filter script to all files in the target directory
                                tfilter(subtargname, filter_script)

                    else:
                        # Remove any existing file
                        if os.path.isfile(targname):
                            os.remove(targname)
                        elif os.path.isdir(targname):
                            shutil.rmtree(targname)

                        if os.path.isfile(toolname):
                            shutil.copy(toolname, targname)
                        else:
                            shutil.copytree(toolname, targname)

                        for filter_script in filter_scripts:
                            # Apply filter script to all files in the target directory
                            tfilter(targname, filter_script)

                optionlist.remove(option)

    # Do an initial pass through all of the options and determine what is being
    # installed, so that we know in advance which file formats are missing and
    # need to be generated.

    for option in optionlist[:]:
        if option[0] == 'lef':
            have_lef = True
        if option[0] == 'techlef' or option[0] == 'techLEF':
            have_techlef = True
        elif option[0] == 'gds':
            have_gds = True
        elif option[0] == 'spice' or option[0] == 'spi':
            have_spice = True
        elif option[0] == 'cdl':
            have_cdl = True
        elif option[0] == 'verilog':
            have_verilog = True
        elif option[0] == 'lib' or option[0] == 'liberty':
            have_lib = True

    # The remaining options in optionlist should all be types like 'lef' or 'liberty'
    # and there should be a corresponding library list specified by '-library'

    for option in optionlist[:]:

        # Ignore if no library list---should have been taken care of above.
        if libraries == []:
            break

        # Diagnostic
        print("Install option: " + str(option[0]))

        # For ef_format:  always make techlef -> techLEF and spice -> spi

        if ef_format:
            if option[0] == 'techlef':
                option[0] = 'techLEF'
            elif option[0] == 'spice':
                option[0] = 'spi'

            destdir = targetdir + '/libs.ref/' + option[0]
            os.makedirs(destdir, exist_ok=True)

        # If the option is followed by the keyword "up" and a number, then
        # the source should be copied (or linked) from <number> levels up
        # in the hierarchy (see below).

        hier_up = 0
        for item in option:
            if item.split('=')[0] == 'up':
                hier_up = int(item.split('=')[1])
                break

        filter_scripts = []
        for item in option:
            if item.split('=')[0] == 'filter':
                filter_scripts.append(item.split('=')[1])
                break

        # Option 'stub' applies to netlists ('cdl' or 'spice') and generates
        # a file with only stub entries.
        do_stub = 'stub' in option

        # Option 'compile' is a standalone keyword ('comp' may be used).
        do_compile = 'compile' in option or 'comp' in option
        do_compile_only = 'compile-only' in option or 'comp-only' in option
 
        # Option 'nospecify' is a standalone keyword ('nospec' may be used).
        do_remove_spec = 'nospecify' in option or 'nospec' in option

        # Option 'exclude' has an argument
        try:
            excludelist = list(item.split('=')[1].split(',') for item in option if item.startswith('excl'))[0]
        except IndexError:
            excludelist = []
        else:
            print('Excluding files: ' + (',').join(excludelist))

        # Option 'rename' has an argument
        try:
            newname = list(item.split('=')[1] for item in option if item.startswith('rename'))[0]
        except IndexError:
            newname = None
        else:
            print('Renaming file to: ' + newname)

        # Option 'sort' has an argument. . .
        try:
            sortscript = list(item.split('=')[1] for item in option if item.startswith('sort'))[0]
        except IndexError:
            # If option 'sort' is not specified, then use the "natural sort" script
            sortscript = scriptdir + '/sort_pdkfiles.py'
        else:
            print('Sorting files with script ' + sortscript)

        # 'anno' may be specified for LEF, in which case the LEF is used only
        # to annotate GDS and is not itself installed;  this allows LEF to
        # be generated from Magic and avoids quirky use of obstruction layers.
        have_lefanno = True if 'annotate' in option or 'anno' in option else False
        if have_lefanno: 
            if option[0] != 'lef':
                print("Warning: 'annotate' option specified outside of -lef.  Ignoring.")
            else:
                # Mark as NOT having LEF since we want to use it only for annotation.
                have_lef = False

        # For each library, create the library subdirectory
        for library in libraries:
            if len(library) == 3:
                destlib = library[2]
            else:
                destlib = library[1]

            if ef_format:
                destlibdir = destdir + '/' + destlib
            else:
                destdir = targetdir + '/libs.ref/' + destlib + '/' + option[0]
                destlibdir = destdir

            os.makedirs(destlibdir, exist_ok=True)

            # Populate the library subdirectory
            # Parse the option and replace each '/*/' with the library name,
            # and check if it is a valid directory name.  Then glob the
            # resulting option name.  Warning:  This assumes that all
            # occurences of the text '/*/' match a library name.  It should
            # be possible to wild-card the directory name in such a way that
            # this is always true.

            testpath = substitute(sourcedir + '/' + option[1], library[1])
            liblist = glob.glob(testpath)

            # Create a file "sources.txt" (or append to it if it exists)
            # and add the source directory name so that the staging install
            # script can know where the files came from.

            with open(destlibdir + '/sources.txt', 'a') as ofile:
                print(testpath, file=ofile)

            # Create exclude list with glob-style matching using fnmatch
            if len(liblist) > 0:
                liblistnames = list(os.path.split(item)[1] for item in liblist)
                notliblist = []
                for exclude in excludelist:
                    notliblist.extend(fnmatch.filter(liblistnames, exclude))

                # Apply exclude list
                if len(notliblist) > 0:
                    for file in liblist[:]:
                        if os.path.split(file)[1] in notliblist:
                            liblist.remove(file)

                if len(excludelist) > 0 and len(notliblist) == 0:
                    print('Warning:  Nothing from the exclude list found in sources.')
                    print('excludelist = ' + str(excludelist))
                    print('destlibdir = ' + destlibdir)

            # Diagnostic
            print('Collecting files from ' + testpath)
            print('Files to install:')
            if len(liblist) < 10:
                for item in liblist:
                    print('   ' + item)
            else:
                for item in liblist[0:4]:
                    print('   ' + item)
                print('   .')
                print('   .')
                print('   .')
                for item in liblist[-6:-1]:
                    print('   ' + item)
                print('(' + str(len(liblist)) + ' files total)')

            destfilelist = []
            for libname in liblist:
                # Note that there may be a hierarchy to the files in option[1],
                # say for liberty timing files under different conditions, so
                # make sure directories have been created as needed.

                libfile = os.path.split(libname)[1]
                libfilepath = os.path.split(libname)[0]
                destpathcomp = []
                for i in range(hier_up):
                    destpathcomp.append('/' + os.path.split(libfilepath)[1])
                    libfilepath = os.path.split(libfilepath)[0]
                destpathcomp.reverse()
                destpath = ''.join(destpathcomp)

                if option[0] == 'verilog':
                    fileext = '.v'
                elif option[0] == 'liberty' or option[0] == 'lib':
                    fileext = '.lib'
                elif option[0] == 'spice' or option[0] == 'spi':
                    fileext = '.spice' if not ef_format else '.spi'
                elif option[0] == 'techlef':
                    fileext = '.lef'
                else:
                    fileext = '.' + option[0]

                if newname:
                    if os.path.splitext(newname)[1] == '':
                        newname = newname + fileext

                    if len(liblist) == 1:
                        destfile = newname
                    else:
                        if not do_compile and not do_compile_only:
                            print('Error:  rename specified but more than one file found!')
                        destfile = libfile
                else:
                    destfile = libfile

                targname = destlibdir + destpath + '/' + destfile

                # NOTE:  When using "up" with link_from, could just make
                # destpath itself a symbolic link;  this way is more flexible
                # but adds one symbolic link per file.

                if destpath != '':
                    if not os.path.isdir(destlibdir + destpath):
                        os.makedirs(destlibdir + destpath, exist_ok=True)

                # Remove any existing file
                if os.path.isfile(targname):
                    os.remove(targname)
                elif os.path.isdir(targname):
                    shutil.rmtree(targname)

                # NOTE:  Diagnostic, probably much too much output.
                print('   Install:' + libname + ' to ' + targname)
                if os.path.isfile(libname):
                    shutil.copy(libname, targname)
                else:
                    shutil.copytree(libname, targname)

                # File filtering options:  Two options 'stub' and 'nospec' are
                # handled by scripts in ../common/.  Custom filters can also be
                # specified.

                local_filter_scripts = filter_scripts[:]

                if option[0] == 'verilog':
                    # Internally handle syntactical issues with verilog and iverilog
                    vfilter(targname)

                    if do_remove_spec:
                        local_filter_scripts.append(scriptdir + '/remove_specify.py')

                elif option[0] == 'cdl' or option[0] == 'spi' or option[0] == 'spice':
                    if do_stub:
                        local_filter_scripts.append(scriptdir + '/makestub.py')

                for filter_script in local_filter_scripts:
                    # Apply filter script to all files in the target directory
                    tfilter(targname, filter_script)

                destfilelist.append(os.path.split(targname)[1])

            if sortscript:
                with open(destlibdir + '/filelist.txt', 'w') as ofile:
                    for destfile in destfilelist:
                        print(destfile, file=ofile)
                if os.path.isfile(sortscript):
                    print('Diagnostic:  Sorting files with ' + sortscript)
                    subprocess.run([sortscript, destlibdir],
				stdout = subprocess.DEVNULL,
				stderr = subprocess.DEVNULL)

            if do_compile == True or do_compile_only == True:
                # NOTE:  The purpose of "rename" is to put a destlib-named
                # library elsewhere so that it can be merged with another
                # library into a compiled <destlib>.<ext> on another pass.

                compname = destlib
                    
                # To do:  Make this compatible with linking from another PDK.

                if option[0] == 'verilog':
                    # If there is not a single file with all verilog cells in it,
                    # then compile one, because one does not want to have to have
                    # an include line for every single cell used in a design.

                    create_verilog_library(destlibdir, compname, do_compile_only, do_stub, excludelist)

                elif option[0] == 'gds' and have_mag_8_2:
                    # If there is not a single file with all GDS cells in it,
                    # then compile one.

                    # Link to the PDK magic startup file from the target directory
                    startup_script = targetdir + mag_current + pdkname + '-F.magicrc'
                    if not os.path.isfile(startup_script):
                        startup_script = targetdir + mag_current + pdkname + '.magicrc'
                    create_gds_library(destlibdir, compname, startup_script, do_compile_only, excludelist)

                elif option[0] == 'liberty' or option[0] == 'lib':
                    # If there is not a single file with all liberty cells in it,
                    # then compile one, because one does not want to have to have
                    # an include line for every single cell used in a design.

                    create_lib_library(destlibdir, compname, do_compile_only, excludelist)

                elif option[0] == 'spice' or option[0] == 'spi':
                    # If there is not a single file with all SPICE subcircuits in it,
                    # then compile one, because one does not want to have to have
                    # an include line for every single cell used in a design.

                    spiext = '.spice' if not ef_format else '.spi'
                    create_spice_library(destlibdir, compname, spiext, do_compile_only, do_stub, excludelist)

                elif option[0] == 'cdl':
                    # If there is not a single file with all CDL subcircuits in it,
                    # then compile one, because one does not want to have to have
                    # an include line for every single cell used in a design.

                    create_spice_library(destlibdir, compname, '.cdl', do_compile_only, do_stub, excludelist)

                elif option[0] == 'lef':
                    # If there is not a single file with all LEF cells in it,
                    # then compile one, because one does not want to have to have
                    # an include line for every single cell used in a design.

                    create_lef_library(destlibdir, compname, do_compile_only, excludelist)

                if do_compile_only == True:
                    if newname:
                        if os.path.isfile(targname):
                            os.remove(targname)

                # "rename" with "compile" or "compile-only":  Change the name
                # of the compiled file.

                if newname:
                    print('   Renaming ' + compname + fileext + ' to ' + newname)
                    origname = destlibdir + '/' + compname + fileext
                    targrename = destlibdir + destpath + '/' + newname
                    if os.path.isfile(origname):
                        os.rename(origname, targrename)
      
            # If "filelist.txt" was created, remove it
            if sortscript:
                if os.path.isfile(destlibdir + '/filelist.txt'):
                    os.remove(destlibdir + '/filelist.txt')

        # Find any libraries/options marked as "privileged" (or "private") and
        # move the files from libs.tech or libs.ref to libs.priv, leaving a
        # symbolic link in the original location.  Do this during the initial
        # install so that options following in the list can add files to the
        # non-privileged equivalent directory path.

        if 'priv' in option or 'privileged' in option or 'private' in option:

            # Diagnostic
            print("Install option: " + str(option[0]))

            if ef_format == True:
                os.makedirs(targetdir + '/libs.priv', exist_ok=True)

            for library in libraries:
                if len(library) == 3:
                    destlib = library[2]
                else:
                    destlib = library[1]

                if ef_format:
                    srclibdir = targetdir + '/libs.ref/' + option[0] + '/' + destlib
                    destlibdir = targetdir + '/libs.priv/' + option[0] + '/' + destlib
                else:
                    srclibdir = targetdir + '/libs.ref/' + destlib + '/' + option[0]
                    destlibdir = targetdir + '/libs.priv/' + destlib + '/' + option[0]

                if not os.path.exists(destlibdir):
                    os.makedirs(destlibdir)

                print('Moving files in ' + srclibdir + ' to privileged space.')
                filelist = os.listdir(srclibdir)
                for file in filelist:
                    srcfile = srclibdir + '/' + file
                    destfile = destlibdir + '/' + file
                    if os.path.isfile(destfile):
                        os.remove(destfile)
                    elif os.path.isdir(destfile):
                        shutil.rmtree(destfile)

                    if os.path.isfile(srcfile):
                        shutil.copy(srcfile, destfile)
                        os.remove(srcfile)
                    else:
                        shutil.copytree(srcfile, destfile)
                        shutil.rmtree(srcfile)

    print("Completed installation of vendor files.")

    #----------------------------------------------------------------
    # Installation part 2:  Generate derived file formats
    #----------------------------------------------------------------

    # Now for the harder part.  If GDS and/or LEF databases were specified,
    # then migrate them to magic (.mag files in layout/ or abstract/).

    ignorelist = []
    do_cdl_scaleu  = False
    no_cdl_convert = False
    no_gds_convert = False
    no_lef_convert = False
    cdl_compile_only = False

    cdl_exclude = []
    lef_exclude = []
    gds_exclude = []
    spice_exclude = []
    verilog_exclude = []

    cdl_reflib = '/libs.ref/'
    gds_reflib = '/libs.ref/'
    lef_reflib = '/libs.ref/'

    for option in optionlist[:]:
        if option[0] == 'cdl':
            # Option 'scaleu' is a standalone keyword
            do_cdl_scaleu = 'scaleu' in option

            # Option 'ignore' has arguments after '='
            for item in option:
                if item.split('=')[0] == 'ignore':
                    ignorelist = item.split('=')[1].split(',')

	# Option 'noconvert' is a standalone keyword.
        if 'noconvert' in option:
            if option[0] == 'cdl':
                no_cdl_convert = True
            elif option[0] == 'gds':
                no_gds_convert = True
            elif option[0] == 'lef':
                no_lef_convert = True

        # Option 'privileged' is a standalone keyword.
        if 'priv' in option or 'privileged' in option or 'private' in option:
            if option[0] == 'cdl':
                cdl_reflib = '/libs.priv/'
            elif option[0] == 'gds':
                gds_reflib = '/libs.priv/'
            elif option[0] == 'lef':
                lef_reflib = '/libs.priv/'

        # If CDL is marked 'compile-only' then CDL should only convert the
        # compiled file to SPICE if conversion is needed.
        if 'compile-only' in option:
            if option[0] == 'cdl':
                cdl_compile_only = True

        # Find exclude list for any option
        for item in option:
            if item.split('=')[0] == 'exclude':
                exclude_list = item.split('=')[1].split(',')
                if option[0] == 'cdl':
                    cdl_exclude = exclude_list
                elif option[0] == 'lef':
                    lef_exclude = exclude_list
                elif option[0] == 'gds':
                    gds_exclude = exclude_list
                elif option[0] == 'spi' or option[0] == 'spice':
                    spice_exclude = exclude_list
                elif option[0] == 'verilog':
                    verilog_exclude = exclude_list
 
    devlist = []
    pdklibrary = None

    if have_gds and not no_gds_convert:
        print("Migrating GDS files to layout.")

        if ef_format:
            destdir = targetdir + gds_reflib + 'mag'
            srcdir = targetdir + gds_reflib + 'gds'
            vdir = targetdir + '/libs.ref/' + 'verilog'
            cdir = targetdir + cdl_reflib + 'cdl'
            sdir = targetdir + cdl_reflib + 'spi'

            os.makedirs(destdir, exist_ok=True)

        # For each library, create the library subdirectory
        for library in libraries:
            if len(library) == 3:
                destlib = library[2]
            else:
                destlib = library[1]

            if ef_format:
                destlibdir = destdir + '/' + destlib
                srclibdir = srcdir + '/' + destlib
                vlibdir = vdir + '/' + destlib
                clibdir = cdir + '/' + destlib
                slibdir = sdir + '/' + destlib
            else:
                destdir = targetdir + gds_reflib + destlib + '/mag'
                srcdir = targetdir + gds_reflib + destlib + '/gds'
                vdir = targetdir + '/libs.ref/' + destlib + '/verilog'
                cdir = targetdir + cdl_reflib + destlib + '/cdl'
                sdir = targetdir + cdl_reflib + destlib + '/spice'
                destlibdir = destdir
                srclibdir = srcdir
                vlibdir = vdir
                clibdir = cdir
                slibdir = sdir

            os.makedirs(destlibdir, exist_ok=True)

            # For primitive devices, check the PDK script and find the name
            # of the library and get a list of supported devices.

            if library[0] == 'primitive':
                pdkscript = targetdir + mag_current + pdkname + '.tcl'
                print('Searching for supported devices in PDK script ' + pdkscript + '.')

                if os.path.isfile(pdkscript):
                    librex = re.compile('^[ \t]*set[ \t]+PDKNAMESPACE[ \t]+([^ \t]+)$')
                    devrex = re.compile('^[ \t]*proc[ \t]+([^ :\t]+)::([^ \t_]+)_defaults')
                    fixrex = re.compile('^[ \t]*return[ \t]+\[([^ :\t]+)::fixed_draw[ \t]+([^ \t]+)[ \t]+')
                    devlist = []
                    fixedlist = []
                    with open(pdkscript, 'r') as ifile:
                        scripttext = ifile.read().splitlines()
                        for line in scripttext:
                            lmatch = librex.match(line)
                            if lmatch:
                                pdklibrary = lmatch.group(1)
                            dmatch = devrex.match(line)
                            if dmatch:
                                if dmatch.group(1) == pdklibrary:
                                    devlist.append(dmatch.group(2))
                            fmatch = fixrex.match(line)
                            if fmatch:
                                if fmatch.group(1) == pdklibrary:
                                    fixedlist.append(fmatch.group(2))

                # Diagnostic
                print("PDK library is " + str(pdklibrary))

            # Link to the PDK magic startup file from the target directory
            # If there is no -F version then look for one without -F (open source PDK)
            startup_script = targetdir + mag_current + pdkname + '-F.magicrc'
            if not os.path.isfile(startup_script):
                startup_script = targetdir + mag_current + pdkname + '.magicrc'

            if have_mag_8_2 and 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')
 
                # Find GDS file names in the source
                print('Getting GDS file list from ' + srclibdir + '.')
                gdsfilesraw = os.listdir(srclibdir)
                gdsfiles = []
                for gdsfile in gdsfilesraw:
                    gdsext = os.path.splitext(gdsfile)[1].lower()
                    if gdsext == '.gds' or gdsext == '.gdsii' or gdsext == '.gds2':
                        gdsfiles.append(gdsfile)

                # Create exclude list with glob-style matching using fnmatch
                if len(gdsfiles) > 0:
                    gdsnames = list(os.path.split(item)[1] for item in gdsfiles)
                    notgdsnames = []
                    for exclude in gds_exclude:
                        notgdsnames.extend(fnmatch.filter(gdsnames, exclude))

                    # Apply exclude list
                    if len(notgdsnames) > 0:
                        for file in gdsfiles[:]:
                            if os.path.split(file)[1] in notgdsnames:
                                gdsfiles.remove(file)

                # Generate a script called "generate_magic.tcl" and leave it in
                # the target directory.  Use it as input to magic to create the
                # .mag files from the database.

                print('Creating magic generation script to generate magic database files.') 
                with open(destlibdir + '/generate_magic.tcl', 'w') as ofile:
                    print('#!/usr/bin/env wish', file=ofile)
                    print('#--------------------------------------------', file=ofile)
                    print('# Script to generate .mag files from .gds    ', file=ofile)
                    print('#--------------------------------------------', 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 gdsfiles:
                        # Note:  DO NOT use a relative path here.
                        print('gds read ' + srclibdir + '/' + gdsfile, file=ofile)

                    # Make sure properties include the Tcl generated cell
                    # information from the PDK script

                    if pdklibrary:
                        tclfixedlist = '{' + ' '.join(fixedlist) + '}'
                        print('set devlist ' + tclfixedlist, file=ofile)
                        print('set topcell [lindex [cellname list top] 0]',
				    file=ofile)

                        print('foreach cellname $devlist {', file=ofile)
                        print('    load $cellname', file=ofile)
                        print('    property gencell $cellname', file=ofile)
                        print('    property parameter m=1', file=ofile)
                        print('    property library ' + pdklibrary, file=ofile)
                        print('}', file=ofile)
                        print('load $topcell', file=ofile)

                    else:
                        # Use LEF files to set the port properties
                        if have_lefanno or have_lef:
                            if have_lefanno:
                                lefdirname = 'lefanno'
                            else:
                                lefdirname = 'lef'

                            # Find LEF file names in the source
                            if ef_format:
                                lefsrcdir = targetdir + lef_reflib + lefdirname
                                lefsrclibdir = lefsrcdir + '/' + destlib
                            else:
                                lefsrcdir = targetdir + lef_reflib + destlib + '/' + lefdirname
                                lefsrclibdir = lefsrcdir

                            leffiles = os.listdir(lefsrclibdir)
                            leffiles = list(item for item in leffiles if os.path.splitext(item)[1] == '.lef')
                            print('puts stdout "Annotating cells from LEF"', file=ofile)
                            for leffile in leffiles:
                                print('lef read ' + lefsrclibdir + '/' + leffile, file=ofile)
                     
                        # Use CDL or SPICE netlists to set the port order
                        if have_cdl or have_spice:
                            if have_cdl:
                                netdir = clibdir
                            else:
                                netdir = slibdir

                            # Find CDL/SPICE file names in the source
                            # Ignore "sources.txt" if it is in the list.
                            netfiles = os.listdir(netdir)
                            print('puts stdout "Annotating cells from CDL/SPICE"',
					file=ofile)
                            for netfile in netfiles:
                                if os.path.split(netfile)[1] != 'sources.txt':
                                    print('catch {readspice ' + netdir + '/' + netfile
						+ '}', file=ofile)

                    # print('cellname delete \(UNNAMED\)', file=ofile)
                    print('puts stdout "Writing all magic database files"', file=ofile)
                    print('writeall force', file=ofile)

                    leffiles = []
                    lefmacros = []
                    if have_lefanno:
                        # Find LEF file names in the source
                        if ef_format:
                            lefsrcdir = targetdir + lef_reflib + 'lefanno'
                            lefsrclibdir = lefsrcdir + '/' + destlib
                        else:
                            lefsrcdir = targetdir + lef_reflib + destlib + '/lefanno'
                            lefsrclibdir = lefsrcdir

                        leffiles = os.listdir(lefsrclibdir)
                        leffiles = list(item for item in leffiles if os.path.splitext(item)[1] == '.lef')
                        # Get list of abstract views to make from LEF macros
                        for leffile in leffiles:
                            with open(leffile, 'r') as ifile:
                                ltext = ifile.read()
                                llines = ltext.splitlines()
                                for lline in llines:
                                    ltok = re.split(' |\t|\(', lline)
                                    if ltok[0] == 'MACRO':
                                        lefmacros.append(ltok[1])

                        # Create exclude list with glob-style matching using fnmatch
                        if len(lefmacros) > 0:
                            lefnames = list(os.path.split(item)[1] for item in lefmacros)
                            notlefnames = []
                            for exclude in lef_exclude:
                                notlefnames.extend(fnmatch.filter(lefnames, exclude))

                            # Apply exclude list
                            if len(notlefnames) > 0:
                                for file in lefmacros[:]:
                                    if os.path.split(file)[1] in notlefnames:
                                        lefmacros.remove(file)

                    elif have_verilog and os.path.isdir(vlibdir):
                        # Get list of abstract views to make from verilog modules
                        vfiles = os.listdir(vlibdir)
                        vfiles = list(item for item in vfiles if os.path.splitext(item)[1] == '.v')
                        for vfile in vfiles:
                            with open(vlibdir + '/' + vfile, 'r') as ifile:
                                vtext = ifile.read()
                                vlines = vtext.splitlines()
                                for vline in vlines:
                                    vtok = re.split(' |\t|\(', vline)
                                    try:
                                        if vtok[0] == 'module':
                                            if vtok[1] not in lefmacros:
                                                lefmacros.append(vtok[1])
                                    except:
                                        pass

                        # Create exclude list with glob-style matching using fnmatch
                        if len(lefmacros) > 0:
                            lefnames = list(os.path.split(item)[1] for item in lefmacros)
                            notlefnames = []
                            for exclude in verilog_exclude:
                                notlefnames.extend(fnmatch.filter(lefnames, exclude))

                            # Apply exclude list
                            if len(notlefnames) > 0:
                                for file in lefmacros[:]:
                                    if os.path.split(file)[1] in notlefnames:
                                        lefmacros.remove(file)

                    elif have_cdl and os.path.isdir(clibdir):
                        # Get list of abstract views to make from CDL subcircuits
                        cfiles = os.listdir(clibdir)
                        cfiles = list(item for item in cfiles if os.path.splitext(item)[1] == '.cdl')
                        for cfile in cfiles:
                            with open(clibdir + '/' + cfile, 'r') as ifile:
                                ctext = ifile.read()
                                clines = ctext.splitlines()
                                for cline in clines:
                                    ctok = cline.split()
                                    try:
                                        if ctok[0].lower() == '.subckt':
                                            if ctok[1] not in lefmacros:
                                                lefmacros.append(ctok[1])
                                    except:
                                        pass

                        # Create exclude list with glob-style matching using fnmatch
                        if len(lefmacros) > 0:
                            lefnames = list(os.path.split(item)[1] for item in lefmacros)
                            notlefnames = []
                            for exclude in cdl_exclude:
                                notlefnames.extend(fnmatch.filter(lefnames, exclude))

                            # Apply exclude list
                            if len(notlefnames) > 0:
                                for file in lefmacros[:]:
                                    if os.path.split(file)[1] in notlefnames:
                                        lefmacros.remove(file)

                    elif have_spice and os.path.isdir(slibdir):
                        # Get list of abstract views to make from SPICE subcircuits
                        sfiles = os.listdir(slibdir)
                        sfiles = list(item for item in sfiles)
                        for sfile in sfiles:
                            with open(slibdir + '/' + sfile, 'r') as ifile:
                                stext = ifile.read()
                                slines = stext.splitlines()
                                for sline in slines:
                                    stok = sline.split()
                                    try:
                                        if stok[0].lower() == '.subckt':
                                            if stok[1] not in lefmacros:
                                                lefmacros.append(stok[1])
                                    except:
                                        pass

                        # Create exclude list with glob-style matching using fnmatch
                        if len(lefmacros) > 0:
                            lefnames = list(os.path.split(item)[1] for item in lefmacros)
                            notlefnames = []
                            for exclude in spice_exclude:
                                notlefnames.extend(fnmatch.filter(lefnames, exclude))

                            # Apply exclude list
                            if len(notlefnames) > 0:
                                for file in lefmacros[:]:
                                    if os.path.split(file)[1] in notlefnames:
                                        lefmacros.remove(file)

                    if not lefmacros:
                        print('No source for abstract views:  Abstract views not made.')
                    elif not have_lef:
                        # This library has a GDS database but no LEF database.  Use
                        # magic to create abstract views of the GDS cells.  If
                        # option "annotate" is given, then read the LEF file after
                        # loading the database file to annotate the cell with
                        # information from the LEF file.  This usually indicates
                        # that the LEF file has some weird definition of obstruction
                        # layers and we want to normalize them by using magic's LEF
                        # write procedure, but we still need the pin use and class
                        # information from the LEF file, and maybe the bounding box.

                        for leffile in leffiles:
                            if have_lefanno:
                                print('lef read ' + lefsrclibdir + '/' + leffile, file=ofile)
                        for lefmacro in lefmacros:
                            print('if {[cellname list exists ' + lefmacro + '] != 0} {', file=ofile)
                            print('   load ' + lefmacro, file=ofile)
                            print('   lef write ' + lefmacro + ' -hide', file=ofile)
                            print('}', file=ofile)

                    print('puts stdout "Done."', file=ofile)
                    print('quit -noprompt', file=ofile)

                print('Running magic to create magic database files.')
                sys.stdout.flush()

                # Run magic to read in the GDS file and write out magic databases.
                with open(destlibdir + '/generate_magic.tcl', 'r') as ifile:
                    mproc = subprocess.run(['magic', '-dnull', '-noconsole'],
				stdin = ifile, 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 not have_lef:
                    print('No LEF file install;  need to generate LEF.')
                    # Remove the lefanno/ target and its contents.
                    if have_lefanno:
                        if ef_format:
                            lefannosrcdir = targetdir + lef_reflib + 'lefanno'
                        else:
                            lefannosrcdir = targetdir + lef_reflib + destlib + '/lefanno'
                        if os.path.isdir(lefannosrcdir):
                            shutil.rmtree(lefannosrcdir)

                    if ef_format:
                        destlefdir = targetdir + lef_reflib + 'lef'
                        destleflibdir = destlefdir + '/' + destlib
                    else:
                        destlefdir = targetdir + lef_reflib + destlib + '/lef'
                        destleflibdir = destlefdir

                    os.makedirs(destleflibdir, exist_ok=True)
                    leflist = os.listdir(destlibdir)
                    leflist = list(item for item in leflist if os.path.splitext(item)[1] == '.lef')

                    # All macros will go into one file
                    destleflib = destleflibdir + '/' + destlib + '.lef'
                    # Remove any existing library file from the target directory
                    if os.path.isfile(destleflib):
                        print('Removing existing library ' + destleflib)
                        os.remove(destleflib)

                    first = True
                    with open(destleflib, 'w') as ofile:
                        for leffile in leflist:
                            # Remove any existing single file from the target directory
                            if os.path.isfile(destleflibdir + '/' + leffile):
                                print('Removing ' + destleflibdir + '/' + leffile)
                                os.remove(destleflibdir + '/' + leffile)

                            # Append contents
                            sourcelef =  destlibdir + '/' + leffile
                            with open(sourcelef, 'r') as ifile:
                                leflines = ifile.read().splitlines()
                                if not first:
                                    # Remove header from all but the first file
                                    leflines = leflines[8:]
                                else:
                                    first = False

                            for line in leflines:
                                print(line, file=ofile)

                            # Remove file from the source directory
                            print('Removing source file ' + sourcelef)
                            os.remove(sourcelef)

                    # Set have_lef now that LEF files were made, so they
                    # can be used to generate the maglef/ databases.
                    have_lef = True

            elif not have_mag_8_2:
                print('The installer is not able to run magic.')
            else:
                print("Master PDK magic startup file not found.  Did you install")
                print("PDK tech files before PDK vendor files?")

    if have_lef and not no_lef_convert:
        print("Migrating LEF files to layout.")
        if ef_format:
            destdir = targetdir + '/libs.ref/' + 'maglef'
            srcdir = targetdir + lef_reflib + 'lef'
            magdir = targetdir + gds_reflib + 'mag'
            cdldir = targetdir + cdl_reflib + 'cdl'
            os.makedirs(destdir, exist_ok=True)

        # For each library, create the library subdirectory
        for library in libraries:
            if len(library) == 3:
                destlib = library[2]
            else:
                destlib = library[1]

            if ef_format:
                destlibdir = destdir + '/' + destlib
                srclibdir = srcdir + '/' + destlib
                maglibdir = magdir + '/' + destlib
                cdllibdir = cdldir + '/' + destlib
                clibdir = cdir + '/' + destlib
                slibdir = sdir + '/' + destlib
            else:
                destdir = targetdir + '/libs.ref/' + destlib + '/maglef'
                srcdir = targetdir + lef_reflib + destlib + '/lef'
                magdir = targetdir + gds_reflib + destlib + '/mag'
                cdldir = targetdir + cdl_reflib + destlib + '/cdl'
                cdir = targetdir + cdl_reflib + destlib + '/cdl'
                sdir = targetdir + cdl_reflib + destlib + '/spice'

                destlibdir = destdir
                srclibdir = srcdir
                maglibdir = magdir
                cdllibdir = cdldir
                clibdir = cdir
                slibdir = sdir

            os.makedirs(destlibdir, exist_ok=True)

            # Link to the PDK magic startup file from the target directory
            startup_script = targetdir + mag_current + pdkname + '-F.magicrc'
            if not os.path.isfile(startup_script):
                startup_script = targetdir + mag_current + pdkname + '.magicrc'

            if have_mag_8_2 and 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')
 
                # Find LEF file names in the source
                leffiles = os.listdir(srclibdir)
                leffiles = list(item for item in leffiles if os.path.splitext(item)[1].lower() == '.lef')

                # Get list of abstract views to make from LEF macros
                lefmacros = []
                err_no_macros = False
                for leffile in leffiles:
                    with open(srclibdir + '/' + leffile, 'r') as ifile:
                        ltext = ifile.read()
                        llines = ltext.splitlines()
                        for lline in llines:
                            ltok = re.split(' |\t|\(', lline)
                            if ltok[0] == 'MACRO':
                                lefmacros.append(ltok[1])

                # Create exclude list with glob-style matching using fnmatch
                if len(lefmacros) > 0:
                    lefnames = list(os.path.split(item)[1] for item in lefmacros)
                    notlefnames = []
                    for exclude in lef_exclude:
                        notlefnames.extend(fnmatch.filter(lefnames, exclude))

                    # Apply exclude list
                    if len(notlefnames) > 0:
                        for file in lefmacros[:]:
                            if os.path.split(file)[1] in notlefnames:
                                lefmacros.remove(file)

                if len(leffiles) == 0:
                    print('Warning:  No LEF files found in ' + srclibdir)
                    continue

                print('Generating conversion script to create magic databases from LEF')

                # Generate a script called "generate_magic.tcl" and leave it in
                # the target directory.  Use it as input to magic to create the
                # .mag files from the database.

                with open(destlibdir + '/generate_magic.tcl', 'w') as ofile:
                    print('#!/usr/bin/env wish', file=ofile)
                    print('#--------------------------------------------', file=ofile)
                    print('# Script to generate .mag files from .lef    ', file=ofile)
                    print('#--------------------------------------------', file=ofile)
                    print('tech unlock *', file=ofile)

                    # If there are devices in the LEF file that come from the
                    # PDK library, then copy this list into the script.

                    if pdklibrary:
                        shortdevlist = []
                        for macro in lefmacros:
                            if macro in devlist:
                                shortdevlist.append(macro)

                        tcldevlist = '{' + ' '.join(shortdevlist) + '}'
                        print('set devlist ' + tcldevlist, file=ofile)

                    for leffile in leffiles:
                        print('lef read ' + srclibdir + '/' + leffile, file=ofile)

                    # Use CDL or SPICE netlists to make sure that ports are
                    # present, and to set the port order

                    if have_cdl or have_spice:
                        if have_cdl:
                            netdir = clibdir
                        else:
                            netdir = slibdir

                        # Find CDL/SPICE file names in the source
                        # Ignore "sources.txt" if it is in the list.
                        netfiles = os.listdir(netdir)
                        print('puts stdout "Annotating cells from CDL/SPICE"',
				file=ofile)
                        for netfile in netfiles:
                            if os.path.split(netfile)[1] != 'sources.txt':
                                print('catch {readspice ' + netdir + '/' + netfile
					+ '}', file=ofile)

                    for lefmacro in lefmacros:

                        if pdklibrary and lefmacro in shortdevlist:
                            print('set cellname ' + lefmacro, file=ofile)
                            print('if {[lsearch $devlist $cellname] >= 0} {',
					file=ofile)
                            print('    load $cellname', file=ofile)
                            print('    property gencell $cellname', file=ofile)
                            print('    property parameter m=1', file=ofile)
                            print('    property library ' + pdklibrary, file=ofile)
                            print('}', file=ofile)

                    # Load one of the LEF files so that the default (UNNAMED) cell
                    # is not loaded, then delete (UNNAMED) so it doesn't generate
                    # an error message.
                    if len(lefmacros) > 0:
                        print('load ' + lefmacros[0], file=ofile)
                        # print('cellname delete \(UNNAMED\)', file=ofile)
                    else:
                        err_no_macros = True
                    print('writeall force', file=ofile)
                    print('puts stdout "Done."', file=ofile)
                    print('quit -noprompt', file=ofile)

                if err_no_macros == True:
                    print('Warning:  No LEF macros were defined.')

                print('Running magic to create magic databases from LEF')
                sys.stdout.flush()

                # Run magic to read in the LEF file and write out magic databases.
                with open(destlibdir + '/generate_magic.tcl', 'r') as ifile:
                    mproc = subprocess.run(['magic', '-dnull', '-noconsole'],
				stdin = ifile, 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))


                # Now list all the .mag files generated, and for each, read the
                # corresponding file from the mag/ directory, pull the GDS file
                # properties, and add those properties to the maglef view.  Also
                # read the CDL (or SPICE) netlist, read the ports, and rewrite
                # the port order in the mag and maglef file accordingly.

                # Diagnostic
                print('Annotating files in ' + destlibdir)
                sys.stdout.flush()
                magfiles = os.listdir(destlibdir)
                magfiles = list(item for item in magfiles if os.path.splitext(item)[1] == '.mag')
                for magroot in magfiles:
                    magname = os.path.splitext(magroot)[0]
                    magfile = maglibdir + '/' + magroot
                    magleffile = destlibdir + '/' + magroot
                    prop_lines = get_gds_properties(magfile)

                    # Make sure properties include the Tcl generated cell
                    # information from the PDK script

                    prop_gencell = []
                    if pdklibrary:
                        if magname in fixedlist:
                            prop_gencell.append('gencell ' + magname)
                            prop_gencell.append('library ' + pdklibrary)
                            prop_gencell.append('parameter m=1')

                    nprops = len(prop_lines) + len(prop_gencell)

                    cdlfile = cdllibdir + '/' + magname + '.cdl'
                    if os.path.exists(cdlfile):
                        cdlfiles = [cdlfile]
                    else:
                        # Assume there is at least one file with all cell subcircuits
                        # in it.
                        try:
                            cdlfiles = glob.glob(cdllibdir + '/*.cdl')
                        except:
                            pass
                    if len(cdlfiles) > 0:
                        for cdlfile in cdlfiles:
                            port_dict = get_subckt_ports(cdlfile, magname)
                            if port_dict != {}:
                                break
                    else:
                        port_dict = {}

                    if port_dict == {}:
                        print('No CDL file contains ' + destlib + ' device ' + magname)
                        cdlfile = None
                        # To be done:  If destlib is 'primitive', then look in
                        # SPICE models for port order.
                        if destlib == 'primitive':
                            print('Fix me:  Need to look in SPICE models!')

                    proprex = re.compile('<< properties >>')
                    endrex = re.compile('<< end >>')
                    rlabrex = re.compile('rlabel[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+([^ \t]+)')
                    flabrex = re.compile('flabel[ \t]+.*[ \t]+([^ \t]+)[ \t]*')
                    portrex = re.compile('port[ \t]+([^ \t]+)[ \t]+(.*)')
                    gcellrex = re.compile('string gencell')
                    portnum = -1

                    with open(magleffile, 'r') as ifile:
                        magtext = ifile.read().splitlines()

                    with open(magleffile, 'w') as ofile:
                        has_props = False
                        is_gencell = False
                        for line in magtext:
                            tmatch = portrex.match(line)
                            if tmatch:
                                if portnum >= 0:
                                    line = 'port ' + str(portnum) + ' ' + tmatch.group(2)
                                else:
                                    line = 'port ' + tmatch.group(1) + ' ' + tmatch.group(2)
                            ematch = endrex.match(line)
                            if ematch and nprops > 0:
                                if not has_props:
                                    print('<< properties >>', file=ofile)
                                if not is_gencell:
                                    for prop in prop_gencell:
                                        print('string ' + prop, file=ofile)
                                for prop in prop_lines:
                                    print('string ' + prop, file=ofile)

                            print(line, file=ofile)
                            pmatch = proprex.match(line)
                            if pmatch:
                                has_props = True

                            gmatch = gcellrex.match(line)
                            if gmatch:
                                is_gencell = True

                            lmatch = flabrex.match(line)
                            if not lmatch:
                                lmatch = rlabrex.match(line)
                            if lmatch:
                                labname = lmatch.group(1).lower()
                                try:
                                    portnum = port_dict[labname]
                                except:
                                    portnum = -1

                    if os.path.exists(magfile):
                        with open(magfile, 'r') as ifile:
                            magtext = ifile.read().splitlines()

                        with open(magfile, 'w') as ofile:
                            for line in magtext:
                                tmatch = portrex.match(line)
                                if tmatch:
                                    if portnum >= 0:
                                        line = 'port ' + str(portnum) + ' ' + tmatch.group(2)
                                    else:
                                        line = 'port ' + tmatch.group(1) + ' ' + tmatch.group(2)
                                ematch = endrex.match(line)
                                print(line, file=ofile)
                                lmatch = flabrex.match(line)
                                if not lmatch:
                                    lmatch = rlabrex.match(line)
                                if lmatch:
                                    labname = lmatch.group(1).lower()
                                    try:
                                        portnum = port_dict[labname]
                                    except:
                                        portnum = -1
                    elif os.path.splitext(magfile)[1] == '.mag':
                        # NOTE:  Possibly this means the GDS cell has a different name.
                        print('Error: No file ' + magfile + '.  Why is it in maglef???')

            elif not have_mag_8_2:
                print('The installer is not able to run magic.')
            else:
                print("Master PDK magic startup file not found.  Did you install")
                print("PDK tech files before PDK vendor files?")

    # If SPICE or CDL databases were specified, then convert them to
    # a form that can be used by ngspice, using the cdl2spi.py script 

    if have_spice:
        if ef_format:
            if not os.path.isdir(targetdir + cdl_reflib + 'spi'):
                os.makedirs(targetdir + cdl_reflib + 'spi', exist_ok=True)

    elif have_cdl and not no_cdl_convert:
        if ef_format:
            if not os.path.isdir(targetdir + cdl_reflib + 'spi'):
                os.makedirs(targetdir + cdl_reflib + 'spi', exist_ok=True)

        print("Migrating CDL netlists to SPICE.")
        sys.stdout.flush()

        if ef_format:
            destdir = targetdir + cdl_reflib + 'spi'
            srcdir = targetdir + cdl_reflib + 'cdl'
            os.makedirs(destdir, exist_ok=True)

        # For each library, create the library subdirectory
        for library in libraries:
            if len(library) == 3:
                destlib = library[2]
            else:
                destlib = library[1]

            if ef_format:
                destlibdir = destdir + '/' + destlib
                srclibdir = srcdir + '/' + destlib
            else:
                destdir = targetdir + cdl_reflib + destlib + '/spice'
                srcdir = targetdir + cdl_reflib + destlib + '/cdl'

                destlibdir = destdir
                srclibdir = srcdir

            os.makedirs(destlibdir, exist_ok=True)

            # Find CDL file names in the source
            # If CDL is marked compile-only then ONLY convert <distdir>.cdl
            if cdl_compile_only:
                alllibname = destlibdir + '/' + destlib + '.cdl'
                if not os.path.exists(alllibname):
                    cdl_compile_only = False
                else:
                    cdlfiles = [alllibname]

            if not cdl_compile_only:
                cdlfiles = os.listdir(srclibdir)
                cdlfiles = list(item for item in cdlfiles if os.path.splitext(item)[1].lower() == '.cdl')

            # The directory with scripts should be in ../common with respect
            # to the Makefile that determines the cwd.

            # Run cdl2spi.py script to read in the CDL file and write out SPICE
            for cdlfile in cdlfiles:
                if ef_format:
                    spiname = os.path.splitext(cdlfile)[0] + '.spi'
                else:
                    spiname = os.path.splitext(cdlfile)[0] + '.spice'
                procopts = [scriptdir + '/cdl2spi.py', srclibdir + '/' + cdlfile, destlibdir + '/' + spiname]
                if do_cdl_scaleu:
                    procopts.append('-dscale=u')
                for item in ignorelist:
                    procopts.append('-ignore=' + item)

                print('Running (in ' + destlibdir + '): ' + ' '.join(procopts))
                pproc = subprocess.run(procopts,
			stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
			stderr = subprocess.PIPE, cwd = destlibdir,
			universal_newlines = True)
                if pproc.stdout:
                    for line in pproc.stdout.splitlines():
                        print(line)
                if pproc.stderr:
                    print('Error message output from cdl2spi.py:')
                    for line in pproc.stderr.splitlines():
                        print(line)

    elif have_gds and not no_gds_convert:
        # If neither SPICE nor CDL formats is available in the source, then
        # read GDS;  if the result has no ports, then read the corresponding
        # LEF library to get port information.  Then write out a SPICE netlist
        # for the whole library.  NOTE:  If there is no CDL or SPICE source,
        # then the port numbering is arbitrary, and becomes whatever the
        # output of this script makes it.

        if ef_format:
            destdir = targetdir + cdl_reflib + 'spi'
            srcdir = targetdir + gds_reflib + 'gds'
            lefdir = targetdir + lef_reflib + 'lef'
            os.makedirs(destdir, exist_ok=True)

        # For each library, create the library subdirectory
        for library in libraries:
            if len(library) == 3:
                destlib = library[2]
            else:
                destlib = library[1]

            if ef_format:
                destlibdir = destdir + '/' + destlib
                srclibdir = srcdir + '/' + destlib
                leflibdir = lefdir + '/' + destlib
            else:
                destdir = targetdir + cdl_reflib + destlib + '/spice'
                srcdir = targetdir + gds_reflib + destlib + '/gds'
                lefdir = targetdir + lef_reflib + destlib + '/lef'

                destlibdir = destdir
                srclibdir = srcdir
                leflibdir = lefdir

            os.makedirs(destlibdir, exist_ok=True)

            # Link to the PDK magic startup file from the target directory
            startup_script = targetdir + mag_current + pdkname + '-F.magicrc'
            if not os.path.isfile(startup_script):
                startup_script = targetdir + mag_current + pdkname + '.magicrc'
            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')

            # Get the consolidated GDS library file, or a list of all GDS files
            # if there is no single consolidated library

            allgdslibname = srclibdir + '/' + destlib + '.gds'
            if not os.path.isfile(allgdslibname):
                glist = glob.glob(srclibdir + '/*.gds')
                glist.extend(glob.glob(srclibdir + '/*.gdsii'))
                glist.extend(glob.glob(srclibdir + '/*.gds2'))

            allleflibname = leflibdir + '/' + destlib + '.lef'
            if not os.path.isfile(allleflibname):
                llist = glob.glob(leflibdir + '/*.lef')

            print('Creating magic generation script to generate SPICE library.') 
            with open(destlibdir + '/generate_magic.tcl', 'w') as ofile:
                print('#!/usr/bin/env wish', file=ofile)
                print('#---------------------------------------------', file=ofile)
                print('# Script to generate SPICE library from GDS   ', 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)

                if not os.path.isfile(allgdslibname):
                    for gdsfile in glist:
                        print('gds read ' + gdsfile, file=ofile)
                else:
                    print('gds read ' + allgdslibname, file=ofile)

                if not os.path.isfile(allleflibname):
                    # Annotate the cells with information from the LEF files
                    for leffile in llist:
                        print('lef read ' + leffile, file=ofile)
                else:
                    print('lef read ' + allleflibname, file=ofile)

                # Load first file and remove the (UNNAMED) cell
                if not os.path.isfile(allgdslibname):
                    print('load ' + os.path.splitext(glist[0])[0], file=ofile)
                else:
                    gdslibroot = os.path.split(allgdslibname)[1]
                    print('load ' + os.path.splitext(gdslibroot)[0], file=ofile)
                # print('cellname delete \(UNNAMED\)', file=ofile)

                print('ext2spice lvs', file=ofile)

                # NOTE:  Leaving "subcircuit top" as "auto" (default) can cause
                # cells like decap that have no I/O to be output without a subcircuit
                # wrapper.  Also note that if this happens, it is an indication that
                # power supplies have not been labeled as ports, which is harder to
                # handle and should be fixed in the source.
                print('ext2spice subcircuit top on', file=ofile)

                print('ext2spice cthresh 0.1', file=ofile)

                if os.path.isfile(allgdslibname):
                    print('select top cell', file=ofile)
                    print('set glist [cellname list children]', file=ofile)
                    print('foreach cell $glist {', file=ofile)
                else:
                    print('foreach cell [cellname list top] {', file=ofile)

                print('    load $cell', file=ofile)
                print('    puts stdout "Extracting cell $cell"', file=ofile)
                print('    extract all', file=ofile)
                print('    ext2spice', file=ofile)
                print('}', 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))

            # Remove intermediate extraction files
            extfiles = glob.glob(destlibdir + '/*.ext')
            for extfile in extfiles:
                os.remove(extfile)

            # If the GDS file was a consolidated file of all cells, then
            # create a similar SPICE library of all cells.

            if os.path.isfile(allgdslibname):
                spiext = '.spice' if not ef_format else '.spi'
                create_spice_library(destlibdir, destlib, spiext, do_compile_only, do_stub, excludelist)

    sys.exit(0)
