《Kotin 極簡教程》第16章 使用 Kotlin Native

第16章 使用 Kotlin Native


《Kotlin極簡教程》正式上架:

點擊這里 > 去京東商城購買閱讀

點擊這里 > 去天貓商城購買閱讀

非常感謝您親愛的讀者,大家請多支持!??!有任何問題,歡迎隨時與我交流~


不得不說 JetBrains 是一家務實的公司,各種IDE讓人贊不絕口,用起來也是相當溜。同樣的,誕生自 JetBrains 的 Kotlin 也是一門務實的編程語言,Kotlin以工程實用性為導向,充分借鑒了Java, Scala, Groovy, C#, Gosu, JavaScript, Swift等等語言的精華,讓我們寫起代碼來可謂是相當優雅卻又不失工程質量與效率。Kotlin Native能把 Kotlin代碼直接編譯成機器碼,也就是站在了跟 C/C++、Go和Rust的同一個層次,于是這個領域又添一位競爭對手。

在前面的所有章節中,我們使用的 Kotlin 都是基于 JVM 的運行環境。本章我們將從 JVM 的運行環境中離開,走向直接編譯生成原生機器碼的系統編程的生態系統:Kotlin Native 。

16.1 Kotlin Native 簡介

Kotlin Native利用LLVM來編譯到機器碼。Kotlin Native 主要是基于 LLVM后端編譯器(Backend Compiler)來生成本地機器碼。

Kotlin Native 的設計初衷是為了支持在非JVM虛擬機平臺環境的編程,如 ios、嵌入式平臺等。同時支持與 C 互操作。

16.1.1 LLVM

LLVM最初是Low Level Virtual Machine的縮寫,定位是一個虛擬機,但是是比較底層的虛擬機。LLVM是構架編譯器(compiler)的框架系統,以C++編寫而成,用于優化以任意程序語言編寫的程序的編譯時間(compile-time)、鏈接時間(link-time)、運行時間(run-time)以及空閑時間(idle-time),對開發者保持開放,并兼容已有腳本。

LLVM的出現正是為了解決編譯器代碼重用的問題,LLVM一上來就站在比較高的角度,制定了LLVM IR這一中間代碼表示語言。LLVM IR充分考慮了各種應用場景,例如在IDE中調用LLVM進行實時的代碼語法檢查,對靜態語言、動態語言的編譯、優化等。

16.1.2 支持平臺

Kotlin Native現在已支持以下平臺:

平臺名稱 target 配置
Linux linux
Mac OS macbook
Windows mingw
Android arm32 android_arm32
Android arm64 android_arm64
iOS iphone
Raspberry Pi raspberrypi

這意味著我們可以在這些平臺上愉快地開始體驗了!目前Kotlin Native 已經發布的最新預發布版本是 v0.3 。

16.1.3 解釋型語言與編譯型語言

編譯型語言,是在程序執行之前有一個單獨的編譯過程,將程序翻譯成機器語言,以后執行這個程序的時候,就不用再進行翻譯了。例如,C/C++ 等都是編譯型語言。

解釋型語言,是在運行的時候將程序翻譯成機器語言,所以運行速度相對于編譯型語言要慢。例如,Java,C#等都是解釋型語言。

雖然Java程序在運行之前也有一個編譯過程,但是并不是將程序編譯成機器語言,而是將它編譯成字節碼(可以理解為一個中間語言)。在運行的時候,由JVM將字節碼再翻譯成機器語言。

16.2 快速開始 Hello World

16.2.1 運行環境準備

我們直接去 Github上面去下載 kotlin-native 編譯器的軟件包。下載地址是 :https://github.com/JetBrains/kotlin-native/releases

螢幕快照 2017-07-29 13.23.30.png

下載解壓之后,我們可以看到 Kotlin Native 編譯器 konan 的目錄如下:

-rw-r--r--@  1 jack  staff   6828  6 20 22:47 GRADLE_PLUGIN.md
-rw-r--r--@  1 jack  staff  16286  6 20 22:47 INTEROP.md
-rw-r--r--@  1 jack  staff   1957  6 21 01:03 README.md
-rw-r--r--@  1 jack  staff   4606  6 20 22:47 RELEASE_NOTES.md
drwxr-xr-x@  8 jack  staff    272  6 20 23:04 bin
drwxr-xr-x   6 jack  staff    204  7 28 17:08 dependencies
drwxr-xr-x@  3 jack  staff    102  6 20 23:01 klib
drwxr-xr-x@  5 jack  staff    170  5 12 00:02 konan
drwxr-xr-x@  4 jack  staff    136  5 12 00:02 lib
drwxr-xr-x@ 22 jack  staff    748  6 22 19:04 samples

關于這個目錄里面的內容我們在后面小節中介紹。

另外,我們也可以自己下載源碼編譯,這里就不多說了。

16.2.2新建 Gradle 工程

在本小節中,我們先來使用IDEA 來創建一個普通的 Gradle 工程。

第1步,打開 File -> New -> Project ,如下圖所示

螢幕快照 2017-07-29 13.35.12.png

第2步,新建Gradle項目。我們直接在左側欄中選擇 Gradle,點擊 Next

螢幕快照 2017-07-29 13.36.01.png

第3步,設置項目的 GroupId、ArtifactId、Version 信息

螢幕快照 2017-07-29 13.36.47.png

第4步,配置 Gradle 項目的基本設置。我們直接選擇本地的 Gradle 環境目錄,省去下載的時間(有時候網絡不好,要下載半天),具體配置如下圖所示

螢幕快照 2017-07-29 13.37.11.png

第5步,配置項目名稱和項目存放目錄,點擊 Finish

螢幕快照 2017-07-29 13.37.23.png

第6步,等待 IDEA 創建完畢,我們將得到一個如下的Gradle 工程

螢幕快照 2017-07-29 13.38.50.png

現在這個工程里面什么都沒有。下面我們就來開始原始的手工新建文件編碼。

16.2.3 源代碼目錄

首先我們在工程根目錄下面新建 src 目錄,用來存放源代碼。在 src 下面新建 c 目錄存放 C 代碼,新建 kotlin 目錄存放 Kotlin 代碼。我們的源代碼組織結構設計如下

src
├── c
│   ├── cn_kotlinor.c
│   ├── cn_kotlinor.h
└── kotlin
    └── main.kt

16.2.4 C 代碼文件

cn_kotlinor.h

C頭文件中聲明如下

#ifndef CN_KOTLINOR_H
#define CN_KOTLINOR_H
void printHello();
int factorial(int n);
int fib(int n);
#endif

我們簡單聲明了3個函數。

cn_kotlinor.c

C 源代碼文件內容如下

#include "cn_kotlinor.h"
#include <stdio.h>

void printHello(){
    printf("[C]HelloWorld\n");
}

int factorial(int n){
    printf("[C]calc factorial: %d\n", n);
    if(n == 0) return 1;
    return n * factorial(n - 1);
}

int fib(int n){
    printf("[C]calc fibonacci: %d\n", n);
    if(n==1||n==2) return 1;
    return fib(n-1) + fib(n-2);
}

這就是我們熟悉的 C 語言代碼。

16.2.5 Kotlin 代碼文件

main.kt 文件內容如下

import ckotlinor.*

fun main(args: Array<String>) {
    printHello()
    (1..7).map(::factorial).forEach(::println)
    (1..7).map(::fib).forEach(::println)
}


其中,import kotlinor.* 是 C 語言代碼經過 clang 編譯之后的C 的接口包路徑,我們將在下面的 build.gradle 配置文件中的konanInterop中配置這個路徑。

16.2.6 konan插件配置

首先,我們在 build.gradle 里面添加構建腳本 buildscript 閉包

buildscript {
    repositories {
        mavenCentral()
        maven {
            url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies"
        }
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:0.3"
    }
}

這里我們添加了Gradle 構建 Kotlin Native 工程的 DSL 插件 kotlin-native-gradle-plugin:0.3 。這里的版本號,對應我們下載的 konan 編譯器的版本號,我們使用的是 v0.3,所以這里我們也使用0.3版本的插件。這個插件發布在https://dl.bintray.com/jetbrains/kotlin-native-dependencies倉庫里,所以我們在repositories里面添加了這個倉庫。

然后,我們應用插件 konan

apply plugin: 'konan' 

konan 就是用來編譯 Kotlin 為 native 代碼的插件。

16.2.7 konanInterop 互操作配置

konanInterop {
    ckotlinor {
        defFile 'kotlinor.def' // interop 的配置文件
        includeDirs "src/c" // C 頭文件目錄,可以傳入多個
    }
}

konanInterop 主要用來配置 Kotlin 調用 C 的接口。konanInterop 的配置是由konan 插件API中的 KonanInteropTask.kt來處理的(這個類的源碼在: https://github.com/JetBrains/kotlin-native/blob/master/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanInteropTask.kt)。

這里我們聲明的 ckotlinor 是插件中的KonanInteropConfig 對象。我們在下面的konanArtifacts里面會引用這個 ckotlinor 。

關于konanInterop的配置選項有

  konanInterop {
       pkgName {
           defFile <def-file>  
           pkg <package with stubs>
           target <target: linux/macbook/iphone/iphone_sim>
           compilerOpts <Options for native stubs compilation>
           linkerOpts <Options for native stubs >
           headers <headers to process> 
           includeDirs <directories where headers are located> 
           linkFiles <files which will be linked with native stubs>
           dumpParameters <Option to print parameters of task before execution>
       }
 
       // TODO: add configuration for konan compiler
 }

我們簡要說明如下表所示

配置項 功能說明
defFile 互操作映射關系配置文件
pkg C 頭文件編譯后映射為 Kotlin 的包名
target 編譯目標平臺:linux/macbook/iphone/iphone_sim等
compilerOpts 編譯選項
linkerOpts 鏈接選項
headers 要處理的頭文件
includeDirs 包括的頭文件目錄
linkFiles 與native stubs 鏈接的文件
dumpParameters 打印 Gradle 任務參數選項配置

其中,kotlinor.def 是Kotlin Native 與 C 語言互操作的配置文件,我們在kotlinor.def 里面配置 C 源碼到 kotlin 的映射關系。這個文件內容如下

kotlinor.def

headers=cn_kotlinor.h
compilerOpts=-Isrc/c

同樣的配置,如果我們寫在 build.gradle 文件中的konanInterop配置里如下

konanInterop {
    ckotlinor {
        // defFile 'kotlinor.def' // interop 的配置文件
        compilerOpts '-Isrc/c'
        headers 'src/c/cn_kotlinor.h' // interop 的配置文件
        includeDirs "src/c" // C 頭文件存放目錄,可以傳入多個
    }
}

關于這個配置文件的解析原理可以參考 KonanPlugin.kt 文件的源碼(https://github.com/JetBrains/kotlin-native/blob/master/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt)。

16.2.8 konanArtifacts 配置

在 konan 插件中,我們使用konanArtifacts來配置編譯任務執行。

konanArtifacts { 
    KotlinorApp { // (1)
        inputFiles fileTree("src/kotlin") // (2)
        useInterop 'ckotlinor' // (3)
        nativeLibrary fileTree('src/c/cn_kotlinor.bc') // (4)
        target 'macbook' // (5)
    }
}

其中,(1)處的KotlinorApp名稱,在 build 之后會生成以這個名稱命名的 KotlinorApp.kexe 可執行程序。
(2)處的inputFiles配置的是 kotlin 代碼目錄,程序執行的入口 main 定義在這里。

(3)處的useInterop 配置的是使用哪個互操作配置。我們使用的是前面的 konanInterop 里面的配置 ckotlinor 。

(4) 處的nativeLibrary配置的是本地庫文件。關于'src/c/cn_kotlinor.bc'文件的編譯生成我們在下面講。

(5) 處的target 配置的是編譯的目標平臺,這里我們配置為 'macbook' 。

關于konanArtifacts可選的配置如下所示

 konanArtifacts {
 
       artifactName1 {
 
           inputFiles "files" "to" "be" "compiled"
 
           outputDir "path/to/output/dir"
 
           library "path/to/library"
           library File("Library")
 
           nativeLibrary "path/to/library"
           nativeLibrary File("Library")
 
           noStdLib
           produce "library"|"program"|"bitcode"
           enableOptimization
 
           linkerOpts "linker" "args"
           target "target"
 
           languageVersion "version"
           apiVersion "version"
 
     }
      artifactName2 {
 
           extends artifactName1

           inputDir "someDir"
           outputDir "someDir"
      }
 
   }

konan 編譯任務配置處理類是KonanCompileTask.kt (https://github.com/JetBrains/kotlin-native/blob/master/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanCompileTask.kt)。

16.2.9 完整的 build.gradle 配置

完整的 build.gradle 配置文件內容如下

group 'com.easy.kotlin'
version '1.0-SNAPSHOT'


buildscript {
    repositories {
        mavenCentral()
        maven {
            url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies"
        }
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:0.3"
    }
}

apply plugin: 'konan' // konan 就是用來編譯 Kotlin 為 native 代碼的插件


konanInterop { // konanInterop 主要用來配置 Kotlin 調用 C 的接口
    ckotlinor {
        defFile 'kotlinor.def' // interop 的配置文件
        includeDirs "src/c" // C 頭文件目錄,可以傳入多個
    }
}

konanArtifacts { //konanArtifacts 配置我們的項目
    KotlinorApp { // build 之后會生成 KotlinorApp.kexe 可執行程序
        inputFiles fileTree("src/kotlin") //kotlin 代碼配置,項目入口 main 需要定義在這里
        useInterop 'ckotlinor' //使用前面的 konanInterop 里面的配置  kotlinor{ ... }
        nativeLibrary fileTree('src/c/cn_kotlinor.bc') //自己編譯的 llvm 字節格式的依賴
        target 'macbook' // 編譯的目標平臺
    }
}

提示:關于konan 插件詳細配置文檔:Gradle DSL https://github.com/JetBrains/kotlin-native/blob/master/GRADLE_PLUGIN.md

16.2.10 使用 clang 編譯 C 代碼

為了實用性,我們新建一個 shell 腳本 kclang.sh 來簡化 clang 編譯的命令行輸入參數

#!/usr/bin/env bash
clang -std=c99 -c $1 -o $2 -emit-llvm

這樣,我們把 kclang.sh 放到 C 代碼目錄下,然后直接使用腳本來編譯:

 kclang.sh cn_kotlinor.c cn_kotlinor.bc

我們將得到一個 cn_kotlinor.bc 庫文件。

提示:clang是一個C++編寫、基于LLVM、發布于LLVM BSD許可證下的C/C++/Objective-C/Objective-C++編譯器。它與GNU C語言規范幾乎完全兼容。更多關于 clang 的內容可參考 : http://clang.llvm.org/docs/index.html 。

16.2.11 配置 konan 編譯器主目錄

最后,在執行 Gradle 構建之前,我們還需要指定konan 編譯器主目錄。我們在工程根目錄下面新建 gradle.properties 這個屬性配置文件,內容如下

konan.home=/Users/jack/soft/kotlin-native-macos-0.3

16.2.12 執行構建操作

我們直接在 IDEA 右側的 Gradle 工具欄點擊Tasks ->build -> build 命令執行構建操作

螢幕快照 2017-07-30 03.42.19.png

我們會看到終端輸出

15:12:02: Executing external task 'build'...
:assemble UP-TO-DATE
:check UP-TO-DATE
:downloadKonanCompiler
:genKotlinerInteropStubs
:compileKotlinerInteropStubs
KtFile: kotliner.kt
:compileKonanKotliner
KtFile: main.kt
ld: warning: object file (/var/folders/q5/kvt7_nsd6ngdw5qry4d99xv00000gn/T/combined697750051437954502.o) was built for newer OSX version (10.12) than being linked (10.11)
:compileKonan
:build

BUILD SUCCESSFUL in 29s
4 actionable tasks: 4 executed
15:12:31: External task execution finished 'build'.

構建完成之后,會在build/konan/bin/目錄下面生成一個KotlinorApp.kexe可執行程序,它直接在 Mac OS 上運行,不再依賴JVM 環境了。我們得到的完整的構建輸出目錄樹如下

build
└── konan
    ├── bin
    │   ├── KotlinorApp.kexe
    │   └── KotlinorApp.kt.bc
    ├── interopCompiledStubs
    │   └── ckotlinorInteropStubs
    │       ├── ckotlinorInteropStubs
    │       │   ├── linkdata
    │       │   │   ├── module
    │       │   │   ├── package_ckotlinor
    │       │   │   └── root_package
    │       │   ├── manifest
    │       │   ├── resources
    │       │   └── targets
    │       │       └── macbook
    │       │           ├── kotlin
    │       │           │   └── program.kt.bc
    │       │           └── native
    │       └── ckotlinorInteropStubs.klib
    ├── interopStubs
    │   └── genCkotlinorInteropStubs
    │       └── ckotlinor
    │           └── ckotlinor.kt
    └── nativelibs
        └── genCkotlinorInteropStubs
            └── ckotlinorstubs.bc

16 directories, 10 files

其中在 ckotlinor.kt中,我們可以看出 konan 編譯器還為我們生成了 C 代碼對應的 Kotlin 的接口

@file:Suppress("UNUSED_EXPRESSION", "UNUSED_VARIABLE")
package ckotlinor

import konan.SymbolName
import kotlinx.cinterop.*

fun printHello(): Unit {
    val res = kni_printHello()
    return res
}

@SymbolName("ckotlinor_kni_printHello")
private external fun kni_printHello(): Unit

fun factorial(n: Int): Int {
    val _n = n
    val res = kni_factorial(_n)
    return res
}

@SymbolName("ckotlinor_kni_factorial")
private external fun kni_factorial(n: Int): Int

fun fib(n: Int): Int {
    val _n = n
    val res = kni_fib(_n)
    return res
}

@SymbolName("ckotlinor_kni_fib")
private external fun kni_fib(n: Int): Int


我們在Kotlin 代碼中,調用的就是這些映射到 C 中的函數接口。

16.2.12 執行 kexe 應用程序

我們直接在命令行中執行 KotlinorApp.kexe 如下

chatper16_kotlin_native_helloworld$ build/konan/bin/KotlinorApp.kexe  

我們可以看到如下輸出:

[C]HelloWorld
[C]calc factorial: 1
[C]calc factorial: 0
[C]calc factorial: 2
...
[C]calc factorial: 2
[C]calc factorial: 1
[C]calc factorial: 0
1
2
6
24
120
720
5040
[C]calc fibonacci: 1
[C]calc fibonacci: 2
[C]calc fibonacci: 3
...
[C]calc fibonacci: 3
[C]calc fibonacci: 2
[C]calc fibonacci: 1
1
1
2
3
5
8
13

至此,我們完成了一次簡單的Kotlin Native 與 C 語言互操作在系統級編程的體驗之旅。

我們看到,Kotlin Native仍然看重互操作性(Interoperability)。它能高效地調用C函數,甚至還能從C頭文件自動生成了對應的Kotlin接口,發揚了JetBrains為開發者服務的良好傳統!

但是,在體驗的過程中我們也發現整個過程比較手工化,顯得比較繁瑣(例如手工新建各種配置文件、手工使用 clang 編譯C 代碼等)。

不過,Kotlin Native 的 Gradle 插件用起來還是相當不錯的。相信未來 IDEA 會對 Kotlin Native 開發進行智能的集成,以方便系統編程的開發者更好更快的完成項目的配置以及開發編碼工作。

16.3 Kotlin Native 編譯器 konan 簡介

本小節我們簡單介紹一下Kotlin Native 編譯器的相關內容(主要以 Mac OS 平臺示例)。

bin目錄

bin目錄下面是執行命令行

cinterop       klib           konanc         kotlinc        kotlinc-native  run_konan

run_konan 是真正的入口 shell,它的執行邏輯是

TOOL_NAME="$1"
shift

if [ -z "$JAVACMD" -a -n "$JAVA_HOME" -a -x "$JAVA_HOME/bin/java" ]; then
    JAVACMD="$JAVA_HOME/bin/java"
else
    JAVACMD=java
fi
[ -n "$JAVACMD" ] || JAVACMD=java
...
java_opts=(-ea \
            -Xmx3G \
            "-Djava.library.path=${NATIVE_LIB}" \
            "-Dkonan.home=${KONAN_HOME}" \
           -Dfile.encoding=UTF-8)

KONAN_JAR="${KONAN_HOME}/konan/lib/backend.native.jar"
KOTLIN_JAR="${KONAN_HOME}/konan/lib/kotlin-compiler.jar"
STUB_GENERATOR_JAR="${KONAN_HOME}/konan/lib/StubGenerator.jar"
INTEROP_INDEXER_JAR="${KONAN_HOME}/konan/lib/Indexer.jar"
INTEROP_JAR="${KONAN_HOME}/konan/lib/Runtime.jar"
HELPERS_JAR="${KONAN_HOME}/konan/lib/helpers.jar"
KLIB_JAR="${KONAN_HOME}/konan/lib/klib.jar"
UTILITIES_JAR="${KONAN_HOME}/konan/lib/utilities.jar"
KONAN_CLASSPATH="$KOTLIN_JAR:$INTEROP_JAR:$STUB_GENERATOR_JAR:$INTEROP_INDEXER_JAR:$KONAN_JAR:$HELPERS_JAR:$KLIB_JAR:$UTILITIES_JAR"
TOOL_CLASS=org.jetbrains.kotlin.cli.utilities.MainKt

LIBCLANG_DISABLE_CRASH_RECOVERY=1 \
$TIMECMD "$JAVACMD" "${java_opts[@]}" "${java_args[@]}" -cp "$KONAN_CLASSPATH" "$TOOL_CLASS" "$TOOL_NAME" "${konan_args[@]}"

我們可以看出,Kotlin Native 編譯器 konan 的運行環境還是在 JVM 上,但是它生成的機器碼的可執行程序是直接運行在對應的平臺系統上(直接編譯成機器語言)。

konan目錄

konan目錄是 Kotlin Native 編譯器的核心實現部分。目錄結構如下:

kotlin-native-macos-0.3$ tree konan
konan/
├── konan.properties
├── lib
│   ├── Indexer.jar
│   ├── Runtime.jar
│   ├── StubGenerator.jar
│   ├── backend.native.jar
│   ├── callbacks
│   │   └── shared
│   │       └── libcallbacks.dylib
│   ├── clangstubs
│   │   └── shared
│   │       └── libclangstubs.dylib
│   ├── helpers.jar
│   ├── klib.jar
│   ├── kotlin-compiler.jar
│   ├── protobuf-java-2.6.1.jar
│   └── utilities.jar
└── nativelib
    ├── libcallbacks.dylib
    ├── libclangstubs.dylib
    ├── libllvmstubs.dylib
    └── liborgjetbrainskotlinbackendkonanhashstubs.dylib

6 directories, 16 files

我們可以看到在 run_konan 命令行 shell 中依賴了上面的這些 jar 包。上面的目錄文件是 Mac OS 平臺上的。

對應的 Linux 平臺上的konan目錄文件如下

kotlin-native-linux-0.3$ tree konan
konan
├── konan.properties
├── lib
│   ├── Indexer.jar
│   ├── Runtime.jar
│   ├── StubGenerator.jar
│   ├── backend.native.jar
│   ├── callbacks
│   │   └── shared
│   │       └── libcallbacks.so
│   ├── clangstubs
│   │   └── shared
│   │       └── libclangstubs.so
│   ├── helpers.jar
│   ├── klib.jar
│   ├── kotlin-compiler.jar
│   ├── protobuf-java-2.6.1.jar
│   └── utilities.jar
└── nativelib
    ├── libcallbacks.so
    ├── libclangstubs.so
    ├── libllvmstubs.so
    └── liborgjetbrainskotlinbackendkonanhashstubs.so

6 directories, 16 files

Windows 平臺上的 konan 目錄文件如下

kotlin-native-windows-0.3$ tree konan
konan
├── konan.properties
├── lib
│   ├── Indexer.jar
│   ├── Runtime.jar
│   ├── StubGenerator.jar
│   ├── backend.native.jar
│   ├── callbacks
│   │   └── shared
│   │       └── callbacks.dll
│   ├── clangstubs
│   │   └── shared
│   │       └── clangstubs.dll
│   ├── helpers.jar
│   ├── klib.jar
│   ├── kotlin-compiler.jar
│   ├── protobuf-java-2.6.1.jar
│   └── utilities.jar
└── nativelib
    ├── callbacks.dll
    ├── clangstubs.dll
    ├── llvmstubs.dll
    └── orgjetbrainskotlinbackendkonanhashstubs.dll

6 directories, 16 files

klib 目錄

klib 目錄下是 Kotlin 的標準庫的關聯元數據文件以及 Kotlin Native 針對各個目標平臺的 bc 文件

kotlin-native-macos-0.3$ tree klib
klib/
└── stdlib
    ├── linkdata
    │   ├── module
    │   ├── package_konan
    │   ├── package_konan.internal
    │   ├── package_kotlin
    │   ├── package_kotlin.annotation
    │   ├── package_kotlin.collections
    │   ├── package_kotlin.comparisons
    │   ├── package_kotlin.coroutines
    │   ├── package_kotlin.coroutines.experimental
    │   ├── package_kotlin.coroutines.experimental.intrinsics
    │   ├── package_kotlin.experimental
    │   ├── package_kotlin.internal
    │   ├── package_kotlin.io
    │   ├── package_kotlin.properties
    │   ├── package_kotlin.ranges
    │   ├── package_kotlin.reflect
    │   ├── package_kotlin.sequences
    │   ├── package_kotlin.text
    │   ├── package_kotlin.text.regex
    │   ├── package_kotlin.util
    │   ├── package_kotlinx
    │   ├── package_kotlinx.cinterop
    │   └── root_package
    ├── manifest
    ├── resources
    └── targets
        ├── android_arm32
        │   ├── kotlin
        │   │   └── program.kt.bc
        │   └── native
        │       ├── launcher.bc
        │       ├── runtime.bc
        │       └── start.bc
        ├── android_arm64
        │   ├── kotlin
        │   │   └── program.kt.bc
        │   └── native
        │       ├── launcher.bc
        │       ├── runtime.bc
        │       └── start.bc
        ├── iphone
        │   ├── kotlin
        │   │   └── program.kt.bc
        │   └── native
        │       ├── launcher.bc
        │       ├── runtime.bc
        │       ├── start.bc
        │       ├── start.kt.bc
        │       └── stdlib.kt.bc
        └── macbook
            ├── kotlin
            │   └── program.kt.bc
            └── native
                ├── launcher.bc
                ├── runtime.bc
                └── start.bc

16 directories, 42 files

上面的目錄是 kotlin-native-macos-0.3 平臺的版本。我們可以看出,在Mac OS上,我們可以使用 Kotlin Native 編譯android_arm32、android_arm64、iphone、macbook等目標平臺的機器碼可執行的程序。

另外,對應的 Linux 平臺的目錄文件如下

kotlin-native-linux-0.3$ tree klib
klib/
└── stdlib
    ├── linkdata
    │   ├── module
    │   ├── package_konan
    │   ├── package_konan.internal
    │   ├── package_kotlin
    │   ├── package_kotlin.annotation
    │   ├── package_kotlin.collections
    │   ├── package_kotlin.comparisons
    │   ├── package_kotlin.coroutines
    │   ├── package_kotlin.coroutines.experimental
    │   ├── package_kotlin.coroutines.experimental.intrinsics
    │   ├── package_kotlin.experimental
    │   ├── package_kotlin.internal
    │   ├── package_kotlin.io
    │   ├── package_kotlin.properties
    │   ├── package_kotlin.ranges
    │   ├── package_kotlin.reflect
    │   ├── package_kotlin.sequences
    │   ├── package_kotlin.text
    │   ├── package_kotlin.text.regex
    │   ├── package_kotlin.util
    │   ├── package_kotlinx
    │   ├── package_kotlinx.cinterop
    │   └── root_package
    ├── manifest
    ├── resources
    └── targets
        ├── android_arm32
        │   ├── kotlin
        │   │   └── program.kt.bc
        │   └── native
        │       ├── launcher.bc
        │       ├── runtime.bc
        │       └── start.bc
        ├── android_arm64
        │   ├── kotlin
        │   │   └── program.kt.bc
        │   └── native
        │       ├── launcher.bc
        │       ├── runtime.bc
        │       └── start.bc
        ├── linux
        │   ├── kotlin
        │   │   └── program.kt.bc
        │   └── native
        │       ├── launcher.bc
        │       ├── runtime.bc
        │       └── start.bc
        └── raspberrypi
            ├── kotlin
            │   └── program.kt.bc
            └── native
                ├── launcher.bc
                ├── runtime.bc
                ├── start.bc
                ├── start.kt.bc
                └── stdlib.kt.bc

16 directories, 42 files

也就是說我們可以在 Linux 平臺上編譯android_arm32、android_arm64、linux、raspberrypi等平臺上的目標程序。

對應Windows 平臺的如下

kotlin-native-windows-0.3$ tree klib
klib/
└── stdlib
    ├── linkdata
    │   ├── module
    │   ├── package_konan
    │   ├── package_konan.internal
    │   ├── package_kotlin
    │   ├── package_kotlin.annotation
    │   ├── package_kotlin.collections
    │   ├── package_kotlin.comparisons
    │   ├── package_kotlin.coroutines
    │   ├── package_kotlin.coroutines.experimental
    │   ├── package_kotlin.coroutines.experimental.intrinsics
    │   ├── package_kotlin.experimental
    │   ├── package_kotlin.internal
    │   ├── package_kotlin.io
    │   ├── package_kotlin.properties
    │   ├── package_kotlin.ranges
    │   ├── package_kotlin.reflect
    │   ├── package_kotlin.sequences
    │   ├── package_kotlin.text
    │   ├── package_kotlin.text.regex
    │   ├── package_kotlin.util
    │   ├── package_kotlinx
    │   ├── package_kotlinx.cinterop
    │   └── root_package
    ├── manifest
    ├── mingw
    │   ├── kotlin
    │   │   └── program.kt.bc
    │   └── native
    │       ├── launcher.bc
    │       ├── runtime.bc
    │       └── start.bc
    ├── resources
    └── targets
        └── mingw
            ├── kotlin
            │   └── program.kt.bc
            └── native
                ├── launcher.bc
                ├── runtime.bc
                └── start.bc

10 directories, 32 files

在 Windows 平臺中,Kotlin Native 使用的是 mingw 庫來實現的。目前,在 V0.3預發布版本,我們在 Windows 平臺上可以體驗的東西比較少,像 Android,iOS,Raspberrypi都還不支持。

提示:MinGW,是Minimalist GNUfor Windows的縮寫。它是一個可自由使用和自由發布的Windows特定頭文件和使用GNU工具集導入庫的集合,允許你在GNU/Linux和Windows平臺生成本地的Windows程序而不需要第三方C運行時(C Runtime)庫。MinGW 是一組包含文件和端口庫,其功能是允許控制臺模式的程序使用微軟的標準C運行時(C Runtime)庫(MSVCRT.DLL),該庫在所有的 NT OS 上有效,在所有的 Windows 95發行版以上的 Windows OS 有效,使用基本運行時,你可以使用 GCC 寫控制臺模式的符合美國標準化組織(ANSI)程序,可以使用微軟提供的 C 運行時(C Runtime)擴展,與基本運行時相結合,就可以有充分的權利既使用 CRT(C Runtime)又使用 WindowsAPI功能。

samples目錄

samples目錄下面是官方給出的一些實例。關于這些實例的文檔介紹以及源碼工程是: https://github.com/JetBrains/kotlin-native/tree/master/samples 。想更加深入了解學習的同學可以參考。

本章小結

本章工程源碼: https://github.com/EasyKotlin/chatper16_kotlin_native_helloworld

現在我們可以把 Kotlin 像C 一樣地直接編譯成的機器碼來運行,這樣在 C 語言出現的地方(例如應用于嵌入式等對性能要求比較高的場景),Kotlin 也來了。Kotlin 將會在嵌入式系統和物聯網、數據分析和科學計算、游戲開發、服務端開發和微服務等領域持續發力。

Kotlin 整個語言的架構不可謂不宏大:上的了云端(服務端程序),下的了手機端( Kotlin / Native ),寫的了前端(JS,HTML DSL 等),嵌的了冰箱(Kotlin Native)。Kotlin 儼然已成為一門擅長多個領域的語言了。

在互聯網領域,目前在Web服務端應用開發、Android移動端開發是Kotlin 最活躍的領域。 Kotlin 將會越來越多地進入 Java 程序員們的視野, Java 程序員們會逐漸愛上 Kotlin 。

未來的可能性有很多。但是真正的未來還是要我們去創造。


Kotlin 開發者社區

國內第一Kotlin 開發者社區公眾號,主要分享、交流 Kotlin 編程語言、Spring Boot、Android、React.js/Node.js、函數式編程、編程思想等相關主題。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容