Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for precompiled binaries? #165

Open
thbar opened this issue Sep 23, 2020 · 34 comments
Open

Support for precompiled binaries? #165

thbar opened this issue Sep 23, 2020 · 34 comments

Comments

@thbar
Copy link

thbar commented Sep 23, 2020

When working on projects using asdf, I typically use Erlang in addition to Elixir and NodeJS, for instance.

Both Elixir and NodeJS are very quick to install, while Erlang is much, much longer (a typical install on a modern Mac machine takes around 5 minutes).

This also impacts Docker builds, even in harder ways depending on your configuration (could take 10 minutes), and are more ephemeral (so more likely to be rebuilt). It was so slow that on one project using the 3 asdf plugins mentioned above for local development, I had to skip asdf-erlang in the Docker build and instead install the binaries for Erlang manually.

I wonder if we could evolve this plugin in order to optionally support using the binaries now available at https://www.erlang-solutions.com/resources/download.html (at least for Linux/Mac OS X)?

Just a thought, I wonder what your position is on that.

Thanks for your work on asdf-erlang btw!

@chulkilee
Copy link

https://www.erlang-solutions.com/resources/download.html does not provide easy-to-use prebuilt package for macOS.

This also impacts Docker builds, even in harder ways depending on your configuration (could take 10 minutes), and are more ephemeral (so more likely to be rebuilt)

Could you explain why your docker build does not leverage cache? For example, you can even use multi-stage docker build and copy erlang to maximize caching.

@archan937
Copy link

Hi, @chulkilee. Can you give an example of such a multi-stage docker build with copying erlang to maximize caching? I have no clue which directories I need to copy.

Can it also support multiple Erlang versions?

@wojtekmach
Copy link

FYI I'm working on adding binary releases upstream so if that lands you could use it here, see: erlang/otp#2936

@thbar
Copy link
Author

thbar commented Dec 17, 2020

@chulkilee

Could you explain why your docker build does not leverage cache? For example, you can even use multi-stage docker build and copy erlang to maximize caching.

Because I bump the version of OTP on a regular basis, for instance, causing the layer to be invalidated (it cannot be cached).

@chulkilee
Copy link

@archan937 check out configure option - you can install all files at own directory (e.g. /opt/erlang) instead of default (e.g. /usr/local) - just don't forget to add the bin path there.

@thbar I also update erlang regularly (as soon as new version is released), but it only takes 15 minutes one time for all projects, not 15 minutes for all projects, since I share one base docker image, and all projects just using the base image. BTW my base image does not use asdf-erlang though...

@thbar
Copy link
Author

thbar commented Dec 18, 2020

@chulkilee it is nice that it works nicely for you. You have "economies of scale" in your context, which is nice, and which is also not my case. I cannot share a base image in my context (that's how it is), and I cannot mutualise the build step between projects either efficiently (they belong to different clients), so for me this usually means 15 minutes (or more on occasions depending on the machine) per update, per project and also per developer.

I also think, having coached new Elixir programmers, that this quite hinders the newcomer experience to Elixir. The Elixir install is super fast, and Erlang takes ages. Having something precompiled would make for a better "try this" experience IMO.

@chulkilee
Copy link

I feel the pain! Yeah I'm also looking for precompiled binaries... 😉 I believe @wojtekmach and Erlang Ecosystem Foundation are working on that matter...

Here are some notes (as far as you can run docker pull in your cases):

  • You don't need to share the base image with explicit tagging. You just need to use the exactly same steps after pulling the image using them. You may need to use --cache-from option of docker build as well. By doing so, you can leverage docker caching on dev laptops and CI as well.
  • Consider open-sourcing your "base" docker image, to reuse them freely across clients or projects. It allows making changes as needed, without waiting for official images. Here is my example for using Red Hat UBI - https://gitlab.com/chulkilee/docker-images - I have similar thing at work to push images to the internal repo.

One question to @wojtekmach

The compiled result by asdf-erlang on my mac - can it be freely copied to other mac under different path (e.g. different user name), as far as it has all the same packages (e.g. openssl from brew)?

@wojtekmach
Copy link

The compiled result by asdf-erlang on my mac - can it be freely copied to other mac under different path (e.g. different user name), as far as it has all the same packages (e.g. openssl from brew)?

I haven't tried but I think it should be possible but it may require some manual steps. I believe part of the problem is some paths are hardcoded, e.g.:

$ cat ~/.asdf/installs/erlang/23.2/bin/erl | grep ROOTDIR=
ROOTDIR="/Users/wojtek/.asdf/installs/erlang/23.2"

There's ongoing work on making that easier: erlang/otp#2879.

@JeromeDeBretagne
Copy link

I believe part of the problem is some paths are hardcoded, e.g.:

$ cat ~/.asdf/installs/erlang/23.2/bin/erl | grep ROOTDIR=
ROOTDIR="/Users/wojtek/.asdf/installs/erlang/23.2"

There's ongoing work on making that easier: erlang/otp#2879.

FYI a first solution is already available with erlang/otp#2863. The idea is to pass the different rootdir path in the ERL_ROOTDIR environment variable, as a way to override at runtime the hardcoded ROOTDIR in the script(s) from the compiled binaries. This was implemented mainly for a specific use case but it could be temporarily an option for your need.

The purpose of erlang/otp#2879 is exactly to answer such a need, once for all in a generic way and with no manual steps required anymore.

@seivan
Copy link

seivan commented Mar 28, 2021

I added support for precompiled binaries here #190 but only for macOS as of today.

@thbar
Copy link
Author

thbar commented Apr 8, 2021

I have tested it today. Many thanks @seivan!

One caveat is that without upgrading asdf, things would continue compiling instead of using the binary version.

@thbar
Copy link
Author

thbar commented Apr 8, 2021

I spoke too soon, it is actually still grabbing the source version and compiling it. I will investigate.

@seivan
Copy link

seivan commented Apr 8, 2021

One caveat is that without upgrading asdf, things would continue compiling instead of using the binary version.

@thbar I don't quite understand, you mean without upgrading asdf itself or the forked plugin?
Keep in mind if it can't find the version for your arch and major macOS marketing version it will fallback to source.
Do you happen to see it mentioning going the fallback route in the terminal?

@thbar
Copy link
Author

thbar commented Apr 8, 2021

@seivan sorry, as commented above, I'm not sure anymore of anything. I will investigate and will report back!

@michallepicki
Copy link

michallepicki commented Apr 14, 2021

For linux precompiled binaries, since it doesn't look like the Erlang/OTP team will provide the binaries, would it make sense to use the builds packaged by the hex team? This is what the setup-beam action uses

edit: Here's a list of currently available builds for Ubuntu 20.04: https://repo.hex.pm/builds/otp/ubuntu-20.04/builds.txt

@thbar
Copy link
Author

thbar commented Apr 28, 2021

Heads-up: #190 has not been merged but closed, so if you try to understand why you do not get precompiled binaries, this is the reason.

Thanks to @seivan still, I'm pretty sure the whole ecosystem is going somewhere with this (see various efforts), and your branch has been a useful inspiration!

@michallepicki
Copy link

michallepicki commented May 28, 2021

Regarding precompiled binaries for Ubuntu 18.04 and 20.04, I pursued my idea mentioned earlier, and I don't know if this is a correct approach (or if it's safe to use), but I forked asdf-elixir and made a few changes to it so that instead of downloading Elixir from repo.hex.pm, it downloads installs Erlang. Here are the repositories if someone wants to give it a try:
michallepicki/asdf-erlang-prebuilt-ubuntu-18.04
michallepicki/asdf-erlang-prebuilt-ubuntu-20.04

edit:
Now also 22.04 for Erlang 24.2 and newer (no openssl 3 support in earlier Erlang versions):
michallepicki/asdf-erlang-prebuilt-ubuntu-22.04

edit2:
And for 24.04+:
michallepicki/asdf-erlang-prebuilt-ubuntu-24.04

@Stratus3D
Copy link
Member

Note to self: Refer to @michallepicki's plugins when implement. Also follow https://elixirforum.com/t/asdf-erlang-plugins-with-precompiled-erlang-for-ubuntu/40124

@wojtekmach
Copy link

I opened a PR which would publish the macOS builds on OTP GitHub releases: erlang/otp#5723

@Stratus3D
Copy link
Member

What do you all think of this?

By default:

  • First try hex.pm for the version of Erlang (what the setup-beam action does, and what @michallepicki has done with his forks)
  • If version/OS combination not found, try https://www.erlang-solutions.com/downloads/ (I'm not yet sure how we'd programmatically determine whether they offered the correct version)
  • If version/OS combination not found, compile from source using kerl (as we currently do)

If the users specifies a flag indicating they want to force a compilation, then we only use kerl.

@michallepicki
Copy link

The above plan looks good to me

For Linux, to use the existing builds by Bob and The Hex Team (it could be a band name) I think the plugin needs to confirm x86-64 architecture, distribution and if it’s Ubuntu based then pick latest LTS version for user’s version (e.g. for 21.10 pick 20.04).

Also see a related discussion on erlef/build-and-packaging-wg#27

@loics2
Copy link

loics2 commented Jun 8, 2024

Is there any news on this?

@paulo-ferraz-oliveira
Copy link

If opt-in (to use pre-compiled) would be possible, it'd be nice. One of the features I like about asdf is the fact it takes .kerlrc or other env.-based config. options into account.

How would that look when using pre-compiled builds? Or maybe we could get away with a large-scope-enough superset of options that'd adapt to that use case? (is that what Elixir gets, in asdf?) Or maybe if e.g. .kerlrc or env. config. options were passed it'd take those into account and compile, otherwise just download the pre-compiled artefacts?

@wojtekmach
Copy link

In my opinion when images are available (i.e. user is on macOS and installs OTP 25+) they should be downloaded by default and user would opt-in to compile from scratch, I think the majority of users definitely do not want to compile from scratch and default should reflect that.

Btw there is a parallel discussion here: erlef/otp_builds#24

@ryanjafari
Copy link

Agreed @wojtekmach thank you

@lpil
Copy link

lpil commented Nov 19, 2024

I think it'd be unusual for your typical user to take the time to read the documentation and learn that they can opt-in for precompiled binaries, so having them by default would be beneficial.

@paulo-ferraz-oliveira
Copy link

paulo-ferraz-oliveira commented Nov 20, 2024

Then that aligns with my last sentence, which seems to contradict the first one: "Or maybe if e.g. .kerlrc or env. config. options were passed it'd take those into account and compile, otherwise just download the pre-compiled artefacts?"

I'd like to know (whether opt-in or opt-out) if options are being considered or how this'd look like basically.

@hez
Copy link

hez commented Nov 20, 2024

Anyone following: https://elixirforum.com/t/new-community-maintained-otp-builds-for-macos/67338 and https://github.com/michallepicki/asdf-erlang-prebuilt-macos

We are trying this out right now, all appears good!

@mfilej
Copy link

mfilej commented Nov 28, 2024

Just tried this out and I'm holding back tears of joy.

For mise users: you can even configure an alias globally, so that installing erlang always uses prebuilt binaries:

mise config set alias.erlang "asdf:michallepicki/asdf-erlang-prebuilt-macos" 

@pepicrft
Copy link

pepicrft commented Dec 1, 2024

Just tried this out and I'm holding back tears of joy.

For mise users: you can even configure an alias globally, so that installing erlang always uses prebuilt binaries:

mise config set alias.erlang "asdf:michallepicki/asdf-erlang-prebuilt-macos" 

This is amazing. Do you know if there's an equivalent to the above for Linux?

@mfilej
Copy link

mfilej commented Dec 2, 2024

@pepicrft Yes, depending on your flavor of Linux I guess.

I don't run Linux, but I tried this in a VM just now:

$ mise config set alias.erlang "asdf:michallepicki/asdf-erlang-prebuilt-ubuntu-24.04"
$ time mise i [email protected]
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 67.8M  100 67.8M    0     0  9387k      0  0:00:07  0:00:07 --:--:-- 9849k
mise [email protected] ✓ installed                                                                                                   
real	0m8.691s
user	0m1.285s
sys	0m0.590s

There are also a repos for ubuntu-{22,20,18} — they might work on other distros, but I'm not sure.

@wojtekmach
Copy link

@michallepicki have you considered having just one asdf plugin for ubuntu precompiled builds? I think this is a reliable way determine the version one is running at the runtime which should be all you need to find approbate bob builds:

~% docker run --rm -it ubuntu cat /etc/os-release | grep VERSION_ID
VERSION_ID="24.04"
~% docker run --rm -it ubuntu:24.10 cat /etc/os-release | grep VERSION_ID
VERSION_ID="24.10"
~% docker run --rm -it ubuntu:18.04 cat /etc/os-release | grep VERSION_ID
VERSION_ID="18.04"

@michallepicki
Copy link

michallepicki commented Dec 2, 2024

@wojtekmach see https://github.com/cranksecurity/asdf-erlang-prebuilt-ubuntu and michallepicki/asdf-erlang-prebuilt-ubuntu-22.04#2

I think it would be great if the plugin could also work for non-LTS Ubuntu versions (e.g. for 23.10 pick 22.04 etc) and other Ubuntu-based OSes (e.g. Linux Mint, elementary OS, Pop_OS! etc)

@wojtekmach
Copy link

@michallepicki ah, of course, nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests