macOS CatalinaでErlang 22.2がビルドできない時の対処法

# TL;DR

- 2020年4月時点の最新のmacOS環境下ではErlang 22.2系がビルドできない
- Xcodeのバージョンを11.3に落とすか，kerlにpatchを手作業で追加するのでも良い
- それかよく分からなければおとなしく22.3以降をインストールする
- それか開発者に連絡して一緒に仲良く事態を解消しよう！

# きっかけ

<font color="red">[Nerves 1.6 released!](https://elixirforum.com/t/nerves-1-6-released/29982)</font> Elixir 1.10に対応したぜ！Erlang/OTPの推奨バージョンは22.2.8ね！
これに合わせて[Nerves開発環境の構築記事](https://qiita.com/takasehideki/items/88dda57758051d45fcf9)を更新するぜっ！！と思ったら，存外にめちゃハマったので共有します．
（今はNervesも22.3.2が推奨バージョンになったので，事態は解消されました^^


# 試した環境

* macOS Catalina 10.15.4
* Xcode Version 11.4.1 (11E503a)
    * `$ xcode-select --install`でCommand Line Toolsのみインストール
* asdf v0.7.1
* erlang 22.0.7, 22.2.8

Nervesでも推奨されている，asdfでのソースビルド／ツールバージョン管理を前提としています．

@torifukukaiou さんの素敵な記事も紹介します．本記事とは違う症状ですが，つまりはCatalinaだとまだ不安定なことがあるようです．

- [macOS Catalina(10.15.1)にasdfでElixirをインストールする](https://qiita.com/torifukukaiou/items/75fa25c55ce2f0b92496)


# 症状

```bash
$ asdf install erlang 22.2.8 
Extracting source code
mv: rename ./otp-OTP-22.2.8 to /Users/takase/.asdf/plugins/erlang/kerl-home/builds/asdf_22.2.8/otp_src_22.2.8/otp-OTP-22.2.8: Directory not empty
Building Erlang/OTP 22.2.8 (asdf_22.2.8), please wait...
Build failed.
 GEN    obj/x86_64-apple-darwin19.4.0/opt/MADE
 LD    /Users/takase/.asdf/plugins/erlang/kerl-home/builds/asdf_22.2.8/otp_src_22.2.8/bin/x86_64-apple-darwin19.4.0/erl_child_setup
ld: weak import of symbol '___darwin_check_fd_set_overflow' not supported because of option: -no_weak_imports for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[4]: *** [/Users/takase/.asdf/plugins/erlang/kerl-home/builds/asdf_22.2.8/otp_src_22.2.8/bin/x86_64-apple-darwin19.4.0/erl_child_setup] Error 1
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [opt] Error 2
make[2]: *** [opt] Error 2
make[1]: *** [smp] Error 2
make: *** [emulator] Error 2

Please see /Users/takase/.asdf/plugins/erlang/kerl-home/builds/asdf_22.2.8/otp_build_22.2.8.log for full details.

```

いろいろ調べてみると，[Erlang界隈では既知の問題であり，22.3.1でpatchが適用されていてすでに解決できている](https://bugs.erlang.org/browse/ERL-1205?focusedCommentId=17223&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-17223)ようです．


# 対処法

## 其の壱：Erlang 22.3.1以降にする

おとなしく先人たちの肩に乗りましょう．

```bash
$ asdf install erlang 22.3.1
Extracting source code
Building Erlang/OTP 22.3.1 (asdf_22.3.1), please wait...
Erlang/OTP 22.3.1 (asdf_22.3.1) has been successfully built
Installing Erlang/OTP 22.3.1 (asdf_22.3.1) in /Users/takase/.asdf/installs/erlang/22.3.1...
You can activate this installation running the following command:
. /Users/takase/.asdf/installs/erlang/22.3.1/activate
Later on, you can leave the installation typing:
kerl_deactivate
Cleaning up compilation products for 
Cleaned up compilation products for  under /Users/takase/.asdf/plugins/erlang/kerl-home/builds

Erlang 22.3.1 has been installed. Activate globally with:

    asdf global erlang 22.3.1

Activate locally in the current folder with:

    asdf local erlang 22.3.1

```


## 其の弐：Xcodeのバージョンを落とす

どうしても22.2系を使いたい場合があると思います．例えばNerves v1.6.1はリリース当初の推奨バージョンが22.2.8になっていました．今はもう22.3以降が使えるようになりましたが，Nerves使いとしては公式の情報に合わせたほうが安全なので，これに従っておきたいということもありました．

問題はXcode 11.4に依存するようなので，このバージョンを落とせば解決できます．
まずはXcodeを一旦アンインストールします．私はCommand Line Toolsのみ導入していたので`/Library/Developer/CommandLineTools`を削除するだけでした．
App Storeからインストールされている方は`/Applications/Xcode.app`も削除しましょう．（他にも環境を綺麗にしないといけないかもしれない）

旧バージョンは[Apple Developer Portal](https://developer.apple.com/download/more/?name=Xcode)から.dmgを入手してインストールできます．Apple IDでログインが必要です．
私は`Command Line Tools for Xcode 11.3.1`を使用しました．

ということで，Xcodeのバージョンを落とすことで，Catalinaでも無事にインストールできました！！

```bash
$ asdf install erlang 22.2.8 
Extracting source code
mv: rename ./otp-OTP-22.2.8 to /Users/takase/.asdf/plugins/erlang/kerl-home/builds/asdf_22.2.8/otp_src_22.2.8/otp-OTP-22.2.8: Directory not empty
Building Erlang/OTP 22.2.8 (asdf_22.2.8), please wait...
Erlang/OTP 22.2.8 (asdf_22.2.8) has been successfully built
Installing Erlang/OTP 22.2.8 (asdf_22.2.8) in /Users/takase/.asdf/installs/erlang/22.2.8...
You can activate this installation running the following command:
. /Users/takase/.asdf/installs/erlang/22.2.8/activate
Later on, you can leave the installation typing:
kerl_deactivate
Cleaning up compilation products for 
Cleaned up compilation products for  under /Users/takase/.asdf/plugins/erlang/kerl-home/builds

Erlang 22.2.8 has been installed. Activate globally with:

    asdf global erlang 22.2.8

Activate locally in the current folder with:

    asdf local erlang 22.2.8

```

## 其の参：kerlにパッチを当てる

其の弐の問題は，Xcodeをダウングレードするので「古くね？はよアップデートしよ！？？」と通知がうるさくなることです^^;
まぁいったんErlangをインストールできたらアップデートしても良いのですが，なにかまた問題が起きたときにいちいちアップダウンを繰り返すのは面倒です．Engineeringな道理としては，最新版の環境を採用しながらも問題をうまく解消したいところです．

そんなところ，[Real-Time Phoenix](https://pragprog.com/book/sbsockets/real-time-phoenix)の著者でもあるSteve Busseyが，Twitterにて本質的な解決策を教えてくれました！

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">You can also manually build with the master branch of kerl. It has patches in place to fix the Erlang build problem on latest macOS / XCode versions. I use asdf-erlang, so I have to manually replace the kerl binary in ~/.asdf/plugins/erlang and comment out ensure in utils script.</p>&mdash; Steve Bussey (@YOOOODAAAA) <a href="https://twitter.com/YOOOODAAAA/status/1252069014114795521?ref_src=twsrc%5Etfw">April 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="en" dir="ltr"><a href="https://t.co/WUDiF0US5e">https://t.co/WUDiF0US5e</a> is the PR that fixes this. I think it&#39;s the same problem you&#39;re having.<br><br>Today, I installed OTP 22 on my Catalina Macbook running latest XCode.</p>&mdash; Steve Bussey (@YOOOODAAAA) <a href="https://twitter.com/YOOOODAAAA/status/1252069213424029696?ref_src=twsrc%5Etfw">April 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

つまり `-no_weak_imports` というリンクオプション（LDFLAGS）が問題なので，これを修正するパッチを手作業で追加してあげればよいと言うものです．
`~/.asdf/plugins/erlang/kerl`を，下記のPRのFile changedを参考にして書き換えてみてください．
https://github.com/kerl/kerl/pull/337/files

これで私の環境でもビルドが通りました！
パッチを手作業で追加するのはちょっと高度な気はしますが，最新版の環境を維持しつつ問題をうまく解決できて素晴らしいです！！


# まとめ

~~Erlang 22.3.1以降がNervesでも使えることになれば良さそうです．
とりあえず[Elixir-lang Slackの #Nerves でフィードバック](https://elixir-lang.slack.com/archives/C0AB4A879/p1587348205486200)してみました．~~
-> [22.3.2でおけ！](https://github.com/nerves-project/nerves/pull/517)になるように，対応してくれました！Thanks to Nerves Members!!!




# 参考にしたページ

偉大なる先人たちにまじリスペクトまじ感謝ですm(_ _)m

- [Medium @ vinicius_edipo: Erlang on macOS Catalina
](https://medium.com/@vinicius_edipo/erlang-on-macos-catalina-60d6819d1e4c)
- [Erlang/OTP / ERL-1205: Build errors on macOS 10.15.4](https://bugs.erlang.org/browse/ERL-1205?focusedCommentId=17223&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-17223)
- [GitHub erlang/otp Fix build of OTP with Xcode 11.4 #2577](https://github.com/erlang/otp/pull/2577)
- [StackExchange: How do I uninstall the command line tools for Xcode?](https://apple.stackexchange.com/questions/308943/how-do-i-uninstall-the-command-line-tools-for-xcode)