Rhino Script Compiler and building Python-based plugin on macOS?

Hi! I’m struggling a bit trying to learn how to build Rhino plugins based on Python code on macOS. I think I understand the job of the yak tool, and am able to run it successfully on my Mac, but I’m unclear as to whether rhinoscriptcompiler is needed for the process. Also, no option for “Script Compiler” appears in my Tools menu (Rhino 7.9), and running the rhinoscriptcompiler command generates no output.

Can anyone refer me to some resources explaining the steps to create a distributable package / plugin that is based on Python scripts, and whether or not that process is expected to work on macOS as well as Windows?

Thanks very much in advance!

The script compiler is not currently available on Mac; sorry.

The plugins generated by running the script compiler are able to install and run on Mac; unfortunately the tool itself is currently Windows specific.

Okay, that saves me some struggle! I have access to a Windows machine and can work from there. Is the compiler necessary to create a Python-based plugin, though? In another thread I noticed the folks who make the Tapeworm plugin just seem to zip up some .py files…?

I would recommend using the script compiler. There is an old way of making python “plug-ins” that I wrote years ago that never really became very useful.

Okay, I’ll see what I can do from the Windows machine. Thanks, Steve!

Hi, Steve! I was able to build an experimental one-file Python script as a .yak packaged plugin under Windows using rhinoscriptcompiler. However, I’ve not been able to figure out a way to build a plugin with multiple Python modules. My real code works fine in Rhino when invoked using RunPythonScript, and a bit of sys.path hacking so the imports work, but I don’t see a way to build that into an installable plugin.

I’ve seen in a thread or two that rhinoscriptcompiler doesn’t support Python scripts that span multiple modules, but I’m never sure whether comments like that are still current, or if new features have addressed the limitations.

Can you help me understand exactly what rhinoscriptcompiler is doing with my Python source code, and what my options are for distributing a multi-file Python-based solution in a way that minimizes the chances for user error during installation?

Thank you!

This is still the case that teh script compiler does not support embedding supplementary python module files.

You can get around this issue with a bit of work as long as you use yak as your distribution method (highly recommended). A yak package is a zip file the contains your plug-in as well as any other files that you may want to distribute with your plug-in. When installing a yak package, the zip file is unzipped to a package manager controlled location on your drive. You could have your scripts pay attention to this and adjust paths to get imports to work with extra files shipped via yak.

Ah, thanks! It looks like I will still need a .rhp in the yak-built package, which (as far as I know) I need to use rhinoscriptcompiler to build. Does the .rhc I provide still refer to my “main” Python file – the one that imports the other files? And if so, how does that file know where the other .py files live, for purposes of setting up sys.path appropriately? I tried something like this approach using the file variable to find out the path of the running script, but that variable was undefined when running the Python script that’s part of the .rhp. Thanks again!

The rhp is necessary and will contain an embedded version of your top level python script. Inside of this top level script you could call
path_to_rhp = Rhino.PlugIns.PlugIn.PathFromName("MyPlugInName")

Yes, that’s what I was trying before, when I realized that file wasn’t there. I now have a package building with other .py files in it… hope the path hack will let me import and run them!

On a side note, it seems that yak build always sets rh6_0 as the distribution tag, even though I’m using Rhino 7. Any way to override that, or should I just copy / rename the file to include *rh7_0"?

Thank you again!

Yes, you can rename the yak file to specify distribution

Thanks! Looks like I’m up and running with my test, importing packages after patching in the appropriate path using PathForName as you suggested. I appreciate the super helpful and prompt support!

Hi, @jeff.garbers / @stevebaer and all,

I am so looking forward to Rhino8 with support for external modules in scripcomplier! For now, I was wondering how to help the top-level script to recognize the module using path_to_rhp?

In this quick test, my top-level python script (“mainModule.py”) calls a function from module (“myModule.py).” Once I pack the plug-in, to .yak file with Script Compiler it does not contain any .py files. I place them manually, opening .yak with WinRar and pasting the files in to follow the structure from Rhino - The Anatomy of a Package guide. I am unsure how I would adjust paths in the script to get imports to work with extra files shipped via yak.

Once the yak file is installed, the command is recognized, but nothing happens:

Structure in Packages folder:

Please have a look at the generated package. If you wish to test, rename .zip to .yak as I wasn’t able to upload yak to the forum due to format restrictions:
scriptcompilertest-0.1.0-rh7_0-any.zip (4.0 KB)