Mac OSX 10.9 MavericksにChef(knife-solo)をインストールするとエラー(解決)


Chefやろう!Chef覚えよう!と思って早速macにインストールするもエラーが発生したので、そのトラブルシューティング記録です。

(ちなみにChefはシェフと読むわけですが、今までずっとチーフ(Chief)だと思ってました・・・)

Chefインストール

公式に従って以下のコマンドを叩きます。

curl -L https://www.opscode.com/chef/install.sh | sudo bash

ここまではOKです。installer: The install was successful.が出て無事終了。

knife-soloインストールとエラー

次のコマンドを叩くと・・・

sudo gem install knife-solo

エラー

Fetching: mixlib-config-2.1.0.gem (100%)
Successfully installed mixlib-config-2.1.0
Fetching: mixlib-cli-1.4.0.gem (100%)
Successfully installed mixlib-cli-1.4.0
Fetching: mixlib-log-1.6.0.gem (100%)
Successfully installed mixlib-log-1.6.0
Fetching: mixlib-authentication-1.3.0.gem (100%)
Successfully installed mixlib-authentication-1.3.0
Fetching: mixlib-shellout-1.4.0.gem (100%)
Successfully installed mixlib-shellout-1.4.0
Fetching: systemu-2.5.2.gem (100%)
Successfully installed systemu-2.5.2
Fetching: yajl-ruby-1.2.0.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing knife-solo:
    ERROR: Failed to build gem native extension.

    /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby extconf.rb
creating Makefile

make "DESTDIR="
compiling yajl.c
compiling yajl_alloc.c
compiling yajl_buf.c
compiling yajl_encode.c
compiling yajl_ext.c
compiling yajl_gen.c
yajl_gen.c:295:5: warning: implicit conversion from enumeration type 'yajl_gen_state' to different enumeration type 'yajl_gen_status' [-Wenum-conversion]
    DECREMENT_DEPTH;
    ^~~~~~~~~~~~~~~
yajl_gen.c:181:48: note: expanded from macro 'DECREMENT_DEPTH'
    if (--(g->depth) >= YAJL_MAX_DEPTH) return yajl_gen_error;
                                        ~~~~~~ ^~~~~~~~~~~~~~
yajl_gen.c:321:5: warning: implicit conversion from enumeration type 'yajl_gen_state' to different enumeration type 'yajl_gen_status' [-Wenum-conversion]
    DECREMENT_DEPTH;
    ^~~~~~~~~~~~~~~
yajl_gen.c:181:48: note: expanded from macro 'DECREMENT_DEPTH'
    if (--(g->depth) >= YAJL_MAX_DEPTH) return yajl_gen_error;
                                        ~~~~~~ ^~~~~~~~~~~~~~
2 warnings generated.
compiling yajl_lex.c
compiling yajl_parser.c
compiling yajl_version.c
linking shared-object yajl/yajl.bundle
clang: error: unknown argument: '-multiply_definedsuppress' [-Wunused-command-line-argument-hard-error-in-future]
clang: note: this will be a hard error (cannot be downgraded to a warning) in the future
make: *** [yajl.bundle] Error 1

Gem files will remain installed in /Library/Ruby/Gems/2.0.0/gems/yajl-ruby-1.2.0 for inspection.
Results logged to /Library/Ruby/Gems/2.0.0/gems/yajl-ruby-1.2.0/ext/yajl/gem_make.out

意味が分かりませんでしたが、気になる点がいくつか。

gemなのに.cとか。あと、error吐いてるコマンドがclangとか。gccじゃないの?

トラブルシューティング

少し調べるとこんな投稿が見つかりました。

OSX Mavericks にしたら gdb と gcc が消えた時の対処法

Mavericksからはclangに変わったようです。だから普通は出ないはずのwarningが出たり、unknown argumentが出たりするのだと思います。

ここでclangではなくgccに差し替えれば上手く行くと思ったのですが、残念ながら失敗に終わりました。brewでgcc-4.9を入れて/usr/bin/gcc(実態はclang)をgcc-4.9に差し替えて上手く行くはずが、なぜかgem installで使われるgccは相変わらずclangでした。

もしかしてスクリプト内部でgccじゃなくてclang直接使ってるのかも知れません。それでエラー吐いてるとかいう状況だと悲しいですが・・・。今思えば/usr/bin/clangをgcc-4.9に差し替える方法もありだったのかな?と思います。

とにかくgccインストール作戦は上手く行かなかったので方針を変えました。curl経由じゃなくて、普通にgem installしようと。

# curl経由で入れたchefを一旦削除
sudo gem uninstall chef

# curlではなく普通に入れる
sudo gem install chef
sudo gem install knife-solo

これで正常に入りました。

curl版と比べるといくつかインストールされていないものがありますが、まあ大丈夫でしょう。適当にknife使ってVagrantに適当にアプリ入れたりサービス切ったりしましたが、普通に使えていました。

以上です。