The solution of brew link --force is not the best possible way #661

Closed
artyfarty opened this Issue Nov 24, 2015 · 12 comments

Projects

None yet

6 participants

@artyfarty

The solution presented in #643 is not the best one. Brew openssl is not symlinked by default for a reason, so forcing it into /usr/local is not the best idea.

It would be best for gem to actually try looking in brewed openssl folders by itself, but anyway, the safer way to build the gem is this:

gem install eventmachine -v '1.0.8' -- --with-cppflags=-I/usr/local/opt/openssl/include --with-ldflags=-L/usr/local/opt/openssl/lib

Flags can be looked up in brew info openssl.

@sodabrew
Contributor

I absolutely agree, I think it is a very bad idea that people are doing brew link --force openssl. For those using MacPorts, eventmachine picks up openssl from /opt/local automatically, via pkg-config. And there's already a --with-ssl-dir already in the configure script -- but I was having some trouble with it, so I am working on improving this and adding it to the README.

@sodabrew
Contributor
sodabrew commented Dec 8, 2015

@sj26 Following up from your post in #602, could I bug you to try gem install eventmachine -- --with-pkg-config=/usr/local/bin/pkg-config to see if that works? (I don't have an El Capitan machine handy.)

@sj26
sj26 commented Dec 8, 2015

@sodabrew Unfortunately not. I did try that.

The only options to mkmf for pkgconfig are about which binary to use. Openssl is installed by homebrew keg-only (because os x has openssl already). The pkgconfig file is left inside the keg:

$ gem install eventmachine -v "1.0.8"
Building native extensions.  This could take a while...
ERROR:  Error installing eventmachine:
ERROR: Failed to build gem native extension.
# [...snip...]
compiling binder.cpp
In file included from binder.cpp:20:
./project.h:116:10: fatal error: 'openssl/ssl.h' file not found
#include <openssl/ssl.h>
         ^
1 error generated.
make: *** [binder.o] Error 1
# [...snip...]

$ pkg-config openssl --cflags
# => empty

$ pkg-config openssl --debug
Scanning directory '/usr/local/lib/pkgconfig'
# [...snip...]
Scanning directory '/usr/lib/pkgconfig'
# [...snip...]
Will find package 'libssl' in file '/usr/lib/pkgconfig/libssl.pc'
Will find package 'openssl' in file '/usr/lib/pkgconfig/openssl.pc'
# [...snip...]
Scanning directory '/usr/local/Library/ENV/pkgconfig/10.11'
# [...snip...]
Reading 'openssl' from file '/usr/lib/pkgconfig/openssl.pc'
Parsing package file '/usr/lib/pkgconfig/openssl.pc'

$ brew --prefix
/usr/local

$ ls $(brew --prefix)/lib/pkgconfig
# (missing libcrypo.pc libssl.pc openssl.pc)

$ brew --prefix openssl
/usr/local/opt/openssl

$ ls $(brew --prefix openssl)/lib/pkgconfig
libcrypto.pc    libssl.pc   openssl.pc

$ PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig" pkg-config openssl --cflags
-I/usr/local/Cellar/openssl/1.0.2d_1/include

$ PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig" gem install eventmachine -v "1.0.8"
Fetching: eventmachine-1.0.8.gem (100%)
Building native extensions.  This could take a while...
Successfully installed eventmachine-1.0.8
1 gem installed

Unfortunately there is no command line argument equivalent, so we can't provide a bundle build.eventmachine --pkg-config-path="BLAH" or something. You could add something to extconf to understand --pkg-config-path and prefix PKG_CONFIG_PATH before calling pkg_config(...) maybe?

@sodabrew
Contributor
sodabrew commented Dec 8, 2015

Ah, so it's not just finding the right pkg-config binary. I didn't realize the openssl.pc file would also be in the keg. I'd like to make this auto-discovering, I'll try coming up with something that tries setting ENV['PKG_CONFIG_PATH'] as suggested.

@sj26
sj26 commented Dec 9, 2015

Indeed. Any pkg-config binary should actually be fine. It's the PKG_CONFIG_PATH which needs to change.

@tenderlove

Just for other folks that find this from googling, I was able to install eventmachine on El Capitan using trunk Ruby and openssl from homebrew like this:

$ PKG_CONFIG_PATH=/usr/local/Cellar/openssl/1.0.2d_1/lib/pkgconfig gem install eventmachine
@sodabrew
Contributor
sodabrew commented Jan 3, 2016

Doing a more careful clean install of HomeBrew on a clean install of El Capitan, I found that just doing a brew install openssl doesn't pull in pkg-config, so this solution requires an extra dependency for HomeBrew users. It seems like everyone using HomeBrew for serious work ends up having pkg-config installed anyhow, but I'd like to be explicit about it.

Another silly thing I found is that eventmachine's extconf.rb ends up providing options that both disable SSL when compiling, but link against /usr/lib/libssl.0.9.8.dylib and /usr/lib/libcrypto.0.9.8.dylib in the final binary anyways! ๐Ÿณ

I am half tempted to package in a subset of OpenSSL headers to cover the minimum public API that eventmachine needs. As a side effect, it would allow eventmachine Windows builds to use the bundled libssl.dll in the RubyInstaller packages.

@sodabrew
Contributor
sodabrew commented Jan 3, 2016

And like a minute later, I finally noticed that in the OP, @artyfarty suggests brew info openssl which might just work. I can use have_executable('brew') in extconf.rb to detect and configure with HomeBrew:

Tests-Mac-mini:2.0 test$ brew info openssl | grep FLAGS
    LDFLAGS:  -L/usr/local/opt/openssl/lib
    CPPFLAGS: -I/usr/local/opt/openssl/include
@johnpaulashenfelter

It doesn't permanently solve the problem, but I added the path to my bundle config

bundle config build.eventmachine --with-cppflags=-I/usr/local/opt/openssl/include --with-ldflags=-L/usr/local/opt/openssl/lib

which will ensure that on this machine at least, I don't have to remember how to do it ๐Ÿ˜„

@sodabrew sodabrew closed this in #668 Jan 12, 2016
@sodabrew
Contributor

Please try eventmachine-1.0.9, it should compile and install without error on El Capitan. Discuss issues on #668.

@sunboshan

I'm on El Capitan, trying to install eventmachine-1.0.9.1. It gives me the error of

/usr/local/lib/ruby/2.3.0/shellwords.rb:81:in `shellsplit': undefined method `scan' for nil:NilClass (NoMethodError)
    from /usr/local/lib/ruby/2.3.0/mkmf.rb:1828:in `pkg_config'
    from extconf.rb:65:in `pkg_config_wrapper'
    from extconf.rb:92:in `<main>'

After trying different solutions, and a little prayer, this one finally works:

gem install eventmachine -- --with-pkg-config=/usr/local/Cellar/openssl/1.0.2d_1/lib/pkgconfig
@sodabrew
Contributor

I wonder if this is a bug / change in Ruby 2.3.0's handling of pkg_config? I'll look into it. Thanks for reporting! If we need to discuss further let's open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment