blob: d9a0782ae01e289e59b3c43d4b348820cc17b8f2 [file] [log] [blame]
#!/usr/bin/env python3
###############################################################################
## BSD 3-Clause License
##
## Copyright (c) 2022, The Regents of the University of California
## All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are met:
##
## * Redistributions of source code must retain the above copyright notice, this
## list of conditions and the following disclaimer.
##
## * Redistributions in binary form must reproduce the above copyright notice,
## this list of conditions and the following disclaimer in the documentation
## and/or other materials provided with the distribution.
##
## * Neither the name of the copyright holder nor the names of its
## contributors may be used to endorse or promote products derived from
## this software without specific prior written permission.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
## ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
## POSSIBILITY OF SUCH DAMAGE.
# The purpose of this script is to build a symbolic link farm from a
# source PDK according to a JSON mapping file. This is to adapt a PDK
# from a vendor into the form expected by OpenLane without actually
# modifying the source PDK. This is in opposition to the open_pdks
# approach which modifies the vendor PDK to fit.
# This is a transitional tool. Eventually OpenLane scripts will use
# the mapping file to directly access the files without needing the
# link farm. This will free OL from any dependency on PDK organization.
import argparse
import glob
import json
import os
parser = argparse.ArgumentParser(
description="""Builds a link farm from <source> in <dest> according to <mappings>"""
)
parser.add_argument("-s", "--source", required=True)
parser.add_argument("-d", "--destination", required=True)
parser.add_argument("-m", "--mappings", required=True)
parser.add_argument("-v", "--verbose", action="store_true")
args = parser.parse_args()
def link_files(source_path, destination_path):
"""Create a link from source_path to destination path unless
one already exists. If it exists but is different then the
arguments imply an exception is raised."""
destination_dir = os.path.dirname(destination_path)
if not os.path.isdir(destination_dir):
os.makedirs(destination_dir)
if os.path.exists(destination_path):
if (
os.path.islink(destination_path)
and os.path.realpath(destination_path) == source_path
):
if args.verbose:
print(f" Skip {source_path} -> {destination_path}")
return
else:
raise Exception(f"File {destination_path} already exists")
os.symlink(source_path, destination_path)
if args.verbose:
print(f" Link {source_path} -> {destination_path}")
with open(args.mappings) as f:
mappings = json.load(f)
if not os.path.isdir(args.source):
raise Exception(f"{args.source} is not a directory")
source = os.path.abspath(f"{args.source}")
destination = os.path.abspath(f"{args.destination}")
for category, mapping in mappings.items():
print(f"Linking {category}")
pdk = mapping["pdk"]
openlane = mapping["openlane"]
for pattern in mapping["files"]:
pattern = f"{source}/{pdk}/{pattern}"
paths = glob.glob(pattern)
if len(paths) == 0:
raise Exception(f"No matches for {pattern}")
for source_path in paths:
file_name = os.path.basename(source_path)
destination_path = f"{destination}/{openlane}/{file_name}"
link_files(source_path, destination_path)