_yosys: add a way to retrieve Yosys data directory.
authorwhitequark <whitequark@whitequark.org>
Sun, 14 Jun 2020 00:04:18 +0000 (00:04 +0000)
committerwhitequark <whitequark@whitequark.org>
Sun, 14 Jun 2020 00:31:34 +0000 (00:31 +0000)
This is important for CXXRTL, since that's where its include files
are located.

nmigen/_yosys.py
setup.py

index 0d1dd7f77420c9c4802a3f3020d69295ec769752..6071d044f833e6af2df715d48d02d5cc753447dc 100644 (file)
@@ -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],
index 85a16e6c091e63466e948aa0908aacdfa6debf8d..fe6bd49512a9dfdf7603706ce8ef7043d9d49f7f 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -25,7 +25,8 @@ setup(
     python_requires="~=3.6",
     setup_requires=["setuptools", "setuptools_scm"],
     install_requires=[
-        "importlib_metadata; python_version<'3.8'", # for nmigen._yosys
+        "importlib_metadata; python_version<'3.8'",  # for nmigen._yosys
+        "importlib_resources; python_version<'3.9'", # for nmigen._yosys
         "pyvcd~=0.2.0", # for nmigen.pysim
         "Jinja2~=2.11", # for nmigen.build
     ],