Kotlin/Native開発環境構築＆インストール手順＆チュートリアル

# はじめに

[Kotlin/Native](https://kotlinlang.org/docs/reference/native-overview.html)のmacOS/Linux向けビルド環境(※ビルドツールのGradleなし)のインストール手順をまとめています。ただし、2020/1月時点でKotlin/Native自体がまだベータ版という状況です。

## 前提

KotlinソースコードのコンパイルにJDK (Java環境) が必要なため、事前にインストールしておいてください。

## Kotlin/Nativeのインストール

https://github.com/JetBrains/kotlin/releases/latest
にある正式リリース最新版を利用します。

ここではダウンロードにwgetコマンドを利用するため、未インストールの方は必要に応じてインストールして下さい。

### 事前準備

#### macOS

```
$ brew install wget
```

#### Linux(Ubuntu)

```
$ sudo apt install wget
```

### コンパイラをダウンロード

#### macOS

```shell
$ wget https://github.com/JetBrains/kotlin/releases/download/v1.3.61/kotlin-native-macos-1.3.61.tar.gz
```

#### Linux(Ubuntu)

```shell
$ wget https://github.com/JetBrains/kotlin/releases/download/v1.3.61/kotlin-native-linux-1.3.61.tar.gz
```

### コンパイラのインストール

#### macOS/Linux共通

適切な場所に解凍し、環境変数のパスを通しておきます。ここでは/usr/local/kotlin-nativeに配置することにします。

```shell
$ tar xzvf kotlin-native-macos-1.3.61.tar.gz
$ sudo mkdir -p /usr/local/kotlin-native
$ sudo mv kotlin-native-macos-1.3.61/* /usr/local/kotlin-native
```

コンパイラバイナリへのパスを通すために~/.bash_profileにパスを追記します。

```~/.bash_profile
$ export PATH=$PATH:/usr/local/kotlin-native/bin/
```

## [オプション] IntelliJ IDEAインストール

Gradleを利用しない場合、追加で必要になるパッケージ(例えば、Coroutinesだとkotlinx:kotlinx-coroutines-core-nativeなど)を自分で探してきて、コマンドラインのオプションで指定する必要があります。この場合に問題なのは、どこからダウンロードしてきたらいいかが分からない点です。そのため、IntelliJ IDEAはインストールしておき、Gradle環境も使えるようにしておいた方が便利です…

[ここ](https://www.jetbrains.com/idea/download/)からダウンロードします。macOS環境の場合はdmgファイルのため、GUI操作でインストールします。一方でLinux環境の場合は、適当な場所に解凍してパスを通すだけで使えます。

<img width="666" alt="スクリーンショット 2020-01-23 20.32.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/ee88cd37-77e1-6ace-6207-db2b4f2c2f72.png">

なお、Kotlinプラグインは既にインストール済みの状態になっていると思いますので、このままプロジェクト新規作成で使えます。

## 動作確認用ソースコード

```hello.kt
fun main(args: Array<String>) {
    println("Hello, World!")
}
```

## コンパイル

初回実行時、LLVMなどの依存パッケージをダウンロード＆インストールするために時間がかかります。

```shell
$ kotlinc-native hello.kt -o hello
```

なお、-DオプションでJavaのオプションが渡せるため、ネットワーク環境でプロキシ設定が必要な方は以下のように実行してください。
情報参照元は[ここ](https://github.com/JetBrains/kotlin-native/blob/master/FAQ.md)です。

```shell
$ kotlinc-native hello.kt -o hello ¥
     -Dhttp.proxyHost=hoge.host.co.jp -Dhttp.proxyPort=12345 ¥
     -Dhttps.proxyHost=hoge.host.co.jp -Dhttps.proxyPort=12345
```

## 実行

```
$ ./hello.kexe
Hello, World!
```

macOS/Linuxのネイティブ環境でKotlinプログラムが実行できました！

## ライブラリ生成

-pオプションを利用することでいくつかの形式のライブラリ化が可能で、ヘッダファイルも自動生成してくれます。
iOS/macOSのframeworkにも対応していて結構よくできていますが、dynamic指定時のC/C++用のヘッダファイルは結構出来が悪い気がします…。もう少しまともなマクロにして欲しい…

```
$ kotlinc-native hello.kt -p dynamic
```
|オプション引数|内容|
|----|---|
|program|通常の実行バイナリ|
|static|.aファイル|
|dynamic|Linux環境であれば.so, macOSであれば.dylib|
|framework|iOS/macOS向けのframework形式|
|library|klib(Kotlinライブラリ形式)|
|bitcode|bcファイル (LLVMのBitcodebc)|

使い方が分からない場合は、-hオプションでヘルプメッセージが確認出来ます。

```
$ kotlinc-native -h
Usage: kotlinc-native <options> <source files>
where possible options include:
  -g                         Enable emitting debug information
  -enable-assertions (-ea)   Enable runtime assertions in generated code
  -friend-modules <path>     Paths to friend modules
  -generate-no-exit-test-runner (-trn)
                             Produce a runner for unit tests not forcing exit
  -generate-test-runner (-tr) Produce a runner for unit tests
  -generate-worker-test-runner (-trw)
                             Produce a worker runner for unit tests
  -include-binary (-ib) <path> Pack external binary within the klib
  -library (-l) <path>       Link with the library
  -library-version (-lv) <version>
                             Set library version
  -linker-options <arg>      Pass arguments to linker
  -list-targets              List available hardware targets
  -entry (-e) <name>         Qualified entry point name
  -manifest <path>           Provide a maniferst addend file
  -memory-model <model>      Memory model to use, 'strict' and 'relaxed' are currently supported
  -module-name <name>        Specify a name for the compilation module
  -native-library (-nl) <path> Include the native bitcode library
  -no-default-libs           Don't link the libraries from dist/klib automatically
  -no-endorsed-libs          Don't link the endorsed libraries from dist automatically
  -nomain                    Assume 'main' entry point to be provided by external libraries
  -nopack                    Don't pack the library into a klib file
  -nostdlib                  Don't link with stdlib
  -opt                       Enable optimizations during compilation
  -output (-o) <name>        Output name
  -produce (-p) {program|static|dynamic|framework|library|bitcode}
                             Specify output file kind
  -repo (-r) <path>          Library search path
  -linker-option <arg>       Pass argument to linker
  -target <target>           Set hardware target
  -Werror                    Report an error if there are any warnings
  -api-version <version>     Allow to use declarations only from the specified version of bundled libraries
  -X                         Print a synopsis of advanced options
  -help (-h)                 Print a synopsis of standard options
  -kotlin-home <path>        Path to Kotlin compiler home directory, used for runtime libraries discovery
  -language-version <version> Provide source compatibility with specified language version
  -P plugin:<pluginId>:<optionName>=<value>
                             Pass an option to a plugin
  -progressive               Enable progressive compiler mode.
                             In this mode, deprecations and bug fixes for unstable code take effect immediately,
                             instead of going through a graceful migration cycle.
                             Code written in the progressive mode is backward compatible; however, code written in
                             non-progressive mode may cause compilation errors in the progressive mode.
  -nowarn                    Generate no warnings
  -verbose                   Enable verbose logging output
  -version                   Display compiler version
  @<argfile>                 Read compiler arguments and file paths from the given file
```

## 使ってみた感想

使ってみた感想としては、普通に動くもののとにかくビルドが遅いですね…。[Kotlin 1.4でコンパイラが新しくなる](https://blog.jetbrains.com/jp/2020/01/16/2731)らしいので、それに期待です。