LoginSignup
6
2

More than 5 years have passed since last update.

Kotlin/Native ProjectをBitriseのiOSプラットフォームでビルドする

Last updated at Posted at 2019-02-04

2019/2/19追記

こちらの記事により簡潔な方法を書きました!

この記事について

 この記事では、Kotlin/Nativeのチュートリアル等は解説しません。チュートリアルにおすすめの記事は

辺りがおすすめです
 この記事では、Kotlin/Native ProjectをBitriseのiOSプラットフォームでビルドする方法について述べます。正確にはgradle.frameworkを生成する方法を記述しようと思います。記事の内容は公式のtutorialに沿って記述します
 Kotlin/Nativeは非常に新しいプロジェクトで、日々変わりつつあります。盛り上げて行きましょう!

CIの全体的なステップの流れ

 細かい事は省いて大まかに組むと以下の様になります。この記事では2と3について書いていきます
1. Clone
2. ./gradlew packForXcodeを実行するのに必要な依存ツールのインストール
3. .framework生成(./gradlew packForXcode実行)
4. 証明書とか
5. アーカイブ、テスト等

 注意しなければならないのは、iOSをビルドする前に一度./gradlew packForXcodeを実行する必要があるということです。これは、SharedCode/build.gradlepackForXCodeタスクと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

packForXCodefinal 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 SelectorAndroidにしないと使えないそうです。参考
 つまり、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.propertiessdk.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 packForXcodesuccessし、無事ビルドできると思います :tada:

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勉強して探ってみたいと思います
道のりは長かった…

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2