M1 Macbook ProでRubyGemsのeventmachineをインストールした際に吐かれたSSL関連のビルドエラーについて
仕事で8年ぶりくらいにRubyに触れる機会があり、M1 Macbook ProでRailsの環境を構築中、RubyGemsのeventmachineをインストールしたらSSL関連のビルドエラーが生じたので、その問題解消までのメモを残しておく。
環境
- M1 Macbook Pro (14インチ、2021)
- macOS Monterey バージョン12.6
- anyenv 1.1.5
- rbenv 1.2.0-33-ga6cf6ae
- Ruby 2.7.5
- RubyGems 3.1.6
- eventmachine 1.2.7
エラー内容
$ gem install eventmachine Building native extensions. This could take a while... ERROR: Error installing eventmachine: ERROR: Failed to build gem native extension. current directory: /Users/heroween/.anyenv/envs/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/eventmachine-1.2.7/ext /Users/heroween/.anyenv/envs/rbenv/versions/2.7.5/bin/ruby -I /Users/heroween/.anyenv/envs/rbenv/versions/2.7.5/lib/ruby/2.7.0 -r ./siteconf20221021-64873-1gud8b.rb extconf.rb checking for -lcrypto... no checking for openssl/ssl.h... yes checking for openssl/err.h... yes checking for rb_trap_immediate in ruby.h,rubysig.h... no checking for rb_thread_blocking_region()... no checking for rb_thread_call_without_gvl() in ruby/thread.h... yes checking for rb_thread_fd_select()... yes checking for rb_fdset_t in ruby/intern.h... yes checking for rb_wait_for_single_fd()... yes checking for rb_enable_interrupt()... no checking for rb_time_new()... yes checking for inotify_init() in sys/inotify.h... no checking for __NR_inotify_init in sys/syscall.h... no checking for writev() in sys/uio.h... yes checking for pipe2() in unistd.h... no checking for accept4() in sys/socket.h... no checking for SOCK_CLOEXEC in sys/socket.h... no checking for sys/event.h... yes checking for sys/queue.h... yes checking for clock_gettime()... yes checking for CLOCK_MONOTONIC_RAW in time.h... yes checking for CLOCK_MONOTONIC in time.h... yes CXXFLAGS=-g -O2 -Wall -Wextra -Wno-deprecated-declarations -Wno-ignored-qualifiers -Wno-unused-result -Wno-address creating Makefile current directory: /Users/heroween/.anyenv/envs/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/eventmachine-1.2.7/ext make "DESTDIR=" clean current directory: /Users/heroween/.anyenv/envs/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/eventmachine-1.2.7/ext make "DESTDIR=" compiling binder.cpp compiling cmain.cpp compiling ed.cpp compiling em.cpp compiling kb.cpp compiling page.cpp compiling pipe.cpp compiling rubymain.cpp rubymain.cpp:220:3: warning: 'rb_rescue' is deprecated: Use of ANYARGS in this function is deprecated [-Wdeprecated-declarations] rb_rescue((VALUE (*)(ANYARGS))event_callback, (VALUE)&e, (VALUE (*)(ANYARGS))event_error_handler, Qnil); ^ /Users/heroween/.anyenv/envs/rbenv/versions/2.7.5/include/ruby-2.7.0/ruby/backward/cxxanyargs.hpp:184:1: note: 'rb_rescue' has been explicitly marked deprecated here RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated") ^ /Users/heroween/.anyenv/envs/rbenv/versions/2.7.5/include/ruby-2.7.0/arm64-darwin21/ruby/config.h:152:49: note: expanded from macro 'RUBY_CXX_DEPRECATED' #define RUBY_CXX_DEPRECATED(msg) __attribute__((__deprecated__(msg))) ^ 1 warning generated. compiling ssl.cpp linking shared-object rubyeventmachine.bundle Undefined symbols for architecture arm64: "_BIO_ctrl", referenced from: t_get_peer_cert(unsigned long, unsigned long) in rubymain.o _ssl_verify_wrapper in ssl.o SslBox_t::CanGetCiphertext() in ssl.o SslBox_t::PutPlaintext(char const*, int) in ssl.o "_BIO_free", referenced from: t_get_peer_cert(unsigned long, unsigned long) in rubymain.o SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o _ssl_verify_wrapper in ssl.o "_BIO_new", referenced from: t_get_peer_cert(unsigned long, unsigned long) in rubymain.o SslBox_t::SslBox_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, unsigned long) in ssl.o _ssl_verify_wrapper in ssl.o "_BIO_new_file", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_BIO_new_mem_buf", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_BIO_read", referenced from: SslBox_t::GetCiphertext(char*, int) in ssl.o "_BIO_s_mem", referenced from: t_get_peer_cert(unsigned long, unsigned long) in rubymain.o SslBox_t::SslBox_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, unsigned long) in ssl.o _ssl_verify_wrapper in ssl.o "_BIO_write", referenced from: _ssl_verify_wrapper in ssl.o SslBox_t::PutCiphertext(char const*, int) in ssl.o "_DH_free", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_EC_KEY_free", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_EC_KEY_new_by_curve_name", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_ERR_print_errors_fp", referenced from: SslBox_t::SslBox_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, unsigned long) in ssl.o SslBox_t::GetPlaintext(char*, int) in ssl.o SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) (.cold.2) in ssl.o SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) (.cold.3) in ssl.o SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) (.cold.4) in ssl.o SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) (.cold.5) in ssl.o "_EVP_PKEY_free", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o SslContext_t::~SslContext_t() in ssl.o SslContext_t::~SslContext_t() in ssl.o SslContext_t::~SslContext_t() in ssl.o "_OBJ_sn2nid", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_OPENSSL_init_crypto", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_OPENSSL_init_ssl", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_PEM_read_bio_DHparams", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_PEM_read_bio_PrivateKey", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_PEM_read_bio_X509", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_PEM_write_bio_X509", referenced from: t_get_peer_cert(unsigned long, unsigned long) in rubymain.o _ssl_verify_wrapper in ssl.o "_SSL_CIPHER_get_bits", referenced from: SslBox_t::GetCipherBits() in ssl.o "_SSL_CIPHER_get_name", referenced from: SslBox_t::GetCipherName() in ssl.o "_SSL_CIPHER_get_version", referenced from: SslBox_t::GetCipherProtocol() in ssl.o "_SSL_CTX_ctrl", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_SSL_CTX_free", referenced from: SslContext_t::~SslContext_t() in ssl.o SslContext_t::~SslContext_t() in ssl.o SslContext_t::~SslContext_t() in ssl.o "_SSL_CTX_new", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_SSL_CTX_set_cipher_list", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_SSL_CTX_set_options", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_SSL_CTX_set_session_id_context", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_SSL_CTX_use_PrivateKey", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_SSL_CTX_use_PrivateKey_file", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_SSL_CTX_use_certificate", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_SSL_CTX_use_certificate_chain_file", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_SSL_accept", referenced from: SslBox_t::GetPlaintext(char*, int) in ssl.o "_SSL_clear", referenced from: SslBox_t::~SslBox_t() in ssl.o "_SSL_connect", referenced from: SslBox_t::SslBox_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, unsigned long) in ssl.o SslBox_t::GetPlaintext(char*, int) in ssl.o "_SSL_ctrl", referenced from: SslBox_t::SslBox_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, unsigned long) in ssl.o "_SSL_free", referenced from: SslBox_t::~SslBox_t() in ssl.o "_SSL_get_current_cipher", referenced from: SslBox_t::GetCipherBits() in ssl.o SslBox_t::GetCipherName() in ssl.o SslBox_t::GetCipherProtocol() in ssl.o "_SSL_get_error", referenced from: SslBox_t::GetPlaintext(char*, int) in ssl.o SslBox_t::PutPlaintext(char const*, int) in ssl.o "_SSL_get_ex_data", referenced from: _ssl_verify_wrapper in ssl.o "_SSL_get_ex_data_X509_STORE_CTX_idx", referenced from: _ssl_verify_wrapper in ssl.o "_SSL_get_peer_certificate", referenced from: SslBox_t::GetPeerCert() in ssl.o "_SSL_get_servername", referenced from: SslBox_t::GetSNIHostname() in ssl.o "_SSL_get_shutdown", referenced from: SslBox_t::~SslBox_t() in ssl.o "_SSL_is_init_finished", referenced from: SslBox_t::GetPlaintext(char*, int) in ssl.o SslBox_t::PutPlaintext(char const*, int) in ssl.o "_SSL_new", referenced from: SslBox_t::SslBox_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, unsigned long) in ssl.o "_SSL_read", referenced from: SslBox_t::GetPlaintext(char*, int) in ssl.o "_SSL_set_bio", referenced from: SslBox_t::SslBox_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, unsigned long) in ssl.o "_SSL_set_ex_data", referenced from: SslBox_t::SslBox_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, unsigned long) in ssl.o "_SSL_set_verify", referenced from: SslBox_t::SslBox_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, unsigned long) in ssl.o "_SSL_shutdown", referenced from: SslBox_t::~SslBox_t() in ssl.o "_SSL_write", referenced from: SslBox_t::PutPlaintext(char const*, int) in ssl.o "_TLS_client_method", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_TLS_server_method", referenced from: SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o "_X509_STORE_CTX_get_current_cert", referenced from: _ssl_verify_wrapper in ssl.o "_X509_STORE_CTX_get_ex_data", referenced from: _ssl_verify_wrapper in ssl.o "_X509_free", referenced from: t_get_peer_cert(unsigned long, unsigned long) in rubymain.o SslContext_t::SslContext_t(bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) in ssl.o SslContext_t::~SslContext_t() in ssl.o SslContext_t::~SslContext_t() in ssl.o SslContext_t::~SslContext_t() in ssl.o ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [rubyeventmachine.bundle] Error 1 make failed, exit code 2 Gem files will remain installed in /Users/heroween/.anyenv/envs/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/eventmachine-1.2.7 for inspection. Results logged to /Users/heroween/.anyenv/envs/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/extensions/arm64-darwin-21/2.7.0/eventmachine-1.2.7/gem_make.out
上記エラーメッセージから一部を抜粋すると、以下の様にssl.cppのコンパイルで落ちている事が分かる。
compiling ssl.cpp linking shared-object rubyeventmachine.bundle Undefined symbols for architecture arm64: 〜〜〜 中略 〜〜〜 ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [rubyeventmachine.bundle] Error 1 make failed, exit code 2
ここから、リンカがSSLライブラリを参照出来ていないのではないかと問題のあたりをつけて調べてみた。
調査
rbenvではRubyが依存しているOpenSSLを、Rubyのバージョン毎に個別にインストールしているのだが(昔はHomebrewのOpenSSLに依存していた)、自分の環境だとanyenvとrbenvを使っているので、バージョン2.7.5が依存しているOpenSSLは以下のディレクトリに入っている。
~/.anyenv/envs/rbenv/versions/2.7.5/openssl
そして、RubyGemsでインストールしたeventmachineのソースは、以下のディレクトリに保存される。
~/.anyenv/envs/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/eventmachine-1.2.7/ext
この中にextconf.rbで生成されたMakefileが入っているので、定義されているリンカオプションを確認してみたのだが、LDFLAGSにopenssl/libのパスは見当たらなかった。
ldflags = -L. -L/Users/heroween/.anyenv/envs/rbenv/versions/2.7.5/lib -fstack-protector-strong
これが原因ではないかと推察し、extconf.rbのコードから環境変数「PKG_CONFIG_PATH」が使える感じだったので、ビルド時にHomebrewでインストールしたOpenSSLのpcファイルを参照させてみる事に。
問題解消
MacではmacOS High Sierraから、OpenSSLのハートブリード問題を機に標準のSSLライブラリがLibreSSL(OpenSSL1.0.1からフォークされた)へと代わっており、これを書いている時点ではバージョン2.8.3がインストールされている。
$ openssl version LibreSSL 2.8.3
しかし、Rubyが依存しているのはOpenSSLとなる為、まずはHomebrewを使ってOpenSSLをインストールする。
$ brew install openssl@1.1
ここでバージョン指定しないと現行の最新版であるバージョン3がインストールされるのだが、Ruby 2.7系はOpenSSLのバージョン3に対応していないので、バージョン1.1の方が必要となる。
インストールしたら、環境変数「PKG_CONFIG_PATH」にOpenSSL@1.1のpcファイルのパスを設定するのだが、brew info opsnssl@1.1
コマンドを実行すると、以下の様に環境変数設定のコマンド実行例が出力される。
$ brew info openssl@1.1 ==> openssl@1.1: stable 1.1.1q (bottled) [keg-only] Cryptography and SSL/TLS Toolkit https://openssl.org/ /opt/homebrew/Cellar/openssl@1.1/1.1.1q (8,097 files, 18MB) Poured from bottle on 2022-10-04 at 15:51:35 From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/openssl@1.1.rb License: OpenSSL ==> Dependencies Required: ca-certificates ✔ ==> Caveats A CA file has been bootstrapped using certificates from the system keychain. To add additional certificates, place .pem files in /opt/homebrew/etc/openssl@1.1/certs and run /opt/homebrew/opt/openssl@1.1/bin/c_rehash openssl@1.1 is keg-only, which means it was not symlinked into /opt/homebrew, because macOS provides LibreSSL. If you need to have openssl@1.1 first in your PATH, run: echo 'export PATH="/opt/homebrew/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc For compilers to find openssl@1.1 you may need to set: export LDFLAGS="-L/opt/homebrew/opt/openssl@1.1/lib" export CPPFLAGS="-I/opt/homebrew/opt/openssl@1.1/include" For pkg-config to find openssl@1.1 you may need to set: export PKG_CONFIG_PATH="/opt/homebrew/opt/openssl@1.1/lib/pkgconfig" ==> Analytics install: 712,643 (30 days), 2,287,873 (90 days), 11,108,325 (365 days) install-on-request: 26,710 (30 days), 82,513 (90 days), 390,982 (365 days) build-error: 1,533 (30 days)
上記メッセージの通りにコマンドを実行。
$ export PKG_CONFIG_PATH="/opt/homebrew/opt/openssl@1.1/lib/pkgconfig"
その上で、gem install eventmachine
コマンドを再度実行してみると、今度は問題無くインストールが完了した。
改めて、生成されたMakefileに定義されるLDFLAGSを確認してみたところ、以下の様にopenssl/libのパスが追加されている事が分かる。
ldflags = -L. -L/Users/heroween/.anyenv/envs/rbenv/versions/2.7.5/lib -fstack-protector-strong -L/opt/homebrew/Cellar/openssl@1.1/1.1.1q/lib
という訳で、結論としては、やはりリンカがSSLライブラリを参照出来ていなかったというのが、ビルドエラーの根本原因だったと思われる。
おまけ
rbenvでは、Rubyインストール時のオプションによって、バンドルされたOpenSSLを使うのではなく、HomebrewのOpenSSLを使う事も可能となっている模様。
$ export RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@1.1)"
この環境変数を設定してrbenv install
コマンドを実行した場合は、Rubyと一緒にOpenSSLはインストールされなくなり、最初からHomebrewのOpenSSLに依存する様になる。
この形でインストールしていれば、今回のビルドエラーを回避出来たかもしれないのだが、取り敢えず問題は解消しているので、その検証自体はまた後日にでもやろうと思う。