• Kotlin Native实战开发 2018-11-18 09:15:36
    Kotlin Native是一种将Kotlin源码编译成不需要任何VM支持的目标平台二进制数据的技术,编译后的二进制数据可以直接运行在目标平台上,它主要包含一个基于LLVM的后端编译器的和一个Kotlin本地运行时库。设计Kotlin ...
    注:本部分内容来源于《Kotlin入门与实战》,预计9月上市。
    # 16.1 Kotlin Native
    ## 16.1.1 Kotlin Native简介
    Kotlin Native是一种将Kotlin源码编译成不需要任何VM支持的目标平台二进制数据的技术,编译后的二进制数据可以直接运行在目标平台上,它主要包含一个基于LLVM的后端编译器的和一个Kotlin本地运行时库。设计Kotlin Native的目的是为了支持在非JVM环境下进行编程,如在嵌入式平台和iOS环境下,如此一来,Kotlin就可以运行在非JVM平台环境下。
    
    LLVM是Low Level Virtual Machine的缩写,是一种比较底层的虚拟机技术,LLVM由C++编写而成,主要用来优化应用程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time)。LLVM可以有效的解决编译器重复编译代码的问题,并且LLVM制定了LLVM IR这种中间代码表示语言,LLVM IR充分考虑了各种应用场景,有效的提高了代码的编译效率。
    
    在讲解Kotlin Native具体的知识之前,先来看一下计算机高级语言常见两种流派:编译型语言和解释型语言。
    
    所谓编译型语言,是指使用专门的编译器、针对特定平台/操作系统将某种高级语言源代码一次性编译成该平台硬件能够执行的机器码,编译生成的可执行程序可以脱离开发环境,在特定的平台上独立运行。因为编译型语言是一次性编译成机器码的,所以可以脱离开发环境独立运行,而且通常运行效率较高。不过,正因为编译型语言只能被编译成特定平台上的机器码,所以生成的可执行程序通常无法移植到其他平台上运行。例如,现在比较流行的C、C++等高级编程语言都属于编译型语言。
    
    而所谓解释型语言,是指使用专门的解释器对源程序进行逐行解释,并生成特定平台的机器码并立即执行的编程语言。解释型语言通常不需要进行整体的编译和链接处理,解释型语言会把编译型语言中的编译和解释过程混合在一起执行。虽然解释型语言运行效率较低且不能脱离释器独立运行,但解释型语言可以很方便的实现源程序的移植和运行。
    
    ##16.1.2 Kotlin Native编译器
    目前,Kotlin Native主要提供了Mac、Linux和Windows三个主流平台的编译器,使用该编译器可以很轻松的编译出运行在树莓派、iOS、OS X、Windows以及Linux系统上的程序。Kotlin Native支持平台和版本如下表所示。
    
    ```
    支持的系统平台	支持的版本
    Windows	x86_64
    Linux	x86_64、arm32、MIPS、MIPS小端
    MacOS	x86_64
    iOS	arm64
    Android	arm32、arm64
    WebAssembly	wasm32
    ```
    
    表16-1  Kotlin Native支持平台及其版本
    
    编译Kotlin Native项目,首先需要到Github上下载Kotlin Native的编译器软件包,下载地址为:https://github.com/JetBrains/kotlin-native/releases,使用前下载对应的平台版本即可,下载后解压下载的Kotlin Native编译器软件包,其目录结构如图16-1所示。
     ![这里写图片描述](https://img-blog.csdn.net/2018073121162061)
    图16-1  Kotlin Native编译器目录结构图
    当然,也可以通过克隆Kotlin Native编译器的源码进行编译,编译需要先到Github上下载编译器源码,下载地址为:https://github.com/JetBrains/kotlin-native。下载完成后,使用如下命令下载依赖关系,命令如下:
    
    ```
    ./gradlew dependencies:update
    ```
    
    然后,建立编译器和库的关联。
    
    ```
    ./gradlew bundle
    ```
    
    如果需要构建整个项目可能需要很长的时间。然后,使用以下的命令即可编译项目。
    
    ```
    ./gradlew dist distPlatformLibs
    ```
    
    到此,就可以得到Kotlin的Native编译器了,它通常位于项目的./dist/bin目录下,打开bin文件可以看到Native编译器的相关信息,它有7个可执行程序构成,如图15-2所示。通过对比发现,Native编译器的目录结构和Kotlin Native官方提供的编译器的内容是一样的。然后,就可以利用Native编译器编译应用程序了。例如:
    
    ```
    export PATH=./dist/bin:$PATH
    kotlinc hello.kt -o hello
    ```
    
    如果需要进行优化编译,可以使用-opt参数。
    
    ```
    kotlinc hello.kt -o hello -opt
    ```
    
    如果需要对应用程序进行测试,可以使用类似于下面的命令。
    
    ```
    ./gradlew backend.native:tests:run
    ```
    ![这里写图片描述](https://img-blog.csdn.net/20180731211728214)
     
    图16-2  Kotlin的Native编译器目录结构
    在Kotlin Native官方提供的示例中,系统自带了针对不同平台的例子,并且这些例子都是可以直接编译运行的。由于Kotlin Native本身是一个gradle构建的项目,所以可以使用idea直接打开Kotlin Native目录下的samples文件,idea会自动识别该项目。
    ##16.1.3 编译器konan
       打开kotlin-native-macos-0.6文件,其目录结构如图15-3所示。其中,bin目录包含众多的与Kotlin Native相关的执行命令,klib目录则主要包含Kotlin的标准库的关联元数据文件以及针对各个目标平台的bc文件,konan主要包含编译器依赖的一些jar包和一些已经编译好的项目实例,可以使用IntelliJ IDEA直接导入。
     ![这里写图片描述](https://img-blog.csdn.net/20180731211756766)
    图16-3  编译器konan目录结构
    打开Kotlin Native编译器的bin目录可以发现,bin文件主要由cinterop、jsinterop、klib、konanc、kotlinc、kotlinc-native、run_konan等7个可执行文件组成。其中,run_konan是编译器真正的入口,源码如下。
    
    ```
    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
    //省略部分代码
    
    LIBCLANG_DISABLE_CRASH_RECOVERY=1 \
    $TIMECMD "$JAVACMD" "${java_opts[@]}" "${java_args[@]}" -cp "$KONAN_CLASSPATH" "$TOOL_CLASS" "$TOOL_NAME" "${konan_args[@]}"
    ```
    
    可以发现,Kotlin Native编译器konan的运行环境还是需要JVM环境支持的,但是它生成的机器码的可执行程序是不需要JVM环境支持的,可以直接运行在对应的平台系统上。
    
    # 16.2 Kotlin Native实例
    ##16.2.1 构建Kotlin Native项目
    首先,在IDEA中依次选择【File】→【New】→【Project】创建一个普通的 Gradle工程。
     ![这里写图片描述](https://img-blog.csdn.net/20180731211909425)
    图16-4  创建Gradle工程
    ##16.2.2 添加konan插件配置
    创建完成之后,需要修改build.gradle文件配置。打开build.gradle文件并添加如下配置。
    
    ```
    buildscript {
        repositories {
            mavenCentral()
            maven {
                url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies"
            }
        }
        dependencies {
            classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:0.5"
        }
    }
    apply plugin: 'konan'
    ```
    
    其中,kotlin-native-gradle-plugin:0.5是Gradle构建Kotlin Native工程所使用的DSL插件,这个插件发布在https://dl.bintray.com/jetbrains/kotlin-native-dependencies仓库里。除此之外,还需要应用konan插件,konan插件是用来将Kotlin代码编译为native代码的插件,可以通过如下地址来获取更多konan相关的信息。
    
    ```
    https://github.com/JetBrains/kotlin-native/blob/master/GRADLE_PLUGIN.md
    ```
    
    此时,还需要创建一个kotliner.def文件,该文件主要用来配置C源码到Kotlin的映射关系。
    
    ```
    headers=cn_kotliner.h
    ```
    
    ##16.2.3 编写源代码
    接下来,在工程的src目录下新建一个c目录,此目录专门用来存放C代码。首先,创建两个c文件:cn_kotliner.h和cn_kotliner.c。其中,C头文件声明的代码如下。
    
    ```
    #ifndef CN_KOTLINER_H
    #define CN_KOTLINER_H
    
    void printHello();
    int factorial(int n);
    #endif
    ```
    在上面的代码中,主要声明了两个函数,打印HelloWorld的 printHello函数和用来计算阶乘的factorial函数。cn_kotlinor.c的源代码如下:
    
    ```
    #include "cn_kotliner.h"
    #include 
    
    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);
    }
    ```
    
    接下来,还需要创建一个kotlin文件,该文件主要是调用C层的代码,实现跨平台调用。该文件的源码如下:
    
    ```
    import kotliner.*
    
    fun main(args: Array) {
        printHello()
        (1..5).map(::factorial).forEach(::println)
    }
    ```
    
    其中,导入的kotlinor.*包是C语言代码经过clang编译后对应的C接口的包路径,可以在项目的build.gradle配置文件中的konanInterop中配置这个路径。
     ![这里写图片描述](https://img-blog.csdn.net/20180731212057596)
    图16-5  Kotlin Native项目目录结构图
    
    ##16.2.4 添加konanInterop与konanArtifacts配置
    接下来,还需要添加konanInterop和konanArtifacts相关的配置信息。其中,konanInterop主要用来配置Kotlin调用C的接口。相关的源码如下:
    
    ```
    konanInterop {
        ckotlinor {
            defFile 'kotlinor.def'     // interop配置文件
            includeDirs "src/c"      // C头文件目录,可以传入多个
        }
    }
    ```
    
    在上面的配置文件中,ckotlinor是插件中的KonanInteropConfig对象,在konanArtifacts配置中会引用这个ckotlinor。而kotlinor.def是Kotlin Native与C 语言互操作的配置文件,可以在kotlinor.def里面配置C源码到Kotlin的映射关系,该配置文件的内容如下。
    
    ```
    headers=cn_kotlinor.h
    compilerOpts=-Isrc/c
    ```
    
    除此上面使用的选项之外,konanInterop还提供了如下常用的选项。
    
    ```
    konanInterop {
           pkgName {
               defFile   
               pkg 
               target 
               compilerOpts 
               linkerOpts 
               headers  
               includeDirs  
               linkFiles 
               dumpParameters 
           }   
     }
    ```
    
    konanInterop配置参数选项对应的具体含义如下表所示。
    
    ```
    配置选项	选项说明
    defFile	互操作映射关系配置文件
    pkg	C头文件编译后映射为Kotlin的包名
    target	编译目标平台:linux/macbook/iphone等
    compilerOpts	编译选项
    linkerOpts	链接选项
    headers	需要处理的头文件
    includeDirs	包括头文件的目录
    linkFiles	与native stubs链接的文件
    dumpParameters	打印Gradle任务参数的选项配置
    ```
    
    表16-2  konanInterop配置选项说明表
    接下来,需要为项目添加konanArtifacts相关的配置,该配置主要用来处理编译任务的执行。
    
    ```
    konanArtifacts { 
        KotlinorClient {   
            inputFiles fileTree("src/kotlin")  //kotlin代码配置,项目入口main()
            useInterop 'ckotlinor'   //前面的interop配置
            nativeLibrary fileTree('src/c/cn_kotlinor.bc')   //本地库文件配置
            target 'macbook'   // 编译的目标平台
        }
    } 
    ```
    
    konan编译任务配置的处理类是KonanCompileTask.kt,可以在Kotlin Native的kotlin-native-gradle-plugin插件中找到该类。可以通过以下地址来获取更详细的konan插件配置信息。
    
    ```
    https://github.com/JetBrains/kotlin-native/blob/master/GRADLE_PLUGIN.md
    ```
    
    ## 16.2.5 编译与执行
    接下来,在项目的src/c目录下面,用命令行编译上面的代码,命令如下。
    
    ```
    clang -std=c99 -c cn_kotliner.c -o cn_kotliner.bc -emit-llvm
    ```
    
    其中,clang是一个由C++编写的基于LLVM的C/C++/Objective-C/Objective-C++编译器。如果提示找不到clang命令,可以在编译器的dependencies目录中找到相关的内容。当然,还可以使用shell脚本(名称为kclang.sh)来简化clang编译的命令行输入参数。
    
    ```
    #!/usr/bin/env bash clang -std=c99 -c $1 -o $2 -emit-llvm
    ```
    
    接着把kclang.sh放到C代码目录下,然后使用脚本来编译C代码。例如:
    
    ```
    kclang.sh cn_kotlinor.c cn_kotlinor.bc
    ```
    
    通过上面的命令编译之后,将得到一个名为cn_kotlinor.bc的库文件。最后,在执行Gradle构建之前,还需要指定konan编译器主目录。具体的,在工程根目录下面新建一个gradle.properties属性配置文件,该文件格式如下。
    
    ```
    konan.home=
    ```
    例如:
    
    ```
    konan.home=/Users/xiangzhihong /kotlin native/kotlin-native-macos-0.5
    ```
    
    当然,也可以不添加gradle.properties配置文件,那样的话,只需要在编译的时候使用本地的编译器即可。
    然后,在IDEA的Gradle工具栏依次点击【Tasks】→【build】执行构建操作,如图15-5所示。等待项目构建完成,会在项目的build/konan/bin/目录下面生成一个KotlinorClient.kexe的可执行程序,它可以直接运行在Mac OS系统上而不再需要依赖JVM环境。
     ![这里写图片描述](https://img-blog.csdn.net/20180731212410551)
    图16-5  使用Gradle工具栏编译项目
    然后,在命令行中执行KotlinorApp.kexe命令,即可看到输出结果,对应的命令如下。
    build/konan/bin/KotlinorApp.kexe
    可以看到,作为一款致力于跨平台开发的编程语言,Kotlin Native非常注重语言平台的互操作性,可以说,使用Kotlin Native进行跨平台开发优势是非常明显的。
    
    ## 16.2.6 命令行方式编译Kotlin Native
    对于Kotlin Native项目来说,除了允许Gradle方式构建编译外,还可以使用命令行的方式来编译项目。具体来说,编写完Kotlin源码之后,采用shell脚本的方式来构建,或者使用Makefile或build.sh的方式来构建,官方推荐使用shell脚本构建方式,本篇采用与之类似的Makefile脚本方式。例如:
    
    ```
    build : src/kotlin/main.kt kotliner.kt.bc
        konanc src/kotlin/main.kt -library build/kotliner/kotliner.kt.bc -nativelibrary build/kotliner/cn_kotliner.bc -o build/kotliner/kotliner.kexe
    
    kotliner.kt.bc : kotliner.bc kotliner.def
        cinterop -def ./kotliner.def -o build/kotliner/kotliner.kt.bc
    
    kotliner.bc : src/c/cn_kotliner.c src/c/cn_kotliner.h
        mkdir -p build/kotliner
        clang -std=c99  -c src/c/cn_kotliner.c -o build/kotliner/cn_kotliner.bc -emit-llvm
    
    clean:
          rm -rf build/kotliner
    ```
    
    采用命令行方式编译Kotlin Native时,需要先把编译器`/bin`目录加入系统的path环境中,然后再执行make命令,编译完成之后就可以在项目的build/kotliner目录中找到kotliner.kexe文件。
    
    
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20181118091523401.jpeg)
    
    展开全文
  • kotlin native 再次尝试 2019-02-12 12:44:08
    使用IDEA创建了一个kn工程 gradle配置文件长这样 ... id 'kotlin-multiplatform' version '1.3.21' } repositories { mavenCentral() } kotlin { targets { // For ARM, preset should be changed to pre...
  • 本文来自:www.kotliner.cn,文中链接请点击阅读原文查看内容提要:本文通过 gradle 以及 makefile 两种方式对 Kotlin Native 项目...
  • IDEA运行kotlin native 2018-11-27 23:41:45
    今天试了下kotlin native,好久没玩过这个玩意儿了。 然后建了一个kotlin native的工程 发现IDEA一直在说是多平台项目 Kotlin Multiplatform Projects are an experimental feature. 运行kotlin native程序 没有...
  • Kotlin/Native尝试 2019-03-16 17:47:55
    Kotlin/Native尝试 在官网看到Kotlin/Native已经达到1.0 Beta版于是就去尝试了一下,结果发现坑还是挺多的。首先Kotlin/JVM很多库是用不了的,这个已经猜到了。官网说已经预先导入了 POSIX、 gzip、 OpenGL、 Metal...
  • AppCode简介 AppCode是JetBrains公司出品的用于开发Mac OS X以及iOS应用程序的集成开发环境,能够支持Xcode项目的运行和调试功能,并为Swift和Objective-C提供广泛的技术支持。目前,AppCode只能运行在Mac OS X操作...
  • 原文 kotlin native没有预想中的那么美好 kotlin native的横空出世,给很多人(包括我)以美好的幻想:有一个美好的语言,能代替c了。确实是可以,但是要看情况。客户端应用开发,用kotlin应该没问题。...
  • Kotlin Native编程探索 2018-04-14 13:02:02
    Kotlin简介 Kotlin是JetBains开发一种基于JVM的新的编程语言。Kotlin可以编译成字节码运行在JVM上,与Java完美兼容,并在...Kotlin Native利用LLVM来将Kotlin代码编译成本地机器代码,使得Kotlin可以脱离JVM运行。...
  • 引子Kotlin Native 可以编译成 *.so 也就是我们常说的动态库,自然也就可以被 Android 的 Jni 调用,显然 Kotlin Native 官方的 ...
  • 上一篇文章我讲了用 @CName 这个神奇的注解,可以配置 Kotlin Native 函数在符号表中的名字,进而根据 Jni 静态绑定的规则来对应到 Java nat...
  • 我在之前写过一篇文章,讲如何用 Kotlin Native 编写 Native 代码通过 JNI 让 Java 调用。当时因为完全没有注意到 CName 这个神奇的东西的...
  • 第十章 Kotlin Native介绍 http://www.kotliner.cn/2017/04/15/Kotlin%20Native%20%E8%AF%A6%E7%BB%86%E4%BD%93%E9%AA%8C%EF%BC%8C%E4%BD%A0%E6%83%B3%E8%A6%81%E7%9A%84%E9%83%BD%E5%9C%A8%E8%BF%99%E5%84%BF/
  • Kotlin Native的GTK 绑定
  • 原文链接:在 mac os 上运行 kotlin native 的第一个程序:hello world 背景   不久前有群友在讨论kotlin,就翻看了聊天记录,发现了kotlin native,能把kotin代码编译成本地可执行文件。就到kotlin的官方...
  • wait(null) 这么写是不行的 点进去 看到要传一个CValue的类型 public fun wait(__stat_loc: kotlinx.cinterop.CValue&...): platform.posix.__pid_t /* = kotlin.Int */ { /* compiled code */ } 还有...
  • 第16章 使用Kotlin Native开发原生应用
  • Kotlin/Native Kotlin/NativeKotlin的本地化构建工具,可以为Kotlin提供C的互操作性以及将Kotin开发应用编译成本地化的可执行程序。 Kotlin/Native 支持mac、linux、win32等多个平台,本文主要将以win32平台为主要...
  • 根据JetBrains技术主管Nikolay Igotti的介绍,Kotlin/Native 0.4已经可用于为iOS和macOS开发原生应用。此外该版本还为WebAssembly平台提供了实验性支持。 \\Kotlin/Native对iOS/macOS开发的支持,关键在于实现了与...
  • 在这篇博文中,我们将讨论Kotlin/Native应用程序的开发。在这里,我们使用FFMPEG音频/视频解码器和SDL2进行渲染,来开发个简易的视频播放器。希望此文可以成为能对Kotlin/Native开发者有价值的开发指南,同时该文也...
1 2 3 4 5 ... 20
收藏数 4,789
精华内容 1,915
热门标签