From 7c09744c35984699a33e6bf9b3f1d69758543d90 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 14 Jun 2020 00:04:18 +0000 Subject: [PATCH] _yosys: add a way to retrieve Yosys data directory. This is important for CXXRTL, since that's where its include files are located. --- nmigen/_yosys.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/nmigen/_yosys.py b/nmigen/_yosys.py index 0d1dd7f..6071d04 100644 --- a/nmigen/_yosys.py +++ b/nmigen/_yosys.py @@ -3,6 +3,7 @@ import sys import re import subprocess import warnings +import pathlib try: from importlib import metadata as importlib_metadata # py3.8+ stdlib except ImportError: @@ -10,6 +11,14 @@ except ImportError: import importlib_metadata # py3.7- shim except ImportError: importlib_metadata = None # not installed +try: + from importlib import resources as importlib_resources + try: + importlib_resources.files # py3.9+ stdlib + except AttributeError: + import importlib_resources # py3.8- shim +except ImportError: + import importlib_resources # py3.6- shim from ._toolchain import has_tool, require_tool @@ -53,6 +62,17 @@ class YosysBinary: """ raise NotImplementedError + @classmethod + def data_dir(cls): + """Get Yosys data directory. + + Returns + ------- + data_dir : pathlib.Path + Yosys data directory (also known as "datdir"). + """ + raise NotImplementedError + @classmethod def run(cls, args, stdin=""): """Run Yosys process. @@ -107,6 +127,10 @@ class _BuiltinYosys(YosysBinary): match = re.match(r"^(\d+)\.(\d+)(?:\.post(\d+))?", version) return (int(match[1]), int(match[2]), int(match[3] or 0)) + @classmethod + def data_dir(cls): + return importlib_resources.files(cls.YOSYS_PACKAGE) / "share" + @classmethod def run(cls, args, stdin="", *, ignore_warnings=False, src_loc_at=0): popen = subprocess.Popen([sys.executable, "-m", cls.YOSYS_PACKAGE, *args], @@ -129,6 +153,16 @@ class _SystemYosys(YosysBinary): match = re.match(r"^Yosys (\d+)\.(\d+)(?:\+(\d+))?", version) return (int(match[1]), int(match[2]), int(match[3] or 0)) + @classmethod + def data_dir(cls): + popen = subprocess.Popen([require_tool(cls.YOSYS_BINARY) + "-config", "--datdir"], + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + encoding="utf-8") + stdout, stderr = popen.communicate() + if popen.returncode: + raise YosysError(stderr.strip()) + return pathlib.Path(stdout.strip()) + @classmethod def run(cls, args, stdin="", *, ignore_warnings=False, src_loc_at=0): popen = subprocess.Popen([require_tool(cls.YOSYS_BINARY), *args], -- 2.30.2