macOS, Ruby 3.0.0 の native extension build で '__declspec' attributes are not enabled と怒られて gem がインストールできないとき
環境
- macOS 10.15.7 (Catalina)
- ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
- Apple clang version 12.0.0 (clang-1200.0.32.28)
結論
-fdeclspec オプションをコンパイラに渡してビルドすればOK
$ CC='clang -fdeclspec' gem i byebug
なぜ
事象
Ruby 3.0.0 ではじめて byebug 入れようとしたときに以下のエラーが発生。
$ gem i byebug
Fetching byebug-11.1.3.gem
Building native extensions. This could take a while...
ERROR: Error installing byebug:
ERROR: Failed to build gem native extension.
current directory: /Users/USERNAME/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/byebug-11.1.3/ext/byebug
/Users/USERNAME/.rbenv/versions/3.0.0/bin/ruby -I /Users/USERNAME/.rbenv/versions/3.0.0/lib/ruby/3.0.0 -r ./siteconf20210114-74414-sq50tn.rb extconf.rb
creating Makefile
current directory: /Users/USERNAME/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/byebug-11.1.3/ext/byebug
make "DESTDIR=" clean
current directory: /Users/USERNAME/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/byebug-11.1.3/ext/byebug
make "DESTDIR="
compiling breakpoint.c
In file included from breakpoint.c:1:
In file included from ./byebug.h:4:
In file included from /Users/USERNAME/.rbenv/versions/3.0.0/include/ruby-3.0.0/ruby.h:38:
In file included from /Users/USERNAME/.rbenv/versions/3.0.0/include/ruby-3.0.0/ruby/ruby.h:23:
In file included from /Users/USERNAME/.rbenv/versions/3.0.0/include/ruby-3.0.0/ruby/defines.h:73:
In file included from /Users/USERNAME/.rbenv/versions/3.0.0/include/ruby-3.0.0/ruby/backward/2/attributes.h:43:
In file included from /Users/USERNAME/.rbenv/versions/3.0.0/include/ruby-3.0.0/ruby/internal/attr/pure.h:25:
/Users/USERNAME/.rbenv/versions/3.0.0/include/ruby-3.0.0/ruby/assert.h:132:1: error: '__declspec' attributes are not enabled; use '-fdeclspec' or '-fms-extensions' to enable support for __declspec attributes
RBIMPL_ATTR_NORETURN()
^
/Users/USERNAME/.rbenv/versions/3.0.0/include/ruby-3.0.0/ruby/internal/attr/noreturn.h:29:33: note: expanded from macro 'RBIMPL_ATTR_NORETURN'
# define RBIMPL_ATTR_NORETURN() __declspec(noreturn)
^
...(snip)...
In file included from breakpoint.c:1:
In file included from ./byebug.h:4:
In file included from /Users/USERNAME/.rbenv/versions/3.0.0/include/ruby-3.0.0/ruby.h:38:
In file included from /Users/USERNAME/.rbenv/versions/3.0.0/include/ruby-3.0.0/ruby/ruby.h:26:
In file included from /Users/USERNAME/.rbenv/versions/3.0.0/include/ruby-3.0.0/ruby/internal/core.h:23:
/Users/USERNAME/.rbenv/versions/3.0.0/include/ruby-3.0.0/ruby/internal/core/rarray.h:88:19: error: field has incomplete type 'struct RBasic'
struct RBasic basic;
^
/Users/USERNAME/.rbenv/versions/3.0.0/include/ruby-3.0.0/ruby/internal/core/rstring.h:74:12: note: forward declaration of 'struct RBasic'
struct RBasic basic;
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
6 warnings and 20 errors generated.
make: *** [breakpoint.o] Error 1
make failed, exit code 2
こまった。
解決法
エラーメッセージ読めば書いてある。
どう -fdeclspec を適用するという話だが、gem が Makefile つくるときに extconf.rb で渡せるようにしてあげれば良い。
byebug 見に行くとこうなっているもんで
じゃあ CC 指定すりゃ良いなってことがわかった。
なお sqlite3 も同様にコケたので同じ方法で解決できた。
根本的には?
これ、 gem 側でオプション渡すような改修入れたほうが良いのかな?どうなっているのが理想かよくわからん。