• 原文链接:在 mac os 上运行 kotlin native 的第一个程序:hello world 背景   不久前有群友在讨论kotlin,就翻看了聊天记录,发现了kotlin native,能把kotin代码编译成本地可执行文件。就到kotlin的官方...

    原文链接:在 mac os 上运行 kotlin native 的第一个程序:hello world


    背景

      不久前有群友在讨论kotlin,就翻看了聊天记录,发现了kotlin native,能把kotin代码编译成本地可执行文件。就到kotlin的官方网站看了一下。觉得kotlin native确实很有潜力,能够零开销调用c代码,这比JNI要好很多。也许能把kotlin当做一个语法先进的c了。
      顺便说一下,我在2015年使用过一年的kotlin,用来做游戏服务器的开发,对kotlin的基本语法很熟悉了。如果kotlin能以很低的开销来做系统开发的话,这是我很乐意看到的。我前学了半年的swift,发现这货的运行开销很高,不是我想要的,现在有了kotlin native,我倒是想发掘一下,看看它究竟能干什么,希望他给的比我期望的更多。
      现在kotlin native的文档很少,基本是零文档,那没办法,想要探索的话只能是:动手!!!

    编译kotlin-native

    1. 从github下载kotlin native
    2. cd kotlin-native
    3. 下载依赖包:
      ./gradlew dependencies:update
    4. 编译
      ./gradlew dist

      至此,我们就得到了kotin的native编译器,它们在目录:./dist/bin。

    编写hello world

      kotlin-native自带了十来个例子,都是可以编译运行的,此刻,我们对kotlin的编译过程还不太熟悉,就先沿用例子中的编译方式。kotin-native本身是一个gradle项目,可以用idea直接打开这个目录,会自动识别项目类型。不要忘记安装kotin插件,这样idea才能识别kotlin的语法。如果你不使用idea,那你可以忽略它。

    1. 翻到kotlin-native/samples,复制socket目录,并命名为hello。
    2. 进入hello目录,保留build.gradle和main目录,删除其余文件。
    3. 修改hello/build.gradle如下,这里是告诉gradle要编译Hello.kt这个文件:

      apply plugin: 'konan'
      konanArtifacts {
       Hello {
      
       }
      }
      
    4. 删除hello/src/main/kotlin下的所有文件,在hello/src/main/kotlin下创建文件Hello.kt,内容如下,这程序只打印了两个字:
      import kotlinx.cinterop.*
      fun main(args: Array<String>) {
       println("Hello world")
      }
      
    5. 修改 kotlin-native/settings.gradle,添加一行include ‘:hello’
      include ':tensorflow'
      include ':concurrent'
      include ':hello'
      

    编译方法1:命令行编译

      上面的步骤中,我们编写了程序,并修改了主配置,添加了我们新建的项目。接下来,我们来编译这个程序。

    1. 打开命令行终端
    2. cd kotlin-native/samples/hello
    3. 执行 ../gradlew build
    4. 此时会打印一堆东西,耐心等待,如果你上面的步骤没有错误,这里最终会打印:

       BUILD SUCCESSFUL
      
       Total time: 20.522 secs
      

    编译方法2:从idea编译

    1. 右键点击:kotlin-native/samples/hello/build.gradle,选择run
    2. 观察控制台输出,如果出现如下提示,说明成功(注意:一定要有KtFile: Hello.kt这一行): 

       KtFile: Hello.kt
       :hello:build
      
       BUILD SUCCESSFUL
      
       Total time: 25.053 secs
      
    3. 如果没有KtFile: Hello.kt这一行,就需要给kotlin-native/samples/hello/build.gradle添加运行参数,方法是:
      1. 在idea右上角的“运行”图标的左侧,点击下拉选项,点击“edit configurations”,
      2. 在“Program arguments”后填写“build”。意思是告诉gradle执行build任务。
      3. 再次运行kotlin-native/samples/hello/build.gradle

    运行

      编译出来的文件位于:kotlin-native/samples/hello/build/konan/bin,直接在命令行执行它即可,结果如下:

        zhmt$ ./build/konan/bin/Hello.kexe
        Hello world
    

    至此,我们的第一个kotlin native程序顺利执行。



    展开全文
  • 在这篇博文中,我们将讨论Kotlin/Native应用程序的开发。在这里,我们使用FFMPEG音频/视频解码器和SDL2进行渲染,来开发个简易的视频播放器。希望此文可以成为能对Kotlin/Native开发者有价值的开发指南,同时该文也...

    在这篇博文中,我们将讨论Kotlin/Native应用程序的开发。在这里,我们使用FFMPEG音频/视频解码器和SDL2进行渲染,来开发个简易的视频播放器。希望此文可以成为能对Kotlin/Native开发者有价值的开发指南,同时该文也会解释使用该平台的预期机制。

    \\

    在本教程中,我们主要关注的是Kotlin/Native,我们只会粗略地介绍一下如何开发视频层。您可以参阅这篇名为《如何用不到1000行代码编写一个视频播放器》的优秀教程,以了解如何用C语言实现它。如果您的兴趣点在于比较C语言的编码与Kotlin/Native编码的不同之处,我建议您从本教程开始。

    \\

    理论上,每一个视频播放器的工作都相当简单:读入带有交错的视频帧和音频帧的输入流,解码并显示视频帧,同时与音频流同步。通常,这一工作由多个线程完成,执行流解码、播放视频和音频。要准确的做到这些,需要线程同步和特定的实时保证,如果音频流没有被及时解码,播放声音听起来会很不稳定,如果视频帧没有及时显示,影像看起来会很不流畅。

    \\

    Kotlin/Native不鼓励您使用线程,也不提供在线程之间共享Kotlin对象的方法。然而,我们相信在Kotlin/Native中并发的软实时编程很容易实现,所以我们决定从一开始就以并发的方式来设计我们的播放器。来看看我们是怎么做到的吧。

    \\

    Kotlin/Native计算并发性是围绕workers构建的。Worker是比线程更高级的并发性概念,不像对象共享和同步,它允许对象传输,因此每一时刻只有一个workers可以访问特定对象。这意味着,访问对象数据时不需要同步,因为多个访问永远不能同时进行。workers可以接收执行请求,这些请求可以接受对象并根据需要执行任务,然后将结果返回给需要计算结果的人。这样的模型确保了许多典型的并发编程错误(例如对共享数据的不同步访问,或者由未排序的锁导致的死锁)不再出现。

    \\

    让我们看看,它是如何转化为视频播放器架构的。我们需要对某些容器格式进行解码,比如avi.mkv或者 .mpg,它对交叉音频和视频流进行多路分解、解码,然后将解压缩的音频提供给SDL音频线程。解压后的视频帧应与声音播放同步。为了达到这个目标,worker概念的出现也便是理所当然的了。我们为解码器生成一个worker,并在需要的时候向它请求视频音频数据。在多核机器上,这意味着解码可以与播放并行进行。因此,解码器是一个来自UI线程和音频线程的数据生成器。

    \\

    无论何时我们需要获取下一个音频或视频数据块时,我们都依赖于全能的schedule()函数。它将调度大量的工作给特定的worker执行,以便提供输入参数和返回Future实例,这些可能被挂起,直到任务被目标worker执行完。Future对象可能被销毁,因此产生的对象将直接从worker线程返回到请求程序线程。

    \\

    Kotlin/Native运行时理论上讲是线性的,所以当运行多个线程时,需要在做其他操作之前调用函数konan.initRuntimeIfNeeded(),我们在音频线程回调中也是这样做的。为了简化音频播放,我们将音频帧重新采样到两个通道,并以44100的采样率对16位整数流进行标识

    \\

    视频帧可以被解码成用户需要的大小,当然它会有个默认值,同时它的位深度依赖于用户桌面默认设置。还请注意下Kotlin/Native特有的操作C指针的方法,即

    \\
    \private val resampledAudioFrame: AVFrame =\        disposable(create = ::av_frame_alloc, dispose = ::av_frame_unref).pointed\...\with (resampledAudioFrame) {\    channels = output.channels\    sample_rate = output.sampleRate\    format = output.sampleFormat\    channel_layout = output.channelLayout.signExtend()\}
    \\

    我们声明resampledAudioFrame作为由FFMPEG API调用avframealloc()和avframeunref()创建的C程序中的一次性资源。然后,我们将它所指向的值设置成它所期望的字段。需要注意的是,我们可以将FFMPEG(如AV_PIX_FMT_RGB24)声明的定义作为Kotlin的常量。但是,由于它们没有类型信息,并且默认情况下是Int类型的,如果某个字段具有不同的类型(比如channellayout),那便需要调用适配器函数signExtend()。这是编译器的内在特性,它会插入适当的转换中

    \\

    在设置完解码器后,我们开始播放流程。这没有什么特别的,只是检索下一个帧,将它呈现给纹理,并在屏幕上显示这个纹理。至此,视频帧便被渲染了。音频线程回调是由音频线程回调处理的,它从解码器中获取下一个采样缓冲区,并将其反馈给音频引擎。

    \\

    音频/视频同步是必须要保证的,它可以确保我们没有太多的未播放的音频帧。真正的多媒体播放器应该依赖于帧时间戳,我们只计算它,但永远不会使用。这里有一个有趣的地方

    \\
    \val ts = av_frame_get_best_effort_timestamp(audioFrame.ptr) * \  av_q2d(audioCodecContext.time_base.readValue())
    \\

    它展示了如何使用api接收C语言的结构体。它是在libavutil/rational.h中声明的

    \\
    \static inline double av_q2d(AVRational a){\    return a.num / (double) a.den;\}
    \\

    因此,要通过值传递它,我们首先需要在字段上使用readValue()。

    \\

    总结来说,多亏了FFMPEG库,我们才能用较少的代价便实现了一个支持多种输入格式的简易音频/视频播放器。这里我们还讨论了Kotlin/Native中基于C语言的互操作性相关的基础知识,以及更容易使用和维护的并发方法。 

    \\

    英文原文链接Application development in Kotlin/Native

    \\

    感谢冬雨对本文的审校。

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

    在这里插入图片描述

    展开全文
  • AppCode是JetBrains公司出品的用于开发Mac OS X以及iOS应用程序的集成开发环境,能够支持Xcode项目的运行和调试功能,并为Swift和Objective-C提供广泛的技术支持。目前,AppCode只能运行在Mac OS X操作系统环境下,...

    AppCode简介

    AppCode是JetBrains公司出品的用于开发Mac OS X以及iOS应用程序的集成开发环境,能够支持Xcode项目的运行和调试功能,并为Swift和Objective-C提供广泛的技术支持。目前,AppCode只能运行在Mac OS X操作系统环境下,作为XCode的高级替代品,AppCode继承了IDEA的诸多优良特性,是Mac OS X和iOS应用程序开发的又一利器。
    Kotlin Native是一种能够将Kotlin源代码编译成不需要任何虚拟机支持的二进制技术,编译后的二进制数据可以直接运行在目标平台上。Kotlin Native在0.4版本引入了对Objective-C API的调用支持,并引入了对WebAssembly的实验性支持。要想使用Kotlin来开发iOS应用,需要先下载最新版的AppCode(即AppCode 2018.1.1及以上版本),然后安装【Kotlin Native for AppCode】插件。
    安装的步骤为,依次选择【AppCode】→【Preferences】→【Plugins】打开JetBrains的插件页面,然后搜索【Kotlin Native for AppCode】并安装,如图16-6所示。
    这里写图片描述

    创建Kotlin Native项目

    Kotlin Native使用Gradle作为默认构建工具,想要在Xcode中编译Kotlin Native项目,需要在项目中添加相关的运行脚本,该脚本调用Gradle来构建Kotlin Native工程。当然,也可以借助一些第三方的IDE,如AppCode,使用AppCode之前需要先安装【Kotlin Native for AppCode】插件。
    启动AppCode,依次选择【Kotlin/Native】→【Single View APP with a Kotlin/Native Framwork】即可创建iOS应用程序,使用Kotlin/Native方式创建的iOS项目支持使用Kotlin语言来编写iOS应用程序,如图16-7所示。
    这里写图片描述
    等待项目构建完成,可以看到,使用Kotlin/Native方式创建的iOS项目的目录结构如图16-8所示。
    这里写图片描述
    相比使用Xcode创建的原生iOS项目而言,使用Kotlin/Native方式创建的iOS项目显然多一些配置文件(如Frameworks和KotlinNativeFramework)。文件的具体含义如下:

    • Projects:主要用于存放Mac软件开发的可执行文件等,iOS应用开发很少用到这个文件;
    • Frameworks:主要用于存放项目依赖的一些系统库和第三方库;
    • Project:此目录用于存放与项目相关的源码,也是iOS应用开发的核心组成部分;
    • KotlinNativeFramework:用于存放和KotlinNative相关的库。

    此时,只需要点击【Run】按钮即可在iPhone模拟器或者真机中启动应用程序。不过,此时的程序还没有实现任何的功能,为了在项目中使用Kotlin来编写iOS应用程序,可以在Kotlin Native项目的Project文件中创建一个Kotlin的文件目录(如src/main/kotlin),然后添加一个ViewController类,如图16-9所示。
    这里写图片描述
    需要注意的是,使用AppCode创建的Kotlin Native项目默认是没有引入iOS的UIKit.framework系统库的,所以在使用iOS的相关库之前需要先导入相应的库。
    ViewController类的源码如下:

    import kotlinx.cinterop.ExportObjCClass
    import kotlinx.cinterop.ObjCAction
    import kotlinx.cinterop.ObjCOutlet
    import platform.Foundation.NSCoder
    import platform.UIKit.*
    import kotlinx.cinterop.initBy
    
    @ExportObjCClass
    class ViewController: UIViewController {
    
        constructor(aDecode:NSCoder): super(aDecode)
        override fun initWithCoder(aDecode:NSCoder) =initBy(ViewController(aDecode))
    
        @ObjCOutlet
        lateinit var label: UILabel
    
        @ObjCOutlet
        lateinit var textField: UITextField
    
        @ObjCOutlet
        lateinit var button:UIButton
    
        @ObjCAction
        fun click(){
            label.text="Hello,${textFiled.text}"
        }
    }
    

    由于开发者自己定义的文件目录未被标记为源根目录,是不会被编译系统识别的,所以需要将“src/main/kotlin”目录标记为项目源码目录才能够被系统识别。

    Kotlin Native测试

    众所周知,AppCode本身就是基于IntelliJ IDEA的Kotlin插件,所以很多支持Kotlin的功能对于Kotlin/Native也是同样支持的(如代码检查、重构等操作)。
    这里写图片描述
    同时,AppCode插件也支持使用kotlin.test框架来编写测试代码。在项目名上右键,依次选中【Project Settings…】→【项目名】,然后点击左下角的添加按钮,如图16-11所示。
    这里写图片描述
    等待项目构建完成,然后选中【edit configurations…】打开项目配置面板并添加“Kotlin/Native test”选项来添加测试用例,如图16-12所示。
    这里写图片描述
    当然,除了上面介绍的功能外,Kotlin Native还支持调用Objective-C标准 API,而且也为此提供了非常便捷的阅读API文档的方法,可以说Kotlin Native是Kotlin多平台的真正魅力之所在。

    展开全文
  • Kotlin/NativeKotlin的本地化构建工具,可以为Kotlin提供C的互操作性以及将Kotin开发应用编译成本地化的可执行程序。 Kotlin/Native 支持mac、linux、win32等多个平台,本文主要将以win32平台为主要介绍 使用...
        

    Kotlin/Native

    Kotlin/Native是Kotlin的本地化构建工具,可以为Kotlin提供C的互操作性以及将Kotin开发应用编译成本地化的可执行程序。

    Kotlin/Native 支持mac、linux、win32等多个平台,本文主要将以win32平台为主要介绍

    使用Gradle构建

    Gradle构建文件

    创建hello/src/main/kotlin/build.gradle:

    buildscript {
        repositories {
            mavenCentral()
            maven {
                url "http://dl.bintray.com/jetbrains/kotlin-native-dependencies"
            }
        }
        dependencies {
            classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:0.7"
        }
    }
    // 启用konan插件提供本地化编译支持
    apply plugin: 'konan'
    // 指定编译平台,windows为mingw,其它包括linux,ios等
    konan.targets = ['mingw']
    // konan编译应用名
    konanArtifacts {
        program('hello')
    }

    随便写点测试代码

    创建hello/src/main/kotlin/main.kt:

    /**
     * main方法,程序主入口
     * 注意此处不需要包名
     */
    fun main(args: Array<String>) {
        println("Hello Kotlin/Native with Gradle!")
    }

    使用Gradle构建

    目前的项目结构应该是这样的:

    hello
    --build.gradle
    --src
    ----main
    ------kotlin
    --------main.kt

    BUILD它!

    在hello目录下执行:

    gradle build

    如果幸运的话,你将看到构建成功的信息:

    $ gradle build
    > Task :assemble UP-TO-DATE
    > Task :check UP-TO-DATE
    > Task :checkKonanCompiler
    > Task :compileKonanHelloMingw_x64
    > Task :compileKonanHello
    > Task :compileKonan
    > Task :build
    
    BUILD SUCCESSFUL in 5s
    2 actionable tasks: 2 executed

    Build成功后在hello文件夹下会发现有新增的build文件夹,其包括了编译后的输出文件,一般我们的可执行文件会在这个路径下:
    hello/build/konan/bin/mingw_x64/hello.exe
    运行他看看?

    $ cd build/konan/bin/mingw_x64/
    $ ./hello
    Hello Kotlin/Native with Gradle!

    然后呢?

    至此,我们已经初步掌握了使用kotlin/Native构建的方法,接下来让我们试着写点什么吧!

    展开全文
  • 当你还在死扣泛型语法的时候,别人的文章早就说了Kotlin/NativeKotlin1.3的新特性”。瞬间感觉自己out了,今天我们就说说这些时髦的东西,也许你能看到一些和别人不一样的东西哦。 前段时间你们的熊猫小哥哥(也...
  • Kotlin Native 详细体验,你想要的都在这儿
  • KotlinConf 大会宣布了 Kotlin 1.2 RC 版,并宣布 Kotlin/Native 已支持用于开发 iOS 应用和 Web 应用开发。 近日,首届官方举办的 Kotlin 专题会议 KotlinConf 正式开幕,来自世界各地约 1200 名...
  • 原文 kotlin native没有预想中的那么美好 kotlin native的横空出世,给很多人(包括我)以美好的幻想:有一个美好的语言,能代替c了。确实是可以,但是要看情况。客户端应用开发,用kotlin应该没问题。...
  • 前段时间学习使用TornadoFx一个kotlin版的javaFx框架开发了一个应用,完成后,第一次遇到打包jar文件(之前一直写JS前端和PHP后端,从来没用过java),心累啊,然后就是打包成为EXE格式的程序。 这篇文章只做打包的...
1 2 3 4 5 ... 20
收藏数 2,992
精华内容 1,196