Bundling platform-specific compiled C binaries

My plugin depends on compiled C binaries to provide certain functionality, I have around 50 MB of binaries per OS per Architecture, bundling it all with the plugin would mean additional 350 MB or so to the archive size.

Is there a recommended way to handle these per-os dependencies on the archive level? Or should I download them in the IDE?

My current approach is showing an inspection about these missing dependencies and then installing them to a directory managed by the plugin that persists IDE updates as a quick fix - alternatively showing a missing dependencies dialog and running the dependency installation through there if a feature requiring these binaries is executed.

I don’t perfectly like requiring the users to click a button each time the dependencies are changed somehow. I was considering first attempting to automatically download the dependencies on IDE start up and only showing the inspection dialog if that fails..

But I’m wondering whether there is some better way to handle installing these dependencies, perhaps a way to distribute per-OS/Arch plugin archives so that I don’t need to bundle everything into a single archive?

I’m looking for some option that would allow me to get rid of the dynamic package installation code and also the code to handle missing dependencies states. If that’s not possible, is there some recommended IntelliJ-like way to handle updating these dependencies without disturbing the user?

Maybe having the plugin implement some custom installation step that is ran when the plugin is installed that would download the dependencies alongside the plugin archive?

1 Like

You basically have to choices:

  • Bundle all into your plugin
  • Download on demand, including updates

There are no os-specific/arch-specific plugins (yet). https://youtrack.jetbrains.com/issue/MP-1896/Add-support-for-OS-specific-plugins
AFAIK there’s no other way.

Bundle into your plugin:
I’m doing this for BashSupport Pro, which contains binaries for Windows, macOS (unified executables) and Linux.
That’s by far the solution with the least troubles as the binaries are always there. No problems with offline setup, network problems, update problems, disk space issues, etc.

For my use-case the binaries compress well in the plugin.zip. You can also try the usual approaches to minimize the binaries (removing debug symbols, strip, using compiler optimizations for size, etc).

Download on demand:
Although you could download without prompting the user, I wouldn’t recommend it. Some users or companies don’t like that (or even prevent it via proxies, etc).

At first, I also downloaded on demand. But in the end I accepted the larger distribution size to gain the much easier installation for users.

1 Like

That’s a good point about some users/companies likely being against that, I haven’t thought of it.

I’ve done some small tests of compressing the binaries to check how much space I can save, it’s quite promising for the pure C binaries I have, only 9MB or so compressing them and I end up having all of them readily available in the IDE, no downloads.

The second dependency of my plugin is esptool - I need a specific version and I don’t want to touch the user’s interpreter, since he might prefer his own esptool version for the project, and I found problems with the new python package API, so I decided to bundle it.

The good thing about it is that most of the code is universal cross-platform python code, however, some dependencies are platform specific.

However, I suppose that I can manually work around that by installing esptool without dependencies, and then feeding it the correct os-specific packages on runtime. This way I have the plugin as a self-sufficient binary and need to do no downloads, the size shouldn’t be that awful at the end either…

I still need a python interpreter though - I currently depend on the project one, but I’ve been considering switching the logic to only prefer the project interpreter, and fallback to looking for any python interpreter on the system - I won’t mutate it, I only need it to run my code and possibly execute pip install –target commands.

Do you have any experience with relying on python interpreters? And could you please tell me what you think about my approach? Would users find a problem with it?

I can share that we are actively working on OS-specific plugin versions and we prepared a PoC for such a mechanism based on existing versions/products limitations in Marketplace (you will need to publish more versions with special markup in plugin.xml) and it works in our experiments with IntelliJ IDEA 2025.3. Unfortunately, there is no proper support in Gradle IntelliJ plugin yet and we are not ready to external plugins using this experimental setup.

Let us get back to you next months when we have something working for Gradle build and publishing.

3 Likes

I don’t have experience with bundling Python scripts.
Unless you require a python project I don’t think that you can safely assume that a user always has Python configured in the IDE.
I’d detect python in $PATH or from the IDE settings and add an (application) setting in the UI to allow the user to set a custom path. If there’s no Python, tell the user in a notification or via the inspection.

1 Like