My External Storage

Dec 9, 2018 - 2 minute read - Comments - go

[Go] bluele/mecab-golangを含むコードをビルドすると Undefined symbols for architecture x86_64 と出て失敗する

他の方のリポジトリにビルドすると表題のエラーが出てしまった。 bluele/mecab-golangをimportしている(CGOの設定が必要だった)のが原因だったのでメモしておく。

TL;DR

  • bluele/mecab-golangimportするリポジトリの場合はgo getdepなどのimport解決だけでは不十分
  • Macの場合はbrew install mecabmecabをインストールする
  • 環境変数を設定しておく必要がある。CGO_LDFLAGSを設定してビルドをすれば問題ない

Undefined symbols for architecture x86_64

git clonego get ./...後のあるリポジトリのtestを実行しようとしたところ、以下のエラーが出てしまった。

$ go test
# github.com/bluele/mecab-golang
Undefined symbols for architecture x86_64:
  "_mecab_destroy", referenced from:
      __cgo_41e1bb9c719c_Cfunc_mecab_destroy in _x005.o
     (maybe you meant: __cgo_41e1bb9c719c_Cfunc_mecab_destroy)

....

ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
FAIL	github.com/budougumi0617/mecab-project [build failed]

どうやらimportしているbluele/mecab-golangmecab関係のCGO関数をきちんと呼べていないのが原因のようだった。

環境変数を設定してgo getをやり直す

解決方法はbluele/mecab-golangのREADMEを見ればすぐにわかった。

MacOSの場合はbrew経由でmecabmecab-configをインストールできる。

$ brew install mecab
$ which mecab
/usr/local/bin/mecab
$ which mecab-config
/usr/local/bin/mecab-config

インストール後はbluele/mecab-golangのREADME通りに環境変数を設定すればよい。 不要かもしれないが、私はgo getもやり直しておいた。

$ export CGO_LDFLAGS="`mecab-config --libs`"
$ export CGO_CFLAGS="-I`mecab-config --inc-dir`"
$ go get -u github.com/bluele/mecab-golang

とはいえ、mecab以外のCGOの設定などもあってexportで設定はしたくないという人(自分)もいるだろう。 そのような人は以下のようにコマンド実行時にCGO_LDFLAGSを渡せばよい。

$ CGO_LDFLAGS="`mecab-config --libs`" go test
PASS
ok  	github.com/budougumi0617/mecab-project	0.018s

ちなみにmecab-config --libsが出力する結果は以下だった。

$ mecab-config --libs
-L/usr/local/Cellar/mecab/0.996/lib -lmecab -lstdc++

関連記事