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

Automatically link to Homebrew openssl #2275

Merged
merged 3 commits into from
Nov 3, 2023
Merged

Conversation

mislav
Copy link
Member

@mislav mislav commented Oct 13, 2023

If a build definition invokes an openssl requirement, but there is no satisfying system OpenSSL version—e.g. always a state of affairs on macOS—automatically query Homebrew-installed versions with brew --prefix openssl@<version> (with a range of versions between "1.1" and "3.1") and automatically link to the latest one found that Ruby is known to be compatible with.

The goal is to skip compiling a per-Ruby version of OpenSSL whenever possible, speeding up Ruby installation and reducing the number of compile dependencies for a typical user, hopefully resulting in fewer "build failed" reports in this repository.

We tried this before by always linking to [email protected], but that was neither future-proof (today is more common to have openssl@3 installed) nor backward compatible as it sabotaged installations of older Ruby versions. #1375

Fixes #2157
Followup to #1974, ref. #1375


Feedback wanted: this PR introduces this syntax:

install_package openssl-1.1.1 "https://..." --if "needs_openssl 1.0.2 3.x.x"

i.e. there is a single function needs_openssl that now takes arbitrary arguments. This replaces the previous set of functions named like needs_openssl_102_300 which weren't future-proof. Now, every build definition explicitly and precisely specifies which openssl versions it wants.

I'm not in love with the new syntax, especially because quotes are necessary to keep the condition function and its arguments as a single argument in bash. But I do like the added functionality! What do you think?

Possible alternative syntaxes:

  • --if "needs_openssl 1.0.2 3.x.x" - I don't like the quotes; it looks like the code in question will get eval'd from string (not true)
  • --if needs_openssl:1.0.2:3.x.x
  • --if needs_openssl:1.0.2-3.x.x
  • --if [email protected]

Keep in mind that the intent here is that this is a more generalized syntax for any --if condition, means that it could facilitate passing different arguments than just version numbers in the future.

bin/ruby-build Outdated Show resolved Hide resolved
@mislav mislav force-pushed the auto-homebrew-openssl branch 2 times, most recently from 183e5b6 to 15098e5 Compare October 14, 2023 21:25
@mislav mislav marked this pull request as ready for review October 14, 2023 21:28
@mislav mislav force-pushed the auto-homebrew-openssl branch from d4ac29d to 8d209e8 Compare October 15, 2023 13:33
@mislav mislav force-pushed the auto-homebrew-openssl branch 2 times, most recently from bf25f06 to 2dcfe58 Compare October 17, 2023 16:01
bin/ruby-build Fixed Show fixed Hide fixed
@mislav
Copy link
Member Author

mislav commented Oct 17, 2023

@hsbt @eregon This is now ready for final review. The change here is that ruby-build will automatically link to a compatible Homebrew OpenSSL on all platforms unless --with-openssl-dir was passed by the user or if the system OpenSSL is already compatible. I suspect that this will have the most positive effect on macOS where Homebrew is really common and system OpenSSL/LibreSSL is useless.

One potential downside of this change is that there is no way to opt out of this mechanism, e.g. if you do have openssl@* installed via Homebrew but do not want ruby-build to automatically link to it (for whatever reason), there is currently no way to instruct ruby-build to continue doing what it did before and download+compile a bundled instance of OpenSSL internally. Should there be an opt-out mechanism?

@eregon I noticed that Truffleruby definitions invoke use_homebrew_openssl on Darwin, which unconditionally links to [email protected] from Homebrew or errors out if not present. Is Truffleruby also compatible with later OpenSSL versions, e.g. OpenSSL v3.x? Could we in theory use some of the new code from this PR to indicate a range of supported OpenSSL versions in Truffleruby definitions? That way, if I have openssl@3 installed with Homebrew but not [email protected], Truffleruby installation would still succeed.

@mislav
Copy link
Member Author

mislav commented Oct 17, 2023

It looks like TruffleRuby looks up Homebrew OpenSSL in $(brew --prefix)/opt/[email protected] and $(brew --prefix)/opt/openssl (the latter is a symlink to the latest-installed openssl@* version), and otherwise this location can be overridden by setting OPENSSL_PREFIX environment variable.

@eregon With all that in mind, it sounds to me that use_homebrew_openssl has very little effect in TruffleRuby build definitions, since its main side effects are that it either

  1. sets RUBY_CONFIGURE_OPTS_ARRAY - this has no effect on TruffleRuby; or
  2. errors out if [email protected] is not installed - however, the user might have openssl@3 installed instead, or specified their own OPENSSL_PREFIX.

I would propose to remove use_homebrew_openssl step from TruffleRuby definitions and to instead extend build_package_truffleruby with extra Darwin-specific logic relating to OpenSSL. Thoughts?

@eregon
Copy link
Member

eregon commented Oct 18, 2023

I would propose to remove use_homebrew_openssl step from TruffleRuby definitions and to instead extend build_package_truffleruby with extra Darwin-specific logic relating to OpenSSL. Thoughts?

Yes, let's remove it.
I don't think we need any logic for this in ruby-build, it's best to let truffleruby handle as it knows better which openssl versions it's compatible with.

@eregon
Copy link
Member

eregon commented Oct 18, 2023

Should there be an opt-out mechanism?

I think it would be safer, yes.
But it could probably be added later, and if there is no issue with the new default then not needed.

Copy link
Member

@eregon eregon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@mislav mislav force-pushed the auto-homebrew-openssl branch 2 times, most recently from 4b59bfd to c6429cb Compare November 2, 2023 12:49
@mislav
Copy link
Member Author

mislav commented Nov 2, 2023

Feedback wanted: this PR introduces this syntax:

install_package openssl-1.1.1 "https://..." --if "needs_openssl 1.0.2 3.x.x"

Update: I went with this syntax in the end, which I find more readable and, most importantly, avoids the use of shell quotes:

install_package openssl-1.1.1 "https://..." --if needs_openssl:1.0.2-3.x.x

Example:

    install_package openssl-1.1 "https://..." --if needs_openssl:1.0.1-3.1.x

In the example, the two values are passed as arguments to the `needs_openssl` function.
If a system OpenSSL version was not found or is at version that is incompatible with a Ruby being installed, ruby-build would typically download and compile a new OpenSSL version scoped to that Ruby installation.

Now the `needs_openssl` condition will also check for Homebrew-installed OpenSSL and automatically link to the first one found that satisfies the version requirement. This primarily helps speed up Ruby installation on macOS where the system OpenSSL is never compatible and where Homebrew is a de-facto standard package manager.
@mislav mislav force-pushed the auto-homebrew-openssl branch from c6429cb to 315373b Compare November 2, 2023 12:53
@mislav mislav merged commit e0b71e7 into master Nov 3, 2023
6 checks passed
@mislav mislav deleted the auto-homebrew-openssl branch November 3, 2023 16:49
@brandonfriess-stripe
Copy link

One potential downside of this change is that there is no way to opt out of this mechanism, e.g. if you do have openssl@* installed via Homebrew but do not want ruby-build to automatically link to it (for whatever reason), there is currently no way to instruct ruby-build to continue doing what it did before and download+compile a bundled instance of OpenSSL internally. Should there be an opt-out mechanism?

Catching up but is there an opt-out mechanism?

@mislav
Copy link
Member Author

mislav commented Dec 6, 2023

@brandonfriess-stripe Not yet, but if you open a new issue detailing how the current mechanism (automatically linking to Homebrew) doesn't work for you, we will consider adding an opt-out mechanism.

I prefer to first understand potential negative ramifications of the current approach before adding options around it. Thank you!

@brandonfriess-stripe
Copy link

Thanks @mislav I opened #2319

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

Successfully merging this pull request may close these issues.

Automatically link to Homebrew openssl
3 participants