UbuntuにKotlin/Nativeコンパイラをインストール

目次

KotlinはAndroidアプリだけでなくサーバーサイドでも使えるというのでUbuntuで使ってみました。

OSは"Ubuntu 20.04.2"です。 Kotlinは2021年5月21日現在、Kotlin 1.5.0を使用します。

途中トラブルもあったのですが、後で確認するためそのまま載せています。

Kotlinをインストールする

よくわからないので公式ページをさまよっていたらKotlinコマンドラインコンパイラーというページにたどり着きました。

Kotlinコンパイラには2種類あります。 実行ファイルをJava仮想マシンで動かすバージョンと、直接実行できるNativeバージョンです。 ただし、コマンドラインコンパイラでKotlin/Nativeを始めるのページにあるようにNativeコンパイラの出力結果は仮想マシンを必要としませんが、コンパイラの動作にはJava 1.8以上が必要となります。

先にJavaをインストールします。 UbuntuにJavaをインストール

SDKMAN!というツールを使用すると、簡単に開発環境をインストールしたり言語のバージョンを切り替えたりできるそうです。 後で試すことにしてまずは手動でインストールしてみます。

1.Kotlinコンパイラをダウンロードする

GitHubのページにコンパイラのバイナリがありました。 https://github.com/JetBrains/kotlin/releases/tag/v1.5.0

“kotlin-compiler-1.5.0.zip"と"kotlin-native-linux-1.5.0.tar.gz"の2つあります。 nativeはKotlinソースコードをネイティブバイナリにコンパイルすることで、仮想マシンなしに実行できるそうです。 ということで、nativeをダウンロードします。

curlコマンドを使用する場合、リダイレクトされるので-Lオプションが必要です。

$ curl https://github.com/JetBrains/kotlin/releases/download/v1.5.0/kotlin-native-linux-1.5.0.tar.gz -O -L
Kotlin/Nativeコンパイラのリンク

Kotlin/Nativeコンパイラのリンク

2.ダウンロードファイルを検証する

ページにあったチェックサム(Checksum)でダウンロードしたファイルが壊れていないか確認します。

$ echo "33241c460fab8c496a6b01ca08670ae7f667df23acc56081f8b37c50b021b50f kotlin-native-linux-1.5.0.tar.gz" > sha256.txt
$ sha256sum -c sha256.txt
kotlin-native-linux-1.5.0.tar.gz: OK

“OK"と表示されたので次の手順へ進みます。

3.ファイルを展開する

ダウンロードした圧縮ファイルを展開します。

$ tar xzf kotlin-native-linux-1.5.0.tar.gz

今回はインストール先を/usr/localディレトリにします。 またシンボリックリンクを作成することで使用するバージョンの切り替えができるようにします。 別バージョンを使うときにはシンボリックリンクを変更します。

$ sudo mv kotlin-native-linux-1.5.0 /usr/local
$ sudo rm /usr/local/kotlin
$ sudo ln -s /usr/local/kotlin-native-linux-1.5.0 /usr/local/kotlin

Kotlinコンパイラのパスをbashの初期化ファイル(~/.bashrc)でPATH環境変数に追加します。 その後、sourceコマンドで実行することで現在実行中の端末に反映させます。

$ echo "PATH=/usr/local/kotlin/bin:$PATH" >> ~/.bashrc
$ source ~/.bashrc

4.インストールされたバージョンを確認する

Kotlin/Nativeコンパイラはkotlinc-nativeです。

$ kotlinc-native -version
info: kotlinc-native 1.5.0-743 (JRE 16.0.1+9-Ubuntu-120.04)
Kotlin/Native: 1.5

これでインストールできました。

Kotlinファイルをコンパイルする

hello.ktというKotlinのソースファイルを作成します。

fun main() {
    val data = arrayOf(
        intArrayOf(1,2,1,1,4,1,1,4,1,5,2,2,1),
        intArrayOf(1,2,1,1,1,4,1,4,1,4,1,2,1,1,1),
        intArrayOf(4,1,3,2,1,4,1,4,1,2,1,1,1,1),
        intArrayOf(1,2,1,1,1,4,1,4,1,4,1,2,1,2),
        intArrayOf(1,2,1,1,4,1,4,1,4,2,2,2,1)
    )

    var counter : Int
    var type : Char
    var buffer : StringBuilder = StringBuilder()
    for (h in data) {
        counter = 0
        buffer.clear()
        for (w in h) {
            type = if (counter % 2 == 0) '*' else ' '
            for (i in 1..w) {
                buffer.append(type)
            }
            counter++
        }
        println(buffer)
    }

    println("\n終わりだよ〜(o・∇・o)")
}

kotlinc-nativeコマンドでコンパイルします。 初回コンパイルではコンパイルに不足しているものがダウンロードされるので時間がかかります。 しかし、まだ不足しているものがあるようでエラーになってしまいました。

$ kotlinc-native hello.kt -o hello
error: compilation failed: The /home/izumi/.konan/dependencies/clang-llvm-8.0.0-linux-x86-64/bin/clang++ command returned non-zero exit code: 127.
output:
/home/izumi/.konan/dependencies/clang-llvm-8.0.0-linux-x86-64/bin/clang++: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory

 * Source files: hello.kt
 * Compiler version info: Konan: 1.5 / Kotlin: 1.5.0
 * Output kind: PROGRAM

exception: org.jetbrains.kotlin.konan.KonanExternalToolFailure: The /home/izumi/.konan/dependencies/clang-llvm-8.0.0-linux-x86-64/bin/clang++ command returned non-zero exit code: 127.
output:
/home/izumi/.konan/dependencies/clang-llvm-8.0.0-linux-x86-64/bin/clang++: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory
	at org.jetbrains.kotlin.konan.exec.Command.handleExitCode(ExecuteCommand.kt:114)
	at org.jetbrains.kotlin.konan.exec.Command.execute(ExecuteCommand.kt:75)
	at org.jetbrains.kotlin.backend.konan.BitcodeCompiler.runTool(BitcodeCompiler.kt:31)
	at org.jetbrains.kotlin.backend.konan.BitcodeCompiler.hostLlvmTool(BitcodeCompiler.kt:47)
	at org.jetbrains.kotlin.backend.konan.BitcodeCompiler.clang(BitcodeCompiler.kt:89)
	at org.jetbrains.kotlin.backend.konan.BitcodeCompiler.makeObjectFiles(BitcodeCompiler.kt:113)
	at org.jetbrains.kotlin.backend.konan.ToplevelPhasesKt$objectFilesPhase$1.invoke(ToplevelPhases.kt:191)
	at org.jetbrains.kotlin.backend.konan.ToplevelPhasesKt$objectFilesPhase$1.invoke(ToplevelPhases.kt:191)
	at org.jetbrains.kotlin.backend.common.phaser.PhaseBuildersKt$namedOpUnitPhase$1.invoke(PhaseBuilders.kt:97)
	at org.jetbrains.kotlin.backend.common.phaser.PhaseBuildersKt$namedOpUnitPhase$1.invoke(PhaseBuilders.kt:95)
	at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:94)
	at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:30)
	at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:94)
	at org.jetbrains.kotlin.backend.common.phaser.CompilerPhaseKt.invokeToplevel(CompilerPhase.kt:41)
	at org.jetbrains.kotlin.backend.konan.KonanDriverKt.runTopLevelPhases(KonanDriver.kt:29)
	at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:78)
	at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:35)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:88)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:44)
	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:98)
	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:76)
	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:45)
	at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit(CLITool.kt:227)
	at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit$default(CLITool.kt:222)
	at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMain(CLITool.kt:214)
	at org.jetbrains.kotlin.cli.bc.K2Native$Companion$main$1.invoke(K2Native.kt:273)
	at org.jetbrains.kotlin.cli.bc.K2Native$Companion$main$1.invoke(K2Native.kt:272)
	at org.jetbrains.kotlin.util.UtilKt.profileIf(Util.kt:27)
	at org.jetbrains.kotlin.util.UtilKt.profile(Util.kt:21)
	at org.jetbrains.kotlin.cli.bc.K2Native$Companion.main(K2Native.kt:272)
	at org.jetbrains.kotlin.cli.bc.K2NativeKt.main(K2Native.kt:484)
	at org.jetbrains.kotlin.cli.utilities.MainKt$main$1.invoke(main.kt:60)
	at org.jetbrains.kotlin.cli.utilities.MainKt$main$1.invoke(main.kt:60)
	at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:17)
	at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:60)

“libtinfo.so.5"と言うファイルが見つからないようです。 apt-fileコマンドで検索してみました。

$ sudo apt-file update
$ apt-file search libtinfo.so.5
libtinfo5: /lib/x86_64-linux-gnu/libtinfo.so.5
libtinfo5: /lib/x86_64-linux-gnu/libtinfo.so.5.9

libtinfo5というパッケージにファイルが見つかりました。 apt showコマンドで情報を見てみました。

$ apt show libtinfo5
Package: libtinfo5
Version: 6.2-0ubuntu2
Priority: optional
Section: universe/libs
Source: ncurses
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Craig Small <csmall@debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 535 kB
Depends: libc6 (>= 2.16)
Breaks: dialog (<< 1.2-20130523)
Homepage: https://invisible-island.net/ncurses/
Download-Size: 83.0 kB
APT-Sources: http://jp.archive.ubuntu.com/ubuntu focal/universe amd64 Packages
Description: shared low-level terminfo library (legacy version)
 ncurses ライブラリルーチンは、文字画面を適切な最適化付きで端末に依存せずに 更新できる手段です。
 .
 This package contains the legacy version of the shared low-level terminfo
 library.

レガーシーバージョンとありますが、無いと先へ進まなそうなのでインストールします。

$ sudo apt install libtinfo5

再び、コンパイルしてみます。

$ kotlinc-native hello.kt -o hello

何も表示されなかったのでディレクトリ内容を確認します。

$ ls -l
合計 692
-rwxrwxr-x 1 izumi izumi 703672  5月 23 22:11 hello.kexe
-rw-rw-r-- 1 izumi izumi    713  5月 23 22:05 hello.kt

“hello.kexe"実行ファイルが作成されていましたので、実行します。

$ ./hello.kexe
*  * **** *    *     **  *
*  * *    *    *    *  * *
**** ***  *    *    *  * * 
*  * *    *    *    *  *  
*  * **** **** ****  **  *

終わりだよ〜(o・∇・o)
Kotlin/Nativeコンパイルから実行まで

Kotlin/Nativeコンパイルから実行まで