Goがmacで動かなくて四苦八苦した話(#runtime/cgoとかCommand Line Toolsとかclangとか)

#動かんGo!!!!!!!!!!!!!!!!!!!!!!!!!!!!

因果が巡り巡ってGoを触ることになったので, Goをinstallして
サンプルコードを動かそうとしてみたんですが以下のようなエラーが出て動きませんでした.

```terminal.

go run main.go
# runtime/cgo
ld: warning: ld: warning: ignoring file /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libSystem.tbd, file was built for unsupported file format ( 0x2D 0x2D 0x2D 0x20 0x21 0x74 0x61 0x70 0x69 0x2D 0x74 0x62 0x64 0x2D 0x76 0x33 ) which is not the architecture being linked (x86_64): /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libSystem.tbd
ignoring file /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libpthread.tbd, file was built for unsupported file format ( 0x2D 0x2D 0x2D 0x20 0x21 0x74 0x61 0x70 0x69 0x2D 0x74 0x62 0x64 0x2D 0x76 0x33 ) which is not the architecture being linked (x86_64): /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libpthread.tbd
Undefined symbols for architecture x86_64:
  "___stack_chk_fail", referenced from:
      _x_cgo_init in _x004.o
      __cgo_sys_thread_start in _x004.o
  "___stack_chk_guard", referenced from:
      _x_cgo_init in _x004.o
      __cgo_sys_thread_start in _x004.o
  "___stderrp", referenced from:
      __cgo_sys_thread_start in _x004.o
      _x_cgo_sys_thread_create in _x005.o
      _x_cgo_thread_start in _x008.o
  "_abort", referenced from:
      __cgo_sys_thread_start in _x004.o
      _x_cgo_sys_thread_create in _x005.o
      _x_cgo_thread_start in _x008.o
  "_fprintf", referenced from:
      __cgo_sys_thread_start in _x004.o
      _x_cgo_sys_thread_create in _x005.o
  "_free", referenced from:
      _threadentry in _x004.o
  "_fwrite", referenced from:
      _x_cgo_thread_start in _x008.o
  "_malloc", referenced from:
      _x_cgo_thread_start in _x008.o
  "_nanosleep", referenced from:
      _x_cgo_sys_thread_create in _x005.o
      __cgo_try_pthread_create in _x005.o
  "_pthread_attr_destroy", referenced from:
      _x_cgo_init in _x004.o
  "_pthread_attr_getstacksize", referenced from:
      _x_cgo_init in _x004.o
      __cgo_sys_thread_start in _x004.o
  "_pthread_attr_init", referenced from:
      _x_cgo_init in _x004.o
      __cgo_sys_thread_start in _x004.o
  "_pthread_cond_broadcast", referenced from:
      _x_cgo_notify_runtime_init_done in _x005.o
  "_pthread_cond_wait", referenced from:
      __cgo_wait_runtime_init_done in _x005.o
  "_pthread_create", referenced from:
      _x_cgo_sys_thread_create in _x005.o
      __cgo_try_pthread_create in _x005.o
     (maybe you meant: __cgo_try_pthread_create)
  "_pthread_detach", referenced from:
      _x_cgo_sys_thread_create in _x005.o
      __cgo_try_pthread_create in _x005.o
  "_pthread_mutex_lock", referenced from:
      __cgo_wait_runtime_init_done in _x005.o
      _x_cgo_notify_runtime_init_done in _x005.o
      _x_cgo_set_context_function in _x005.o
      __cgo_get_context_function in _x005.o
  "_pthread_mutex_unlock", referenced from:
      __cgo_wait_runtime_init_done in _x005.o
      _x_cgo_notify_runtime_init_done in _x005.o
      _x_cgo_set_context_function in _x005.o
      __cgo_get_context_function in _x005.o
  "_pthread_sigmask", referenced from:
      __cgo_sys_thread_start in _x004.o
  "_setenv", referenced from:
      _x_cgo_setenv in _x006.o
     (maybe you meant: _x_cgo_setenv)
  "_strerror", referenced from:
      __cgo_sys_thread_start in _x004.o
      _x_cgo_sys_thread_create in _x005.o
  "_unsetenv", referenced from:
      _x_cgo_unsetenv in _x006.o
     (maybe you meant: _x_cgo_unsetenv)
ld: symbol(s) not found for architecture x86_64
clang-4.0: error: linker command failed with exit code 1 (use -v to see invocation)
```

clangのリンカが死んでいる...?????????
無限にわかりませんがとりあえず調べます.

### 9/6追記
本記事最後の解決法で正常に動作することを確認しました.
最後まで読むのがめんどくさい方は以下のコマンドを実行してターミナルをリロードしてみてください.

```
echo "export CC=clang" >> ~/.bash_profile
echo "export CXX=clang++" >> ~/.bash_profile
source /.bash_profile
```



# 解決法

たまたまGoが動く別のmac bookが手元にあったので,比較しながらエラーメッセージの一番上に乗っていた`/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libpthread.tbd`について色々調べているとこんな記事を発見しました.

[Xcode10 の /usr/include インストール方法](https://qiita.com/yoya/items/630c991a98e4554e6e87)

記事中に記載の通り, macOS mojaveだとたまに`/usr/include`が消えてしまうようで、どうもそれが問題っぽいです.

実際,問題のmacでは/usr/includeが消えていました(というか元から存在していたのかも知らない)

というわけで記事に従って以下を実行します.

```terminal.
/Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
```
するとエラーが出ました.
そんなファイルは存在しないそうです.

というのも, `/Library/Developer/CommandLineTools`ディレクトリ配下に`Packages`ディレクトリ自体が存在していませんでした.

(以下のコードで確認できます)

```terminal.
ls /Library/Developer/CommandLineTools
```

なので仕方なく[More Downloads for Apple Developers](https://developer.apple.com/download/more/)から直接落としてきます.

ここらへんは元記事様の通りですね.

Apple IDでのログインが必要なので注意してください.

そして以下の画像の通りダウンロードします.

<img width="1280" alt="スクリーンショット 2019-09-04 0.28.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386550/ba4dc1d2-72d7-5cae-2705-b03cae55137f.png">

ダウンロードするのは
**Command Line Tools (macOS 10.14) for Xcode 10.3**
です.

ダウンロードしてインストーラの指示に従ってインストールを進めると、先ほどの`/Library/Developer/CommandLineTools/`ディレクトリ配下に`Packages`ディレクトリが作成されています.

それでは実行してみましょう.pkgファイルのインストールなのでinstallerコマンドを使います.
sudoをお忘れなく.

```terminal.
open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
```

もにょもにょとinstallが終わったら確認してみましょう.

```terminal.
ls /usr
```

すると

```terminal.
bin  include  lib  libexec  local  sbin  share  standalone
```

しっかりincludeディレクトリが出来ていますね.
それではウインドウをリロードしてみましょう.

これでうまく動けば終了です,やったぜ！

#私は動きませんでした

上記変更を加えたのちにウキウキしながら`go run main.go`をしたところこのようなエラーが発生しました.

```terminal.
# runtime/cgo
ld: warning: ld: warning: ignoring file /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib/libpthread.tbd, file was built for unsupported file format ( 0x2D 0x2D 0x2D 0x20 0x21 0x74 0x61 0x70 0x69 0x2D 0x74 0x62 0x64 0x2D 0x76 0x33 ) which is not the architecture being linked (x86_64): /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib/libpthread.tbd
ignoring file /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib/libSystem.tbd, file was built for unsupported file format ( 0x2D 0x2D 0x2D 0x20 0x21 0x74 0x61 0x70 0x69 0x2D 0x74 0x62 0x64 0x2D 0x76 0x33 ) which is not the architecture being linked (x86_64): /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib/libSystem.tbd
Undefined symbols for architecture x86_64:
  "___stack_chk_fail", referenced from:
      _x_cgo_init in _x004.o
      __cgo_sys_thread_start in _x004.o
  "___stack_chk_guard", referenced from:
      _x_cgo_init in _x004.o
      __cgo_sys_thread_start in _x004.o
...
```

ちゃんとMacOSX10.14.sdkという文字が見えますね,キレそうです.
Command Line Toolsのインストールで解決している人も割といたっぽいので,自分のは原因がまた別に存在しているようでした...

ちょっと検索方針を変えて,頭に書いてある # runtime/cgoの方でエラーが起きていないかみてみることにしました.

すると以下に対策が記載されていました.

[runtime/cgo.a: unable to find it when cross compile ](https://github.com/golang/go/issues/16445)

上記記事を参考に以下のようにcgoをクロスコンパイル中は動作しないように設定.

```terminal.
CGO_ENABLED=0
```

すると動きました！！！！！！！！！
どうやらクロスコンパイル時にcgoが変な感じになっていた？のが原因？なのでしょうか？？？？
ふわっとした理解です.

#でもなんか嫌じゃない？

動くには動いたんですが,cgoを殺して得るバイナリは美味しいか？という気持ちがあります.
というわけで,例のごとく「動く方」のmacも使って比較検証です.

`go env`の出力を目grepしながら比べていると,「動く方」はCC="clang"が,「動かない方」はCC="x86_64-apple-darwin13.4.0-clang"が設定されていることがわかりました.
(CXXも"x86_64-apple-darwin13.4.0-clang++"だった)

`x86_64-apple-darwin13.4.0-clang`が何を指しているか不明ですが多分mac付属のclangという感じでしょうか.

おそらくこれが原因なので以下のコマンドを叩いて,使用するcross compilerを変更します.
(「動く方」のmacに合わせます)

```terminal.
export CC=clang
export CXX=clang++
```

また,毎回設定するのは嫌なので~/.bash_profileにも追記します.

```terminal.
echo "export CC=clang" >> ~/.bash_profile
echo "export CXX=clang++" >> ~/.bash_profile
```

適当にターミナルをリロードして`go run  main.go`をすると...

**動きました!!!!!!!!!!!!!!!**
**終了!!!!!!!!!!!!!!!!!!!!!**
(でもなんかVScodeのターミナルではwarning残ってる(は?))

# ~~Goなんもわからん~~
~~誰か助けてください.~~

#Go完全理解
### 9/6追記
**上記の方法で普通に動いてました！！！！！**
**優勝！！！！！！！！！！！！！！！！！！！！！！！！！！！１**