環境
Rails 5.2, 6.0
puma 4.3.1, 4.3.4, 4.3.5など
xcode 12.0
xcodeのバージョンは$ xcodebuild -version
で確認できます。
「puma4台インストールできない問題」というよりは「xcode最新版を入れているとpuma4台インストールできない問題」です。
Rails6で開発をしようとしたところ、以下のようなエラーが出てpumaのインストールができませんでした。
(9/13追記)
puma4.3.6で対応したそうです!
アップデートでこの問題は解決しました。
(11/12追記)
Railsチュートリアルでこの事例が起きる場合があるようです。
Gemfileの以下の記述で'4.3.6'
に変更すると解決できると思われます。
gem 'puma', '4.3.6'
エラー文
$ rails new new_app
$ rails new new_app
…(省略)
Fetching bootsnap 1.4.7
Installing bootsnap 1.4.7 with native extensions
Using bundler 2.1.4
Using byebug 11.1.3
Fetching regexp_parser 1.7.1
Installing regexp_parser 1.7.1
Using xpath 3.2.0
Fetching capybara 3.33.0
Installing capybara 3.33.0
Using childprocess 3.0.0
Using ffi 1.13.1
Using jbuilder 2.10.0
Using rb-fsevent 0.10.4
Using rb-inotify 0.10.1
Using listen 3.2.1
Using method_source 1.0.0
Fetching puma 4.3.5
Installing puma 4.3.5 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
current directory:
/Users/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.5/ext/puma_http11
/Users/k_end/.rbenv/versions/2.6.6/bin/ruby -I
/Users/k_end/.rbenv/versions/2.6.6/lib/ruby/2.6.0 -r
./siteconf20200729-76891-111jdf1.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/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.5/ext/puma_http11
make "DESTDIR=" clean
current directory:
/Users/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.5/ext/puma_http11
make "DESTDIR="
compiling http11_parser.c
compiling io_buffer.c
compiling mini_ssl.c
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/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.5 for
inspection.
Results logged to
/Users/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-17/2.6.0/puma-4.3.5/gem_make.out
An error occurred while installing puma (4.3.5), and Bundler cannot
continue.
Make sure that `gem install puma -v '4.3.5' --source 'https://rubygems.org/'`
succeeds before bundling.
In Gemfile:
puma
run bundle binstubs bundler
Could not find gem 'rails (~> 6.0.3, >= 6.0.3.1)' in any of the gem sources
listed in your Gemfile.
run bundle exec spring binstub --all
Could not find gem 'rails (~> 6.0.3, >= 6.0.3.1)' in any of the gem sources listed in your Gemfile.
Run `bundle install` to install missing gems.
rails webpacker:install
Could not find gem 'rails (~> 6.0.3, >= 6.0.3.1)' in any of the gem sources listed in your Gemfile.
Run `bundle install` to install missing gems.
$ bundle install
$ bundle install
…(省略)
Using bundler 2.1.4
Using byebug 11.1.3
Using regexp_parser 1.7.1
Using xpath 3.2.0
Using capybara 3.33.0
Using childprocess 3.0.0
Using ffi 1.13.1
Using jbuilder 2.10.0
Using rb-fsevent 0.10.4
Using rb-inotify 0.10.1
Using listen 3.2.1
Using method_source 1.0.0
Fetching puma 4.3.5
Installing puma 4.3.5 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
current directory: /Users/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.5/ext/puma_http11
/Users/k_end/.rbenv/versions/2.6.6/bin/ruby -I /Users/k_end/.rbenv/versions/2.6.6/lib/ruby/2.6.0 -r ./siteconf20200729-77400-1d4l9f3.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/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.5/ext/puma_http11
make "DESTDIR=" clean
current directory: /Users/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.5/ext/puma_http11
make "DESTDIR="
compiling http11_parser.c
compiling io_buffer.c
compiling mini_ssl.c
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/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.5 for inspection.
Results logged to /Users/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-17/2.6.0/puma-4.3.5/gem_make.out
An error occurred while installing puma (4.3.5), and Bundler cannot continue.
Make sure that `gem install puma -v '4.3.5' --source 'https://rubygems.org/'` succeeds before bundling.
In Gemfile:
puma
$ gem install puma -v '4.3.5' --source 'https://rubygems.org/'
$ gem install puma -v '4.3.5' --source 'https://rubygems.org/'
Building native extensions. This could take a while...
ERROR: Error installing puma:
ERROR: Failed to build gem native extension.
current directory: /Users/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.5/ext/puma_http11
/Users/k_end/.rbenv/versions/2.6.6/bin/ruby -I /Users/k_end/.rbenv/versions/2.6.6/lib/ruby/2.6.0 -r ./siteconf20200729-77587-1dqkt4f.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/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.5/ext/puma_http11
make "DESTDIR=" clean
current directory: /Users/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.5/ext/puma_http11
make "DESTDIR="
compiling http11_parser.c
compiling io_buffer.c
compiling mini_ssl.c
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/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.5 for inspection.
Results logged to /Users/k_end/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-17/2.6.0/puma-4.3.5/gem_make.out
その後、Rubyのバージョンを変えたりbrewのアップデートをしたりRubyを再インストールをしたりopensslを再インストールしたりしてみましたが、解消せず。
しかも、他の人に聞いてみたところ、同じバージョンでも普通にできている。
pumaのバージョンを3台に下げれば動くことはわかったものの、どうにか解決したい。
対処法
結論からいうと、Xcodeの最新バージョンがpumaにエラーを投げているらしい。
以下のコマンドで解消した。
$ bundle config build.puma --with-cflags="-Wno-error=implicit-function-declaration"
$ bundle install
fail to bundle install puma 4.3.5 or gem puma with ruby-2.6.6 on macos-10.15.6 - Stack Overflow
$ bundle config build.puma --with-cflags="-Wno-error=implicit-function-declaration" とは
とりあえずこれでうまく行ったけど、つまり何をやっているのさ?と思ったので、とりあえず自分の理解の範囲で調べてまとめました。
bundle config build.puma
$ bundle config
Settings are listed in order of priority. The top value will be used.
build.puma
Set for the current user (/Users/k_end/.bundle/config): "--with-cflags=-Wno-error=implicit-function-declaration"
path
Set for your local app (/Users/k_end/workspace/personal/paranoia/.bundle/config): "vendor/bundle"
pathに関しては覚えてはいないですが、$ bundle config set path 'vendor/bundle'
でpathを設定していたのだと思います。
bundlerで非推奨になった --path --binstubs - Qiita
Bundlerでビルドオプションを指定する - Qiita
--with-cflags
pumaをビルドするときには、C言語で書かれたファイルをコンパイルしている(エラーではcompiling puma_http11.c
でこけていた)。
--with-cflags
オプションを付けることで、puma_http11.cや他のCファイルを-Wno-error=implicit-function-declaration
オプションを付けてコンパイルします。
-Wno-error=implicit-function-declaration
-Werror-implicit-function-declaration
というのが、「関数が宣言される前に使われている場合にエラーを出」すオプションらしい。そして、「これらの特定の警告オプションのそれぞれには,-Wno-で始まる警告を出力させないための否定形式があります.」ということなので、関数が宣言される前に使われている場合にエラーを出さないということです。
警告を要求/抑止するオプション - フリーソフトウェア徹底活用講座(3)
今回は、#include <ctype.h>
がされていないよ、というコンパイルエラーが出ているので、それをエラーとして出力しないようにしています。
結論
ということで、コンパイル時におけるエラーを発生させないようにしているだけなので、あくまでも応急処置のようなコマンドのようです。
Explicitly include ctype.h to fix compilation warning by venables · Pull Request #2314 · puma/pumaで解決しそうなので、とりあえずマージされるまでは現在のオプションを設定することでしのぎたいと思います。
(9/13追記)
puma4.3.6で対応したそうです!
bundle config --delete build.puma
で先述の設定は削除することができます。