wheels: fix missing yosys-abc/share directory

* `misc/__init__.py`:
  * checks if there's a `yosys-abc` in the same directory - if yes, sets the variable `sys._pyosys_abc`
  * checks if there's a `share` in the same directory - if yes, sets the variable `sys._pyosys_share_dirname`
* `yosys.cc::init_share_dirname`: check for `sys._pyosys_share_dirname`, use it at the highest priority if Python is enabled
* `yosys.cc::init_abc_executable_name`: check for `sys._pyosys_abc`, use it at at the highest priority if Python is enabled
* `Makefile`: add new target, `share`, to only create the extra targets
* `setup.py`: compile libyosys.so, yosys-abc and share, and copy them all as part of the pyosys build
* `test/arch/ecp5/add_sub.py`: ported `add_sub.ys` to Python to act as a test for the share directory and abc with Python wheels, used in CI
This commit is contained in:
Mohamed Gaber 2024-10-09 12:44:52 +03:00
parent 8893dadc4b
commit 3d6b8b8e1a
No known key found for this signature in database
6 changed files with 105 additions and 23 deletions

View File

@ -110,7 +110,7 @@ jobs:
MACOSX_DEPLOYMENT_TARGET=11
makeFlags='BOOST_PYTHON_LIB=./boost/pfx/lib/libboost_python*.a CONFIG=clang'
CIBW_BEFORE_BUILD: bash ./.github/workflows/wheels/cibw_before_build.sh
CIBW_TEST_COMMAND: python3 -c "from pyosys import libyosys as ys;d=ys.Design();ys.run_pass('help', d)"
CIBW_TEST_COMMAND: python3 {project}/tests/arch/ecp5/add_sub.py
- uses: actions/upload-artifact@v4
with:
name: python-wheels-${{ matrix.os.runner }}

View File

@ -737,6 +737,12 @@ compile-only: $(OBJS) $(GENFILES) $(EXTRA_TARGETS)
@echo " Compile successful."
@echo ""
.PHONY: share
share: $(EXTRA_TARGETS)
@echo ""
@echo " Share directory created."
@echo ""
$(PROGRAM_PREFIX)yosys$(EXE): $(OBJS)
$(P) $(CXX) -o $(PROGRAM_PREFIX)yosys$(EXE) $(EXE_LINKFLAGS) $(LINKFLAGS) $(OBJS) $(LIBS) $(LIBS_VERIFIC)

View File

@ -554,7 +554,7 @@ void yosys_setup()
#include "kernel/constids.inc"
#undef X
#ifdef WITH_PYTHON
#ifdef WITH_PYTHON
// With Python 3.12, calling PyImport_AppendInittab on an already
// initialized platform fails (such as when libyosys is imported
// from a Python interpreter)
@ -564,7 +564,7 @@ void yosys_setup()
PyRun_SimpleString("import sys");
signal(SIGINT, SIG_DFL);
}
#endif
#endif
Pass::init_register();
yosys_design = new RTLIL::Design;
@ -1013,6 +1013,16 @@ void init_share_dirname()
#else
void init_share_dirname()
{
# ifdef WITH_PYTHON
PyObject *sys_obj = PyImport_ImportModule("sys");
if (PyObject_HasAttrString(sys_obj, "_pyosys_share_dirname")) {
PyObject *share_path_obj = PyObject_GetAttrString(sys_obj, "_pyosys_share_dirname");
const char *share_path = PyUnicode_AsUTF8(share_path_obj);
yosys_share_dirname = std::string(share_path);
return;
}
# endif
std::string proc_self_path = proc_self_dirname();
# if defined(_WIN32) && !defined(YOSYS_WIN32_UNIX_DIR)
std::string proc_share_path = proc_self_path + "share\\";
@ -1058,12 +1068,20 @@ void init_abc_executable_name()
}
#else
yosys_abc_executable = proc_self_dirname() + proc_program_prefix()+ "yosys-abc";
#endif
#ifdef _WIN32
#ifndef ABCEXTERNAL
# ifdef _WIN32
if (!check_file_exists(yosys_abc_executable + ".exe") && check_file_exists(proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc.exe"))
yosys_abc_executable = proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc";
#endif
# endif
# ifdef WITH_PYTHON
PyObject *sys_obj = PyImport_ImportModule("sys");
if (PyObject_HasAttrString(sys_obj, "_pyosys_abc")) {
PyObject *abc_path_obj = PyObject_GetAttrString(sys_obj, "_pyosys_abc");
const char *abc_path = PyUnicode_AsUTF8(abc_path_obj);
yosys_abc_executable = std::string(abc_path);
}
# endif
#endif
}

View File

@ -1,5 +1,19 @@
import os
import sys
sys.setdlopenflags(os.RTLD_NOW | os.RTLD_GLOBAL)
__dir__ = os.path.abspath(os.path.dirname(__file__))
sys._pyosys_dir = os.path.abspath(__dir__)
bin_ext = ".exe" if os.name == "nt" else ""
_share_candidate = os.path.join(__dir__, "share")
if os.path.isdir(_share_candidate):
sys._pyosys_share_dirname = _share_candidate + os.path.sep
_abc_candidate = os.path.join(__dir__, f"yosys-abc{bin_ext}")
if os.path.isfile(_abc_candidate):
sys._pyosys_abc = _abc_candidate
__all__ = ["libyosys"]

View File

@ -44,26 +44,50 @@ class libyosys_so_ext(Extension):
"ENABLE_PYTHON_CONFIG_EMBED=0",
# Would need to be installed separately by the user
"ENABLE_TCL=0",
# Would need to be installed separately by the user
"ENABLE_READLINE=0",
"ENABLE_EDITLINE=0",
# Always compile and include ABC in wheel
"ABCEXTERNAL=",
# Show compile commands
"PRETTY=0",
]
def custom_build(self, bext: build_ext):
bext.spawn(
["make", f"-j{os.cpu_count() or 1}", self.name]
[
"make",
f"-j{os.cpu_count() or 1}",
self.name,
"yosys-abc",
"share",
]
+ shlex.split(os.getenv("makeFlags", ""))
+ self.args
)
build_path = os.path.dirname(os.path.dirname(bext.get_ext_fullpath(self.name)))
pyosys_path = os.path.join(build_path, "pyosys")
target = os.path.join(pyosys_path, os.path.basename(self.name))
os.makedirs(pyosys_path, exist_ok=True)
shutil.copyfile(self.name, target)
# libyosys.so
target = os.path.join(pyosys_path, os.path.basename(self.name))
shutil.copy(self.name, target)
bext.spawn(["strip", "-S", target])
# yosys-abc
yosys_abc_target = os.path.join(pyosys_path, "yosys-abc")
shutil.copy("yosys-abc", yosys_abc_target)
bext.spawn(["strip", "-S", "yosys-abc"])
# share directory
share_target = os.path.join(pyosys_path, "share")
try:
shutil.rmtree(share_target)
except FileNotFoundError:
pass
shutil.copytree("share", share_target)
# I don't know how debug info is getting here.
bext.spawn(["strip", "-S", target])
class custom_build_ext(build_ext):

View File

@ -0,0 +1,20 @@
import os
from pyosys import libyosys as ys
__dir__ = os.path.dirname(os.path.abspath(__file__))
add_sub = os.path.join(__dir__, "..", "common", "add_sub.v")
base = ys.Design()
ys.run_pass(f"read_verilog {add_sub}", base)
ys.run_pass("hierarchy -top top", base)
ys.run_pass("proc", base)
ys.run_pass("equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5", base)
postopt = ys.Design()
ys.run_pass("design -load postopt", postopt)
ys.run_pass("cd top", postopt)
ys.run_pass("select -assert-min 25 t:LUT4", postopt)
ys.run_pass("select -assert-max 26 t:LUT4", postopt)
ys.run_pass("select -assert-count 10 t:PFUMX", postopt)
ys.run_pass("select -assert-count 6 t:L6MUX21", postopt)
ys.run_pass("select -assert-none t:LUT4 t:PFUMX t:L6MUX21 %% t:* %D", postopt)