swiftenv で現在進行中の Swift 3.0-dev を扱う。
Swift プログラミング
swiftenv を使うと簡単に Swift ツールチェインを切り替えられるようになります。
それを使って Swift 3.0 候補の最新ビルドも切り替えられるようにしてみました。
ちょっと無理やり感はありますけれど。
先日に kylef/swiftenv を使って、Swift ツールチェインのバージョンを簡単に切り替えられるようにしてみました。それについては こちら で紹介しましたけれど、それを使って Swift 3.0 Developer Preview 1 も切り替えられるようにしたくなりました。
3.0-dev はビルドエラーに
そこで、結果的に失敗したので確かなことはわからないのですけど、次のようにすることで apple/swift
の master
ブランチを使ってツールチェインを作れるかもしれないことがわかりました。
swiftenv install 3.0-dev
ただ、実際にこれを実行すると の時点では、次のように Swift のビルドに失敗したことを知らせるメッセージが表示され、続行することができませんでした。
$ swiftenv install 3.0-dev
Found swift, skipping download
Found llvm, skipping download
Found clang, skipping download
Found lldb, skipping download
Found cmark, skipping download
Building Swift
This may take a very long time...
Building Swift failed
Check out the logfile for more information: /Users/tomohiro/.swiftenv/tmp/swiftenv-build-3.0-dev/swiftenv-build.20160519181517.16460.log
You can inspect or delete the working tree at: /Users/tomohiro/.swiftenv/tmp/swiftenv-build-3.0-dev
失敗の様子
エラーメッセージに記載されていたログファイルを見ると、どうやらそもそも メソッドが存在しない みたいな根本的なエラーであることが窺えます。
/Users/tomohiro/.swiftenv/tmp/swiftenv-build-3.0-dev/swift/lib/IRGen/GenClangDecl.cpp:81:24: error: no member named 'GetAddrOfGlobal' in 'clang::CodeGenerator'
return ClangCodeGen->GetAddrOfGlobal(global, (bool) forDefinition);
~~~~~~~~~~~~ ^
1 error generated.
ninja: build stopped: subcommand failed.
./utils/build-script: command terminated with a non-zero exit status 1, aborting
現時点でも、自分で直接 Swift ソースコードをダウンロードしてビルドする限りは正常にビルドできるようで不思議だったのですけど、目的のリポジトリがクローンされた作業ディレクトリを眺めてみると、どうやら clang
と llvm
のブランチが、手動でビルドするときは stable
なのが、swiftenv を使ってビルドした時には swift-3.0-branch
なっていて、それが原因の様子でした。
この clang
と llvm
は、Swift 3.0 のリリースプロセスの中で、ちょうどそれら以外のリポジトリとはブランチの切り方が違い、現時点ではそれ以外のリポジトリでは swift-3.0-branch
が切られていないはずなので、その辺りの足並みの差が影響しているのかもしれません。
正常化の試みは失敗
とりあえずその作業ディレクトリ内にある clang
と llvm
のブランチが stable
になるように調整してみましたけれど、再び swiftenv install 3.0-dev
を実行すると、ブランチが強制的に swift-3.0-branch
になってしまうため、この方法ではうまく行きませんでした。
手作業でツールチェインを追加することに
せっかくブランチさえ stable
にできればビルドは成功してくれるので、それなら swiftenv
に手作業で Swift ツールチェインを追加してみたらどうかと思ってやってみたら、とりあえず、切り替えできるようになりました。
試行錯誤でやってみたので、正しく登録できているかは少し自信がないですけれど、とりあえずどんなことをやってみたのか、備忘録も兼ねて記しておくことにします。
Swift をビルドする
まずは swiftenv
で使うための Swift を手作業でビルドします。今回は Swift のビルド環境が既に準備されているものとして、次のようにして最新ソースを取得してビルドします。
cd swift/
./utils/update-checkout --clone
./utils/build-script -R -c
そうすると ../build/Xcode-ReleaseAssert
に Swift のビルドが出来上がります。
ちなみに上で指定した -R
は デバッグ情報を伴わないリリースビルド
を、-c
は クリーンにした上でビルドする
という意味になるようです。今回みたいにソースコードを更新した場合、クリーンビルドをしないと思いがけないところでビルドエラーになったりするので注意です。
ビルドをツールチェインとしてまとめる
Swift をビルドできたら、それをツールチェインとして登録します。
見た感じ、ツールチェインは /Library/Developer/Toolchains
ディレクトリーに *.xctoolchain
というフォルダーでまとめられる様子です。中身を見ると Info.plist
とかいろいろあるみたいですけど、とりあえず swiftenv/swiftenv-build
あたりを眺める限りでは、フォルダーを作ってバイナリをコピーすれば良さそうな様子もうかがえて、このコードだけでは足りなそうな気はするものの、とりあえずそんな調子で実施してみることにしました。
sudo mkdir -p /Library/Developer/Toolchains/swift-master.xctoolchain/usr/bin
sudo cp -r "../build/Ninja-ReleaseAssert/"swift-*/bin "/Library/Developer/Toolchains/swift-master.xctoolchain/usr"
sudo cp -r "../build/Ninja-ReleaseAssert/"swift-*/lib "/Library/Developer/Toolchains/swift-master.xctoolchain/usr"
こんな風にすることで swift-master
という名前の Swift ツールチェインをシステムに組み込むことが(たぶん)できました。
swiftenv で切り替える
ここまでできると、swiftenv
で swift-master
というバージョンを選択できるようになるので、いつもと同じコマンドで切り替えてあげれば完成です。
swiftenv local swift-master
そうして試しに Swift のバージョンを確認してみると、今の時点で最新の Swift に切り替えられた様子です。
$ swift --version
Swift version 3.0-dev (LLVM a12db8b2fe, Clang 9df84c4959, Swift f045e5960d)
Target: x86_64-apple-macosx10.9
とりあえず、シンプルなコードを試す限りでは、コンパイラとしてちゃんと動いてくれる様子でした。
Swift 3.0 のリリースプロセスでは master ブランチで最新の Swift 3.0 コミットが入れられていくらしいので、もちろんコミットされるたびに、それを使って再ビルドの上、ツールチェインフォルダーにコピーする作業が必要になりますけれど、これで比較的気軽に最新の Swift 3.0 リリース候補を試していけるのではないかなって期待してます。