小林ノエルのエンジニア日記

フリーランス兼会社員エンジニアが技術とかリモートワークのこととかをツラツラ書いていきます

macにpuma4.3系をインストールしようとしたときにエラーになった時の対応メモ

追記(2020/9/16)

puma4.3.6で解決したようです

したがって4.3.6以降は下記のような対応は不要です。

問題

bundle installでpumaをインストールしようと思ったら下記のようなエラーが出てインストールできなかった。

$ gem install puma -v '4.3.3'
Building native extensions. This could take a while...
ERROR:  Error installing puma:
    ERROR: Failed to build gem native extension.

    current directory: /Users/noel/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/puma-4.3.3/ext/puma_http11
/Users/noel/.rbenv/versions/2.7.1/bin/ruby -I /Users/noel/.rbenv/versions/2.7.1/lib/ruby/2.7.0 -r ./siteconf20200914-35394-zt1e96.rb extconf.rb
checking for BIO_read() in -lcrypto... yes
checking for SSL_CTX_new() in -lssl... yes
checking for openssl/bio.h... yes
checking for DTLS_method() in openssl/ssl.h... yes
checking for TLS_server_method() in openssl/ssl.h... yes
checking for SSL_CTX_set_min_proto_version in openssl/ssl.h... yes
creating Makefile

current directory: /Users/noel/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/puma-4.3.3/ext/puma_http11
make "DESTDIR=" clean

current directory: /Users/noel/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/puma-4.3.3/ext/puma_http11
make "DESTDIR="
compiling http11_parser.c
ext/puma_http11/http11_parser.c:44:18: warning: unused variable 'puma_parser_en_main' [-Wunused-const-variable]
static const int puma_parser_en_main = 1;
                 ^
1 warning generated.
compiling io_buffer.c
compiling mini_ssl.c
mini_ssl.c:145:7: warning: unused variable 'min' [-Wunused-variable]
  int min, ssl_options;
      ^
mini_ssl.c:299:40: warning: function 'raise_error' could be declared with attribute 'noreturn' [-Wmissing-noreturn]
void raise_error(SSL* ssl, int result) {
                                       ^
2 warnings generated.
compiling puma_http11.c
puma_http11.c:203:22: error: implicitly declaring library function 'isspace' with type 'int (int)' [-Werror,-Wimplicit-function-declaration]
  while (vlen > 0 && isspace(value[vlen - 1])) vlen--;
                     ^
puma_http11.c:203:22: note: include the header <ctype.h> or explicitly provide a declaration for 'isspace'
1 error generated.
make: *** [puma_http11.o] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/noel/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/puma-4.3.3 for inspection.
Results logged to /Users/noel/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/extensions/x86_64-darwin-19/2.7.0/puma-4.3.3/gem_make.out

ネットで出てくる記事

ググるとOpenSSL関連のパスが指定できてないからだ的な指摘が多い。

puma gem - Failed to build gem native extension - Stack Overflow

で、実際に下記のコマンドを試してみるが結果は上と同じだった。

$ gem install puma -v '4.3.3' -- --with-opt-dir="$(brew --prefix openssl)"
Building native extensions with: '--with-opt-dir=/usr/local/opt/openssl@1.1'
This could take a while...
ERROR:  Error installing puma:
    ERROR: Failed to build gem native extension.
(中略)
puma_http11.c:203:22: note: include the header <ctype.h> or explicitly provide a declaration for 'isspace'
1 error generated.
make: *** [puma_http11.o] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/noel/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/puma-4.3.3 for inspection.
Results logged to /Users/noel/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/extensions/x86_64-darwin-19/2.7.0/puma-4.3.3/gem_make.out

原因と解決方法

こちらの回答が原因と解決方法を指摘していた。

stackoverflow.com

Cコンパイラの例外を投げる挙動が変わったことによってコンパイル中に例外が発生しているようだった。 したがってbundle config-- --with-cflags="-Wno-error=implicit-function-declaration"を指定してインストールで解決できるようだった。

他のrailsプロジェクトでも同様の問題が発生すると思うので、bundle configで一旦指定しておくのが良さそう。

$ bundle config build.puma --with-cflags="-Wno-error=implicit-function-declaration"
$ bundle install

上記のコマンドで無事にインストールできた。

環境

  • macOS Catalina 10.15.6
  • clang
    • Apple clang version 12.0.0 (clang-1200.0.26.2)
    • Target: x86_64-apple-darwin19.6.0
    • Thread model: posix
    • InstalledDir: /Library/Developer/CommandLineTools/usr/bin
  • rbenv 1.1.2
  • ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]
  • puma 4.3.3