How to distribute crystal app on macos with no crystal installed?

I know this topic/question has been raised before but I still want to get some clarity and/or new input. My understanding is that it is NOT possible to build a portable binary for crystal app for macos distribution due to the lack of support for static linking on macos. So what are my options for distributing a crystal app to other users on macos with no crystal installed? Would they have no choice but to install crystal (i.e with “brew install crystal”)? Or would they need to just install a set of supporting libs ?
In other words, what are currently the best practice recommendations to distribute crystal apps on macos?

homebrew + bottles. https://docs.brew.sh/Bottles

You can set your dependencies to only be required if building from source, i.e. crystal. Then assuming there is a bottle available, it would just use that and the other non crystal dependencies.

Was a good guide that i used for oq.

1 Like

Thanks for quick reply. I am checking this out. But my question is not about distribution of some custom libraries my app requires and depends on. No, it is about even a basic crystal app with no custom/exotic requirements but rather with the just dependencies on standard crystal libs and maybe a few other “mainstream” shards.
Possibly I am not following completely the article you linked but brew bottles or not one would still need crystal installed to run the pre-compiled crystal app (on macos - with no static linking) Or are you saying it would be necessary and possible to include all standard crystal libs in the brew bottle and somehow ensure they are visible and linked during runtime when app is run?

Right, you only need crystal itself in order to build that binary. If brew is installing a bottle from a binary that was prebuilt on a specific version of OSX, then the common libs it depends on will be on other macs, or can be listed as dependencies and installed via brew, like libxml2, or libevent, etc.

For example (granted I’m not a pro at homebrew, this is just my understanding based on a crystal app i setup a formula for).

In this case jq, libyaml, and libevent are direct dependencies that the binary needs to run. Crystal itself is only needed when building from source. If the user is on mojave or newer, it’ll install the prebuilt binary from the bottle, which means crystal itself isn’t needed since it doesn’t have to build a new binary.

If you were to try this

brew tap blacksmoke16/tap
brew install oq

It should install jq, libyaml, and libevent, but not crystal or any of its dependencies as it’ll use the bottled version.

EDIT: libevent is required by the binary as its used for fiber stuff within crystal, then libyaml is because im using the stdlib’s YAML module which needs libyaml.

1 Like

Thanks for this detailed explanation and example. I think I get it now and I will give it a try and report back :)

2 Likes