gem install ffi が error: unsupported option '-print-multi-os-directory' で失敗するときの対処法


**2018-12-23追記**
**解決方法が見つかった → [gem ffi のインストールに失敗するときのコンパイラオプション指定方法](https://qiita.com/ts-3156/items/cb2aba33e0bd9d088f4f)**

最新版のMac（10.13.6）では、gem install ffiに失敗する。古いバージョンのffiを指定することで暫定的な対処はできる。

```
gem 'ffi', '1.9.21' # https://github.com/ffi/ffi/issues/640
```

## 原因

gem installの失敗時に表示される下記のエラーが原因の模様。

```
clang: error: unsupported option '-print-multi-os-directory'
clang: error: no input files
```

MacではAppleが用意したCコンパイラを標準で使うが、バージョンが古かったりGCCと仕様が違ったりしており、こういうエラーが表示されることがある。

## 古いバージョンを指定した時に起きる新しい問題

Macでは関係ないものの、下記の脆弱性があるらしく、Githubで警告が出る状態になってしまう。

```
ruby-ffi version 1.9.23 and earlier has a DLL loading issue which can be hijacked on
Windows OS, when a Symbol is used as DLL name instead of a String This vulnerability
appears to have been fixed in v1.9.24 and later.
```

https://nvd.nist.gov/vuln/detail/CVE-2018-1000201

## 諦めずに解決する方法（案）

自分でGCCをインストールしてシンボリックリンクをはってみたものの、gem installの時に使われるコンパイラに変化がなく解決できなかった。

諦めずに自分で解決する場合は、まず上記のオプションを解釈できるバージョンのGCCをインストールし、下記のどれかを試せばよいと思われる。

- 案1：コンパイラ及び関連するコマンドすべてに自分でシンボリックリンクをはる
- 案2：gem installの時に使うコンパイラのみにGCCを指定する
- 案2：bundle updateの時に使うコンパイラのみにGCCを指定する

## エラー内容

```
Building native extensions. This could take a while...
ERROR:  Error installing ffi:
	ERROR: Failed to build gem native extension.

    current directory: /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c
/Users/xxx/.rbenv/versions/2.5.0/bin/ruby -r ./siteconf20180902-49566-ifv9kx.rb extconf.rb
checking for ffi.h... no
checking for ffi.h in /usr/local/include,/usr/include/ffi... yes
checking for ffi_call() in -lffi... yes
checking for ffi_closure_alloc()... no
checking for ffi_raw_call()... no
checking for shlwapi.h... no
checking for ruby/thread.h... yes
checking for rb_thread_blocking_region()... no
checking for rb_thread_call_with_gvl()... yes
checking for rb_thread_call_without_gvl()... yes
creating extconf.h
creating Makefile

current directory: /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c
make "DESTDIR=" clean

current directory: /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c
make "DESTDIR="
Configuring libffi
clang: error: unsupported option '-print-multi-os-directory'
clang: error: no input files
cd "/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi-x86_64-darwin17" && /Library/Developer/CommandLineTools/usr/bin/make
/Library/Developer/CommandLineTools/usr/bin/make 'AR_FLAGS=' 'CC_FOR_BUILD=' 'CFLAGS=-Wall -fexceptions' 'CXXFLAGS=-g -O2' 'CFLAGS_FOR_BUILD=' 'CFLAGS_FOR_TARGET=' 'INSTALL=/usr/local/opt/coreutils/libexec/gnubin/install -c' 'INSTALL_DATA=/usr/local/opt/coreutils/libexec/gnubin/install -c -m 644' 'INSTALL_PROGRAM=/usr/local/opt/coreutils/libexec/gnubin/install -c' 'INSTALL_SCRIPT=/usr/local/opt/coreutils/libexec/gnubin/install -c' 'JC1FLAGS=' 'LDFLAGS=' 'LIBCFLAGS=' 'LIBCFLAGS_FOR_TARGET=' 'MAKE=/Library/Developer/CommandLineTools/usr/bin/make' 'MAKEINFO=/bin/sh /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/missing makeinfo ' 'PICFLAG=' 'PICFLAG_FOR_TARGET=' 'RUNTESTFLAGS=' 'SHELL=/bin/sh' 'exec_prefix=/usr/local' 'infodir=/usr/local/share/info' 'libdir=/usr/local/lib' 'mandir=/usr/local/share/man' 'prefix=/usr/local' 'AR=ar' 'AS=as' 'CC=clang' 'CXX=g++' 'LD=ld' 'NM=/usr/bin/nm -B' 'RANLIB=ranlib' 'DESTDIR=' all-recursive
Making all in include
make[3]: Nothing to be done for `all'.
Making all in testsuite
make[3]: Nothing to be done for `all'.
Making all in man
make[3]: Nothing to be done for `all'.
/bin/sh ./libtool  --tag=CC   --mode=compile clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi  -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src   -Wall -fexceptions -c -o src/prep_cif.lo /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/prep_cif.c
libtool: compile:  clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/prep_cif.c  -fno-common -DPIC -o src/.libs/prep_cif.o
/bin/sh ./libtool  --tag=CC   --mode=compile clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi  -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src   -Wall -fexceptions -c -o src/types.lo /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/types.c
libtool: compile:  clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/types.c  -fno-common -DPIC -o src/.libs/types.o
/bin/sh ./libtool  --tag=CC   --mode=compile clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi  -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src   -Wall -fexceptions -c -o src/raw_api.lo /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/raw_api.c
libtool: compile:  clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/raw_api.c  -fno-common -DPIC -o src/.libs/raw_api.o
/bin/sh ./libtool  --tag=CC   --mode=compile clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi  -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src   -Wall -fexceptions -c -o src/java_raw_api.lo /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/java_raw_api.c
libtool: compile:  clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/java_raw_api.c  -fno-common -DPIC -o src/.libs/java_raw_api.o
/bin/sh ./libtool  --tag=CC   --mode=compile clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi  -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src   -Wall -fexceptions -c -o src/closures.lo /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/closures.c
libtool: compile:  clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/closures.c  -fno-common -DPIC -o src/.libs/closures.o
/bin/sh ./libtool  --tag=CC   --mode=compile clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi  -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src   -Wall -fexceptions -c -o src/x86/ffi64.lo /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/x86/ffi64.c
libtool: compile:  clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/x86/ffi64.c  -fno-common -DPIC -o src/x86/.libs/ffi64.o
/bin/sh ./libtool    --mode=compile clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi  -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src  -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src  -c -o src/x86/unix64.lo /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/x86/unix64.S
libtool: compile:  clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src -c /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/x86/unix64.S  -fno-common -DPIC -o src/x86/.libs/unix64.o
/bin/sh ./libtool  --tag=CC   --mode=compile clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi  -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src   -Wall -fexceptions -c -o src/x86/ffiw64.lo /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/x86/ffiw64.c
libtool: compile:  clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src -Wall -fexceptions -c /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/x86/ffiw64.c  -fno-common -DPIC -o src/x86/.libs/ffiw64.o
/bin/sh ./libtool    --mode=compile clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi  -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src  -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src  -c -o src/x86/win64.lo /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/x86/win64.S
libtool: compile:  clang -DHAVE_CONFIG_H -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src -I. -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/include -Iinclude -I/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src -c /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/src/x86/win64.S  -fno-common -DPIC -o src/x86/.libs/win64.o
/bin/sh ./libtool  --tag=CC   --mode=link clang  -Wall -fexceptions   -o libffi_convenience.la  src/prep_cif.lo src/types.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo   src/x86/ffi64.lo src/x86/unix64.lo src/x86/ffiw64.lo src/x86/win64.lo
libtool: link: ar cru .libs/libffi_convenience.a src/.libs/prep_cif.o src/.libs/types.o src/.libs/raw_api.o src/.libs/java_raw_api.o src/.libs/closures.o src/x86/.libs/ffi64.o src/x86/.libs/unix64.o src/x86/.libs/ffiw64.o src/x86/.libs/win64.o
libtool: link: ranlib .libs/libffi_convenience.a
libtool: link: ( cd ".libs" && rm -f "libffi_convenience.la" && ln -s "../libffi_convenience.la" "libffi_convenience.la" )
/bin/sh ./libtool  --tag=CC   --mode=link clang  -Wall -fexceptions -no-undefined -version-info `grep -v '^#' /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi/libtool-version`     -o libffi.la -rpath /usr/local/lib src/prep_cif.lo src/types.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo  src/x86/ffi64.lo src/x86/unix64.lo src/x86/ffiw64.lo src/x86/win64.lo
Usage: /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi-x86_64-darwin17/libtool [OPTION]... [MODE-ARG]...
Try 'libtool --help' for more information.
libtool:   error: too many parameters to '-version-info'
make[3]: *** [libffi.la] Error 1
make[2]: *** [all-recursive] Error 1
make[1]: *** [all] Error 2
make: *** ["/Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25/ext/ffi_c/libffi-x86_64-darwin17"/.libs/libffi_convenience.a] Error 2

make failed, exit code 2

Gem files will remain installed in /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/ffi-1.9.25 for inspection.
Results logged to /Users/xxx/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/extensions/x86_64-darwin-17/2.5.0-static/ffi-1.9.25/gem_make.out
```