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!