2019/2/19追記
こちらの記事により簡潔な方法を書きました!
この記事について
この記事では、Kotlin/Nativeのチュートリアル等は解説しません。チュートリアルにおすすめの記事は
辺りがおすすめです
この記事では、Kotlin/Native ProjectをBitriseのiOSプラットフォームでビルドする方法について述べます。正確にはgradleで.frameworkを生成する方法を記述しようと思います。記事の内容は公式のtutorialに沿って記述します
Kotlin/Nativeは非常に新しいプロジェクトで、日々変わりつつあります。盛り上げて行きましょう!
CIの全体的なステップの流れ
細かい事は省いて大まかに組むと以下の様になります。この記事では2と3について書いていきます
- Clone
-
./gradlew packForXcodeを実行するのに必要な依存ツールのインストール -
.framework生成(./gradlew packForXcode実行) - 証明書とか
- アーカイブ、テスト等
注意しなければならないのは、iOSをビルドする前に一度./gradlew packForXcodeを実行する必要があるということです。これは、SharedCode/build.gradleのpackForXCodeタスクとXcodeのBuild Phasesで追加したスクリプトを照らし合わせるとわかるのですが、
task packForXCode(type: Sync) {
final File frameworkDir = new File(buildDir, "xcode-frameworks")
final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
inputs.property "mode", mode
dependsOn kotlin.targets.iOS.compilations.main.linkTaskName("FRAMEWORK", mode)
from { kotlin.targets.iOS.compilations.main.getBinary("FRAMEWORK", mode).parentFile }
into frameworkDir
doLast {
new File(frameworkDir, 'gradlew').with {
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
setExecutable(true)
}
}
}
tasks.build.dependsOn packForXCode
packForXCodeのfinal File frameworkDir = new File(buildDir, "xcode-frameworks")で、SharedCode/build/code-frameworksを作成し、このフォルダに.frameworkが置かれますが、XcodeのBuild Phasesには
cd "$SRCROOT/../../SharedCode/build/xcode-frameworks"
./gradlew :SharedCode:packForXCode -PXCODE_CONFIGURATION=${CONFIGURATION}
と書く様になっています。build/はgitignore対象だと思いますので、clone段階ではbuild/xcode-frameworksディレクトリは生成されておらず、cdしようとしてもNo such a file or dictionaryと怒られてしまうのです。
さらに、build/xcode-frameworks以下にgradlewファイルも生成されていませんので、先に./gradlew packForXcodeを実行する必要があります。最初に実行すれば、キャッシュが効くのでBuild Phasesではタスクを実行するのに時間はかかりません。
.frameworkを生成するのに必要なもの
Android SDK
Androidをビルドするのに必要。ローカルではAndroid Studioをインストールする時に入ってきます。CI上ではSDKのみCLIでインストールします。Android SDKはSettingsにあるProject Type SelectorをAndroidにしないと使えないそうです。[参考]
(https://discuss.bitrise.io/t/install-missing-android-tools-failed/3630)
つまり、Project Type SelectorをAndroidにしたらiOSがビルドできなくなるので、自分でAndroid SDKを入れる必要があるということです
Java
Andorid SDKを使う時に必要になります。バージョンはプロジェクトの設定によります。自分のではJava8を使っているのでJava8をインストールします
Homebrew-caskを使ってインストール
幸いなことに、どちらもhomebrew-caskでインストールすることができます。brewはProject Type SelectorがiOSであれば使うことが出来ます
Script Stepを追加して、installします
brew cask install android-sdk java8
これだけでは、./gradlew packForXCode実行時に怒られてしまいます
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':app'.
> SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 0s
Command PhaseScriptExecution failed with a nonzero exit code
local.propertiesにsdk.dirを設定するか、ANDROID_HOMEを設定してくれと言われていますね。local.propertiesはgitignore推奨ですので、ANDROID_HOMEを設定します。
ローカルでは、ANDROID_HOMEを設定しなくても動いたと思うのですが、これはよしなにlocal.propertiesが生成されてsdk.dirを設定されているからです。ここをコメントアウト等すると上記のエラーが出ると思います。
ローカルではbash_profileにexportするなり、local.propertiesに記述するでもどちらでもいいと思います。しかし、local.propertiesを使わない場合は、Build Phasesで使うShellが環境変数ANDROID_HOMEを設定していないShellだとエラーが出てしまいます
ということで、CI上では環境変数ANDROID_HOMEを設定したいと思います。ただ、デフォルトのXcodeのBuild PhasesのスクリプトのShellは/bin/shで、Bitriseは/usr/bin/env bashになっており、ただexportするだけでは解決しません
そこで今回は、.bash_profileを生成してそこにANDROID_HOMEを設定して、Build Phasesでそれを読み込みたいと思います。先程のbrew caskの下に書きます。ついでに、JAVA_HOMEを設定してJava8を使うようにしておきましょう
touch ~/.bash_profile
echo 'export ANDROID_HOME=/usr/local/share/android-sdk' >> ~/.bash_profile
echo 'export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)' >> ~/.bash_profile
source ~/.bash_profile
Build Phasesのスクリプトにsource ~/.bash_profileを追加します
cd "$SRCROOT/../../SharedCode/build/xcode-frameworks"
source ~/.bash_profile # ここ追加
./gradlew :SharedCode:packForXCode -PXCODE_CONFIGURATION=${CONFIGURATION}
良さそうです。やっとだ〜と思い実行するとまたまたエラーが…
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':app'.
> Failed to install the following Android SDK packages as some licences have not been accepted.
platforms;android-28 Android SDK Platform 28
build-tools;27.0.3 Android SDK Build-Tools 27.0.3
To build this project, accept the SDK license agreements and install the missing components using the Android Studio SDK Manager.
Alternatively, to transfer the license agreements from one workstation to another, see http://d.android.com/r/studio-ui/export-licenses.html
Using Android SDK: /usr/local/share/android-sdk
ライセンスに同意していないよ。とのことなので同意します。
yes | sdkmanager --licenses
これは全ライセンスに同意していますが、sdkmanager "platforms;android-28"だけでも通るかもしれません
これで./gradlew packForXcodeがsuccessし、無事ビルドできると思います ![]()
Homebrew-cask以外の選択肢
brew cask以外にも、wget等で引っ張ってきて、解凍してシンボリックリンクを張る等などがあると思います
wget https://dl.google.com/android/repository/sdk-tools-darwin-4333796.zip
unzip ...
完成したスクリプト
# !/usr/bin/env bash
# fail if any commands fails
set -e
# debug log
set -x
brew cask install android-sdk java8
export JAVA_HOME=`/usr/libexec/java_home -v "1.8"`
export ANDROID_HOME=/usr/local/share/android-sdk
PATH=${JAVA_HOME}/bin:${PATH}
PATH=${ANDROID_HOME}/bin:${PATH}
yes | sdkmanager --licenses
cd $BITRISE_SOURCE_DIR
./gradlew packForXCode
最後に
本来ならば、gradleのiOSのビルドにAndroid sdkは要らない気がするのですが、ビルド時にAndroidのタスクも走ってるため何かしらが絡んでしまっているのだと思います。gradleの知識不足でわからず…
gradle勉強して探ってみたいと思います
道のりは長かった…