• 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所示。
    这里写图片描述
    图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
    

    这里写图片描述

    图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直接导入。
    这里写图片描述
    图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工程。
    这里写图片描述
    图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 <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);
    }
    

    接下来,还需要创建一个kotlin文件,该文件主要是调用C层的代码,实现跨平台调用。该文件的源码如下:

    import kotliner.*
    
    fun main(args: Array<String>) {
        printHello()
        (1..5).map(::factorial).forEach(::println)
    }
    

    其中,导入的kotlinor.*包是C语言代码经过clang编译后对应的C接口的包路径,可以在项目的build.gradle配置文件中的konanInterop中配置这个路径。
    这里写图片描述
    图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 <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>
           }   
     }
    

    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环境。
    这里写图片描述
    图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时,需要先把编译器<konan.home>/bin目录加入系统的path环境中,然后再执行make命令,编译完成之后就可以在项目的build/kotliner目录中找到kotliner.kexe文件。

    在这里插入图片描述

    展开全文
  • Kotlin Native编程探索

    2018-04-14 13:02:02
    Kotlin简介 Kotlin是JetBains开发一种基于JVM的新的编程语言。Kotlin可以编译成字节码运行在JVM上,与Java完美兼容,并在...Kotlin Native利用LLVM来将Kotlin代码编译成本地机器代码,使得Kotlin可以脱离JVM运行。...

    Kotlin简介

    Kotlin是JetBains开发一种基于JVM的新的编程语言。Kotlin可以编译成字节码运行在JVM上,与Java完美兼容,并在Java的基础上添加了很多好用的特性。也正因为kotlin的种种优点,Google将Kotlin选为Android开发的一级语言。

    Kotlin Native利用LLVM来将Kotlin代码编译成本地机器代码,使得Kotlin可以脱离JVM运行。借助Kotlin Native,Kotlin也能被打包成lib、exe、dll等格式、运用于嵌入式或其他对性能要求较高的场景。

    Kotlin编译器准备

    这个编译器和Kotlin/JVM工程里的不一样,Kotlin/Native工程里是直接把代码编译成机器码而不是运行在虚拟机上的字节码。下载对应的编译器,或者直接从github上下载源码编译。直接下载release目录下的编译器可以略过下面的编译过程。

    首先运行下面的命令下载依赖包。

    ./gradlew dependencies:update
    

    然后运行下面的命令build编译器,因为编译整包的时间较长,所以建议使用下面的第二种方式或直接下载编译器。

    ./gradlew bundle     // 1.编译整包
    ./gradlew dist       // 2.只编译当前系统对应的包

    将Kotlin编译成机器码

    新建一个kotlin工程,选择使用gradle来构建。
    这里写图片描述
    在项目根目录下新建一个gradle.properties文件,配置编译器的路径。其中Windows下要注意路径分割符,Linux和mac因为分隔符是”/”所以正常写路径就行了。

    konan.home=D\:\\KotlinNative\\kotlin-native-windows-0.6.2         // 1.windows直接下载编译器
    konan.home=D\:\\KotlinNative\\kotlin-native\\dist                 // 2.windows下载源码编译

    在根目录下新建src/main/kotlin目录用于存放Kotlin代码,然后随手就是一个hello world。

    // Main.kt
    fun main(args: Array<String>) {
        println("Hello Kotlin Native")
    }

    编辑build.gradle的内容(其中我注释掉的内容为Kotlin/JVM的配置,可以让Kotlin代码在Intellij上运行,调试Kotlin代码的时候可以用),在把Kotlin编译成机器码的过程中只需要有Kotlin/Native的相关配置就行了。

    buildscript {
    //    ext.kotlin_version = '1.1.4'
    
        repositories {
            mavenCentral()
            maven {
                url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies"
            }
        }
        dependencies {
            classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:0.6"
    //        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        }
    }
    
    apply plugin: 'konan'
    //apply plugin: 'kotlin'
    
    repositories {
        mavenCentral()
    }
    
    //dependencies {
    //    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    //}
    
    konanArtifacts {
        // 这里只是把src/main/kotlin/Main.kt编译成一个名为foo的可执行文件
        program('foo') {
            srcFiles 'src/main/kotlin/Main.kt'
        }
    }

    上面build.gradle中的配置,konanArtifacts这个括号里的内容就是控制打包的相关配置,是我们主要关注的,主要有以下配置项,可以根据自己的需要选择(个人翻译,可以去github看英文原版)。

    // 默认编译的平台
    konan.targets = ['macbook', 'linux', 'wasm32']
    
    // kotlin和api的版本
    konan.languageVersion = 'version'
    konan.apiVersion = 'version'
    
    konanArtifacts {
        // 编译的目标平台 (如果没有的话就是上面konan.targets里面的平台)
        // 生成foo.exe(windows)/foo.kexe(linux)
        program('foo', targets: ['android_arm32', 'android_arm64']) {
    
            // 源代码路径,默认路径为 src/main/kotlin.
            srcDir 'src/other'
    
            // 源文件.
            srcFiles project.fileTree('src')
            srcFiles 'foo.kt', 'bar.kt'
    
            // 生成文件的名字,如果没有就是上面小括号中的foo.
            artifactName 'customName'
    
            // 文件输出的路径,默认为 build/konan/bin
            baseDir 'path/to/output/dir'
    
            libraries {
                // 库文件
                file 'foo.klib'
                files 'file1.klib', file2.klib
                files project.files('file3.klib', 'file4.klib')
    
                // 当前工程中生成的其他文件
                artifact konanArtifacts.bar
                artifact 'baz'
    
                // 其他工程中的生成文件
                artifact project(':path:to:a:project'), 'artifcatName'
    
                // 其他某个工程中生成的所有库文件
                allLibrariesFrom project(':some:project')
    
                // 其他某个工程中的所有的互操作类型的库文件
                allInteropLibrariesFrom project(':some:interop:project')
    
                // 根据名字查找的.klib库文件
                klib 'foo'
                klib 'bar', 'baz'
            }
    
            // 需要链接的native库 (*.bc).
            nativeLibrary project.file('path/to/native/library.bc')
            nativeLibraries 'library1.bc', 'library2.bc'
    
            noStdLib true             // 不链接stdlib (true/false).
            enableOptimizations true  // 开启编译优化 (true/false).
            enableAssertions true     // 在生成二进制文件的时候开启断言 (true/false).
            enableDebug true          // 在生成二进制文件的时候开启debug (true/false).
            noDefaultLibs true        // 不链接默认库
    
            // link参数.
            linkerOpts 'Some linker option', 'More linker options'
    
            // build时打印所有参数.
            dumpParameters true
    
            // 计算编译各阶段时间.
            measureTime true
    
            // 编译过程中依赖的其他任务.
            dependsOn anotherTask
    
            // 传递给编译器的额外命令行参数.
            extraOpts '--time', '--verbose', 'linker'
    
            // 额外编译Linux平台的.
            target('linux') {
                // 输出路径,默认为 <baseDir>/<target>
                destinationDir 'exact/output/path'
    
                // 可以添加和上面类似的其他配置.
            }
        }
    
        library('bar') {
            // 其他参数的配置与上面一样
            // 生成bar.klib文件,默认输出路径为 build/konan/libs
        }
    
        bitcode('baz') {
            // 其他参数的配置与上面一样
            // 生成baz.bc文件,默认输出路径为 build/konan/bitcode
        }
    
        dynamic('quux') {
            // 其他参数的配置与上面一样
            // 生成quux.dll和quux_api.h文件,默认输出路径为 is build/konan/bin
        }
    
        framework('quuux') {
            // 其他参数的配置与上面一样
            // Object-C framework文件,Windows下不支持,默认输出路径为 build/konan/bin
        }
    
        interop('qux') {
            // native API的描述文件,默认路径为 src/main/c_interop/<interop-name>.def
            defFile project.file("deffile.def")
    
             // 头文件.
            headers project.files('header1.h', 'header2.h')
    
            // 其他属性配置同上
    
            // 头文件目录.
            includeDirs {
                allHeaders 'path1', 'path2'
    
                // 根据.def文件中定义的 'headerFilter' 筛选出来的头文件.
                headerFilterOnly 'path1', 'path2'
            }
            // 目录下的所有头文件.
            includeDirs "include/directory" "another/directory"
    
            // 需要额外链接的文件.
            link <files which will be linked with native stubs>
        }
    }

    运行下面的命令或双击Intellij中的build选项进行编译

    ./gradlew build

    这里写图片描述
    编译完之后就可以在build/konan目录下发现生成的目标文件了。
    这里写图片描述
    因为是直接把kotlin代码直接编译成了机器代码,因此可以脱离虚拟机直接运行。
    这里写图片描述

    使用Kotlin和C混合编程

    新建一个src/main/c目录用于放置c文件和.h头文件,用c语言编写一个函数给kotlin调用,代码如下:
    这里写图片描述

    //kotlinor.h
    #ifndef KOTLINOR_H
    #define KOTLINOR_H
    int add(int a, int b);
    #endif
    //kotlinor.c
    #include "kotlinor.h"
    #include <stdio.h>
    int add(int a, int b){
        return a + b;
    }
    //Main.kt
    
    //导入的包名和下面konanArtifacts中配置的一致
    import myPkg.*
    fun main(args: Array<String>) {
        println(add(1, 3))
    }

    使用下面的命令通过c代码生成.bc(BitCode)文件供下面使用

    clang -std=c99 -c kotliner.c(c文件) -o kotliner.bc(生成的bc文件) -emit-llvm

    根据上面的介绍配置build.gradle,修改konanArtifacts中的内容

    konanArtifacts {
        // 这个名字下面会用到,必须保持一致
        interop('myInterop') {
            // kotlin代码中import的包名
            packageName 'myPkg'
            compilerOpts '-Isrc/c'
            // null.def 中没有添加配置,可以按自己需求添加
            defFile 'null.def'
            headers "src/main/c/kotlinor.h"
            includeDirs "src/main/c"
        }
    
        program('foo') {
            srcFiles 'src/main/kotlin/Main.kt'
            // 上一个步骤生成的bc文件
            nativeLibraries 'src/main/c/kotlinor.bc'
    
            libraries {
                // interop的名字
                artifact 'myInterop'
            }
        }
    }

    同样是使用./gradlew build命令编译,就可以在build目录下顺利生成目标文件了。
    这里写图片描述

    这里写图片描述

    PS

    • 第一手最新资料请参考jetbrains的github
      https://github.com/JetBrains/kotlin-native

    • 因为Kotlin/Native编译器是将kotlin编译成机器码的编译器,而不是运行在JVM上的字节码,所以在这里的kotlin代码中不能使用Java sdk里的API。

    • 生成的可执行文件,windows下后缀为exe、Linux下后缀为kexe。windows下可以用直接双击运行,如果程序运行时间很短的话只会看到一个黑框一闪而过。

    展开全文
  • 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...

    之前的一篇:IDEA运行kotlin native

    使用IDEA创建了一个kn工程
    在这里插入图片描述
    gradle配置文件长这样

    plugins {
        id 'kotlin-multiplatform' version '1.3.21'
    }
    repositories {
        mavenCentral()
    }
    kotlin {
        targets {
            // For ARM, preset should be changed to presets.iosArm32 or presets.iosArm64
            // For Linux, preset should be changed to e.g. presets.linuxX64
            // For MacOS, preset should be changed to e.g. presets.macosX64
            fromPreset(presets.linuxX64, 'linux')
    
            configure([linux]) {
                // Comment to generate Kotlin/Native library (KLIB) instead of executable file:
                compilations.main.outputKinds('EXECUTABLE')
                // Change to specify fully qualified name of your application's entry point:
                compilations.main.entryPoint = 'sample.main'
            }
        }
        sourceSets {
            // Note: To enable common source sets please comment out 'kotlin.import.noCommonSourceSets' property
            // in gradle.properties file and re-import your project in IDE.
            linuxMain {
            }
            linuxTest {
            }
        }
    }
    
    task runProgram {
        def buildType = 'release' // Change to 'debug' to run application with debug symbols.
        dependsOn "link${buildType.capitalize()}ExecutableLinux"
        doLast {
            def programFile = kotlin.targets.linux.compilations.main.getBinary('EXECUTABLE', buildType)
            exec {
                executable programFile
                args ''
            }
        }
    }
    

    可使用gradle运行
    在这里插入图片描述
    这一次比我之前试多了一点代码提示,然后编译依旧超级慢,而且无法调试
    然后用CLion试了下
    在这里插入图片描述
    这个main文件夹很奇特
    在这里插入图片描述
    gradle配置还是像纯文本一样
    在这里插入图片描述
    运行依赖gradle,跟IDEA没啥区别
    编译慢,无法调试
    当前gradle版本5.0
    当前kotlin版本1.3.21
    总的来说,kn没啥大的变化

    群里说clion可以调试,我还纳闷
    重新试了下,还真可以调试
    在这里插入图片描述

    展开全文
  • Kotlin/Native is a technology for compiling Kotlin code to native binaries, which can run without a virtual machine. It is an LLVM based backend for the Kotlin compiler and native implementation of t....

    Kotlin/Native is a technology for compiling Kotlin code to native binaries, which can run without a virtual machine. It is an LLVM based backend for the Kotlin compiler and native implementation of the Kotlin standard library.

    Kotlin/Native目前虽然是Beta版,但是已经比较稳定,是目前最靠谱的跨平台技术之一。
    KN的安装过程非常简单,本文将基于Linux/MacOS环境安装KN的过程做可一个简单的整理,详细步骤如下:


    安装JVM


    Kotlin的编译离不开JVM,所以安装JVM是前提条件。JVM的安装想必大家都很清楚,这里就不具体介绍了。

    安装Kotlin/Native


    https://github.com/JetBrains/kotlin/releases/latest
    从官方下载KN最新版本,下载需要使用wget

    mac

    $ brew install wget
    

    linux(ubuntu)

    $ sudo apt install wget
    

    然后使用wget下载KN

    mac

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

    linux(ubuntu)

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

    下载完成后,解压并移动到谁当位置,我们选择路径/usr/local/kotlin-native

    $ 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中添加如下

    $ export PATH=$PATH:/usr/local/kotlin-native/bin/
    

    安装 IntelliJ IDEA

    虽然也可以使用别的IDE进行开发,但是同属Jetbrains家族的产品,对KN的支持自然最到位。天然集成gradle也会为我们在开发中对于各种依赖库的管理提供方便。
    请到IntelliJ IDEA官网自行下载安装即可,过程非常简单
    在这里插入图片描述


    Hello world


    打开IDEA,写下第一行KN代码

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

    编译


    初次运行时需要下载和安装LLVM所依赖的各个package,会稍微花点时间

    $ kotlinc-native hello.kt -o hello
    

    运行


    $ ./hello.kexe
    Hello, World!
    

    程序顺利执行!


    编译Library


    通过-p参数,可以编译成任意形式的Library

    $ kotlinc-native hello.kt -p dynamic
    
    -p 参数 lib类型
    program 可执行二进制
    static .a文件
    dynamic Linux下生成.so, macOS下生成.dylib
    framework iOS/macOS所需的framework
    library klib(Kotlin库)
    bitcode bc文件(LLVM的Bitcodebc)

    可以通过-h查询KN更多参数的使用方法

    $ 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
    

    最后


    编译过程感觉有些慢,据说Kotlin1.4对KN的编译有很多优化,值得期待。

    展开全文
  • Kotlin/Native v0.3 发布,将 Kotlin 编译成机器码


    http://www.oschina.net/news/86090/kotlinnative-v-0-3


    https://kotlinlang.org/


    发布于2017年06月23日


    我们很高兴地宣布 Kotlin / Native v0.3 发布了。随着版本v0.3的发布,Windows作为编译主机和执行目标以及Google Android设备作为本机活动的执行目标都被支持。所以Windows API'Hello World'将变得很简单:

    import win32.*
    fun main(args: Array<String>) {
      MessageBoxW(null, "Привет!","标题", MB_YESNOCANCEL or MB_ICONQUESTION)
    }

    调试

    新版本支持源级调试(仅限单步)。例如:

    $ bin/konanc string0.kt  -g -o string0
    $ lldb ./string0.kexe
    (lldb) target create "string0.kexe"
    Current executable set to 'string0.kexe' (x86_64).
    (lldb) b string0.kt:1
    Breakpoint 1: where = string0.kexe`kfun:main(kotlin.Array<kotlin.String>) + 4 at string0.kt:1, address = 0x0000000100001344
    (lldb) r
    Process 12288 launched: '/Users/jetbrains/kotlin/kotlin-native-release/kotlin-native/string0.kexe' (x86_64)
    Process 12288 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
        frame #0: 0x0000000100001344 string0.kexe`kfun:main(kotlin.Array<kotlin.String>) at string0.kt:1
    -> 1       fun main(args: Array<String>) {
       2           val str = "hello"
       3           println(str.equals("HElLo", true))
       4           val strI18n = "Привет"
       5           println(strI18n.equals("прИВет", true))
       6           println(strI18n.toUpperCase())
       7           println(strI18n.toLowerCase())
    (lldb) s
    Process 12288 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = step in
        frame #0: 0x0000000100001354 string0.kexe`kfun:main(kotlin.Array<kotlin.String>) at string0.kt:3
       1       fun main(args: Array<String>) {
       2           val str = "hello"
    -> 3           println(str.equals("HElLo", true))
       4           val strI18n = "Привет"
       5           println(strI18n.equals("прИВет", true))
       6           println(strI18n.toUpperCase())
       7           println(strI18n.toLowerCase())


    我们引入了一个新的库格式,称为.klib,它将作为Kotlin / Native库的默认分发格式。本地库和框架可以轻松地与.klib进行互操作,并通过指定-library库命令行标志或库Gradle插件选项与Kotlin / Native编译器一起使用。

    二进制文件可以在下面下载:

    完整更新信息请查看发行说明

    Kotlin/Native 能把 Kotlin 编译成机器码,由 JetBrains 公司开发。注意,该项目仍处于实验性阶段,请选择合适的场景进行使用。

    Kotlin/Native 利用 LLVM 将 Kotlin 编译成机器码,现在已支持 4 个平台:

    • Linux (暂时只是 Ubuntu)

    • Mac OS

    • iOS

    • Raspberry Pi


    展开全文
  • 第16章 使用 Kotlin Native 最新上架!!!《 Kotlin极简教程》 陈光剑 (机械工业出版社) 可直接打开京东,淘宝,当当===> 搜索: Kotlin 极简教程 http://www.jianshu.com/p/35b487734339 不得不说 JetBrains ...
  • 内容来源:2017 年 10 月 28 日,沪江资深Android工程师何梁伟在“沪江技术沙龙 - 探寻跨平台开发最佳实践”进行《Kotlin 跨平台,还有Native》演讲分享。IT 大咖说(微信id:itdakashuo)作为独家视频合作方,经...
  • 2019独角兽企业重金招聘Python工程师标准>>> ...
  • 随着版本v0.3的发布,Windows作为编译主机和执行目标以及Google Android设备作为本机活动的执行目标都被支持。所以Windows API'Hello World'将变得很简单: import win32.* fun main(args: Array<...
  • csapp ch10.1练习题

    2019-02-16 09:50:29
    配置kotlin native linuxX64('csappCh10No1') { binaries { // Comment the next section to generate Kotlin/Native library (KLIB) instead of executable file: executable('...
  • Kotlin 1.4的第一个预览版终于发布了,有哪些新亮点和功能呢?一文带你一探究竟!
  • Kotlin 1.4的计划是对2020年语言的升级,其中包括重新实现编译器以提高执行速度。 JetBrains的Kotlin开发人员认为, Kotlin 1.4的重点应该放在“质量和性能”上,而不是添加“大”功能。 JetBrains承诺新的编​​...
  • 我们高兴地宣布新的主要版本的第一个预览版本:Kotlin 1.4-M1。几个月以前,我们针对 Kotlin 1.4 值得期待的亮点发布了一则公告。随着发布临近,我们现在提供一个预览版本,...
  • 作者简介陈琦,携程机票研发部无线研发总监,负责携程App机票业务的技术研发和管理工作。从2017年9月到2019年5月,经过一年半的努力,携程机票App团队完成 90% ...
  • Kotlin 1.4的计划是对语言的升级,该计划将于2020年到期,其中包括重新实现编译器以提高执行速度。 JetBrains的Kotlin开发人员认为, Kotlin 1.4的重点应该放在“质量和性能”上,而不是添加“大”功能。 ...
1
收藏数 20
精华内容 8
热门标签