Kotlin 是如何专门编译的?

Posted

技术标签:

【中文标题】Kotlin 是如何专门编译的?【英文标题】:How is Kotlin specifically compiled? 【发布时间】:2019-04-27 14:27:09 【问题描述】:

我试图了解 Kotlin 源代码在编译时所经历的过程。 The documentation 状态

当以 JVM 为目标时,Kotlin 会生成与 Java 兼容的字节码。当以 javascript 为目标时,Kotlin 转译为 ES5.1 并生成与包括 AMD 和 CommonJS 在内的模块系统兼容的代码。当以原生为目标时,Kotlin 将生成特定于平台的代码(通过 LLVM)。

我的理解是,当 Kotlin 以 JVM 为目标时,代码被编译/翻译成字节码,然后 JVM 将其解释(?)成机器码。这会是 JIT(Just in time) 编译的一个例子吗?

在定位 javascript 时,使用“transpiles”一词。代码究竟被编译成什么?它在任何步骤都被进一步解释或编译?

当以原生为目标时,代码是否直接编译为机器码? LLVM 采取了哪些步骤?

最后,这是否意味着 Kotlin 既是编译语言又是解释语言?

【问题讨论】:

【参考方案1】:

<...> 代码被编译/翻译成字节码,然后 JVM 将其解释(?)成机器码。这会是 JIT(Just in time) 编译的一个例子吗?

是的,当面向 JVM 时,Kotlin 被编译为 JVM *.class 文件,这是一种字节码格式,以后可以由 JVM 解释,或者在程序运行期间由 JVM 编译为机器码(JIT ),甚至提前 (AOT) 编译成机器代码。在这里,Kotlin 编译器不需要知道字节码将如何被使用。

在定位 javascript 时,使用“transpiles”一词。代码究竟被编译成什么?它在任何步骤都被进一步解释或编译?

Kotlin/JS 的目标格式是 JavaScript 源代码。您可以尝试构建任何 Kotlin/JS 示例和 examine the *.js output files,其中包含 Kotlin 代码转换为的 JS 源代码。我相信这里使用transpiletranslate + compile)这个词来强调目标格式是源代码而不是二进制,而编译器仍然执行许多转换和优化。

同样,JavaScript 源代码是解释的还是 JIT 编译的,这取决于用于运行程序的 JavaScript 引擎。

当以原生为目标时,代码是否直接编译为机器码? LLVM 采取了哪些步骤?

Kotlin/Native 有两种可能的目标形式:

一个*.klib 库,可以在另一个 Kotlin/Native 项目中重用。这是a ZIP archive containing LLVM bitcode along with some Kotlin-specific metadata。 一种特定于平台的二进制文件,采用多种格式之一,包括静态和动态库以及可执行文件。这确实是特定目标平台的机器代码,如果它是库,则可用于链接,如果它是可执行文件,则可直接运行。在这种情况下,Kotlin 编译器调用 the LLVM linker lld 来链接来自 LLVM 位码的二进制文件。

【讨论】:

以上是关于Kotlin 是如何专门编译的?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 gradle 编译中排除 kotlin 文件

Maven 如何编译 java 和 kotlin 编码的混合项目

如何从枚举在 Kotlin 中创建编译时常量?

如何将手机应用程序反编译回 kotlin 代码?

如何避免“附加到使用 kotlin/native 编译器编译的项目的库”错误?

如何使用终端编译和运行 Kotlin (.kt) 文件 [重复]