TL;DR としては手元の macOS の clang のバージョン更新を怠っていたので、Ruby の head (2.8.0-dev) でコンパイルエラーが起きていた。久しぶりの Ruby 2.8.0-dev でコンパイルエラーが出たら clang を更新してみましょう。
以下ログ込みで記しておく。
Ruby 2.8.0-dev に話題の Endless method definition が入ったこともあり、一昨日あたりに数日ぶりのアップデートをしたら rbenv install 2.8.0-dev
でコンパイルエラーが起きるようになっていたので、ruby/ruby のリポジトリで再現するか見たところ期待どおり同様のエラーになった。
% cd path/to/ruby/ruby % make distclean (snip) % make check BASERUBY = echo executable host ruby is required. use --with-baseruby option.; false CC = clang -fdeclspec LD = ld LDSHARED = clang -fdeclspec -dynamiclib CFLAGS = -O3 -ggdb3 -Wall -Wextra -Werror=deprecated-declarations -Werror=division-by-zero -Werror=implicit-function-declaration -Werror=implicit-int -Werror=pointer-arith -Werror=shorten-64-to-32 -Werror=write-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Werror=extra-tokens -std=gnu99 -pipe XCFLAGS = -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fno-strict-overflow -DRUBY_DEVEL=1 -fvisibility=hidden -DRUBY_EXPORT -fPIE -DCANONICALIZATION_FOR_MATHN -I. -I.ext/include/x86_64-darwin17 -I./include -I. -I./enc/unicode/12.1.0 CPPFLAGS = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT DLDFLAGS = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -fstack-protector-strong -Wl,-pie -framework Security -framework Foundation SOLIBS = -lpthread -lgmp -ldl -lobjc LANG = ja_JP.UTF-8 LC_ALL = LC_CTYPE = ja_JP.UTF-8 MFLAGS = Apple LLVM version 9.0.0 (clang-900.0.39.2) Target: x86_64-apple-darwin17.7.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin compiling ./main.c In file included from ./main.c:21: In file included from ./include/ruby.h:33: In file included from ./include/ruby/ruby.h:46: ./include/ruby/3/scan_args.h:264:47: error: use of undeclared identifier 'fmt'; did you mean 'fma'? RUBY3_ATTR_DIAGNOSE_IF(rb_scan_args_count(fmt) < 0, "bad scan arg format", "error") ^~~ fma ./include/ruby/3/scan_args.h:102:57: note: expanded from macro 'rb_scan_args_count' #define rb_scan_args_count(fmt) rb_scan_args_count_lead(fmt, 0, 0) ^ ./include/ruby/3/scan_args.h:98:29: note: expanded from macro 'rb_scan_args_count_lead' (!rb_scan_args_isdigit((fmt)[ofs]) ? \ ^ ./include/ruby/3/scan_args.h:67:62: note: expanded from macro 'rb_scan_args_isdigit' #define rb_scan_args_isdigit(c) (RUBY3_CAST((unsigned char)((c)-'0'))<10) ^ ./include/ruby/3/cast.h:31:28: note: expanded from macro 'RUBY3_CAST' # define RUBY3_CAST(expr) (expr) ^ ./include/ruby/3/attr/diagnose_if.h:34:36: note: expanded from macro 'RUBY3_ATTR_DIAGNOSE_IF' __attribute__((__diagnose_if__(_, __, ___))) \ ^ /usr/include/math.h:554:15: note: 'fma' declared here extern double fma(double, double, double); ^ In file included from ./main.c:21: In file included from ./include/ruby.h:33: In file included from ./include/ruby/ruby.h:46: ./include/ruby/3/scan_args.h:264:28: error: subscript of pointer to function type 'double (double, double, double)' RUBY3_ATTR_DIAGNOSE_IF(rb_scan_args_count(fmt) < 0, "bad scan arg format", "error") ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./include/ruby/3/scan_args.h:102:33: note: expanded from macro 'rb_scan_args_count' #define rb_scan_args_count(fmt) rb_scan_args_count_lead(fmt, 0, 0) ^ ./include/ruby/3/scan_args.h:98:28: note: expanded from macro 'rb_scan_args_count_lead' (!rb_scan_args_isdigit((fmt)[ofs]) ? \ ^ ./include/ruby/3/scan_args.h:67:62: note: expanded from macro 'rb_scan_args_isdigit' #define rb_scan_args_isdigit(c) (RUBY3_CAST((unsigned char)((c)-'0'))<10) ^ (snip) ./include/ruby/3/scan_args.h:102:57: note: expanded from macro 'rb_scan_args_count' #define rb_scan_args_count(fmt) rb_scan_args_count_lead(fmt, 0, 0) ^ ./include/ruby/3/scan_args.h:99:29: note: expanded from macro 'rb_scan_args_count_lead' rb_scan_args_count_var(fmt, ofs, vari) : \ ^ ./include/ruby/3/scan_args.h:89:31: note: expanded from macro 'rb_scan_args_count_var' rb_scan_args_count_trail(fmt, ofs, vari) : \ ^ note: (skipping 2 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all) ./include/ruby/3/scan_args.h:75:29: note: expanded from macro 'rb_scan_args_count_block' rb_scan_args_count_end(fmt, (ofs)+1, (vari)+1)) ^ ./include/ruby/3/scan_args.h:70:7: note: expanded from macro 'rb_scan_args_count_end' ((fmt)[ofs] ? -1 : (vari)) ^ ./include/ruby/3/attr/diagnose_if.h:34:36: note: expanded from macro 'RUBY3_ATTR_DIAGNOSE_IF' __attribute__((__diagnose_if__(_, __, ___))) \ ^ /usr/include/math.h:554:15: note: 'fma' declared here extern double fma(double, double, double); ^ fatal error: too many errors emitted, stopping now [-ferror-limit=] 20 errors generated. make: *** [main.o] Error 1
自分の環境のことなので、clang のバージョンが古かろうと見てみたところ version 9.0.0 だった。
% clang --version Apple LLVM version 9.0.0 (clang-900.0.39.2) Target: x86_64-apple-darwin17.7.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
LLVM を更新する。
% brew upgrade llvm (snip) ==> llvm To use the bundled libc++ please add the following LDFLAGS: LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib" llvm is keg-only, which means it was not symlinked into /usr/local, because macOS already provides this software and installing another version in parallel can cause all kinds of trouble. If you need to have llvm first in your PATH run: echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.zshrc For compilers to find llvm you may need to set: export LDFLAGS="-L/usr/local/opt/llvm/lib" export CPPFLAGS="-I/usr/local/opt/llvm/include"
clang のバージョンが 10.0.0 になる。
% clang --version clang version 10.0.0 Target: x86_64-apple-darwin17.7.0 Thread model: posix InstalledDir: /usr/local/opt/llvm/bin
rbenv install 2.8.0-dev
でふたたびインストール可能になった。
% ruby -v ruby 2.8.0dev (2020-04-12T05:58:13Z master a07cbacd23) [x86_64-darwin17]
話題の Endless method definition を動かすとこんな感じ。
% ruby -e 'def greet(name) = puts("Hello, #{name}!"); greet("John Smith")' Hello, John Smith!
ついでに右代入してみる。
% ruby -e '1 + 1 => x; puts x' 2
Enjoy!