What is the best way to drive Yosys CLI (to use CXXRTL) from Rust?

I maintain a library that exposes hardware designs in Rust backed by dynamically opening libraries generated by Verilator, and I am interested in adding CXXRTL as an alternate “backend”.

I would like to produce a CXXRTL dynamic library from within Rust using only tools common across the installations for Yosys for every package manager (so presumably just the yosys CLI tool).

From what I can see, I’ll need to generate a scriptfile (or use -p) or TCL code. In an ideal world, I would be able to directly interface with Yosys (through e.g. a dynamic library or a dedicated CLI tool like “yosys-cxxrtl") without needing to generate code in another language and handle string escaping (regardless of how trivial it may be). Moreover, I don’t think I was able to successfully escape, for instance, file names with quotes with \, so I’m not sure how to handle a filename like "’!;#.v.

Not sure if that would help you, but I’ve gone down the following road to generate somewhat Verilator-compatible .so’s that work for HW-Cosimulation in Renode:

  • Use a libyosys build (through the C++ API or Cython bindings) to load the designs and write CXXRTL sources
  • Call the compiler to compile them into a .so
  • …and do the .step() dance from your simulation’s scheduler or main loop

Can’t tell much about Rust, but I presume calling at least the C API of CXXRTL shouldn’t cause major issues.

It would be nice to use Yosys as a library as I had said, but I’d want my system to work with the Yosys installed on the user’s computer instead of being built with a specific version. I don’t believe the standard installation methods will install Yosys as a .so? At least, brew install yosys does not. And I intend to support both macOS and Linux distros.

Moreover, I don’t think I was able to successfully escape, for instance, file names with quotes

This is not currently supported, but it is on my list to fix.

The other option here might be to use pyosys? That might be more portable than trying to use a precompiled libyosys, but does mean you’d be interfacing with Python instead of C

After talking with a couple of people much smarter than I am, it seems the best solution is to programmatically generate a TCL script from Rust that loads in generated files containing the list of filenames and include directories I want, then run `yosys` with this script.