upinetree's memo

Web系技術の話題や日常について。

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 見に行くとこうなっているもんで

https://github.com/deivid-rodriguez/byebug/blob/58bb5fde36e33fe9436067014c67351cd8d89cfc/ext/byebug/extconf.rb#L7

じゃあ CC 指定すりゃ良いなってことがわかった。

なお sqlite3 も同様にコケたので同じ方法で解決できた。

根本的には?

これ、 gem 側でオプション渡すような改修入れたほうが良いのかな?どうなっているのが理想かよくわからん。