Kotlin/Native 库
最终更新: 2025/02/06Kotlin 编译器使用方法
要通过 Kotlin/Native 编译器编译产生库文件, 请使用 -produce library
或 -p library
参数. 例如:
$ kotlinc-native foo.kt -p library -o bar
这个命令会编译源代码文件 foo.kt
, 输出为库文件 bar.klib
.
要链接一个库, 请使用 -library <name>
或 -l <name>
参数. 例如:
$ kotlinc-native qux.kt -l bar
这个命令会编译源代码文件 qux.kt
, 与库文件 bar.klib
链接, 输出为 program.kexe
.
cinterop 工具使用方法
cinterop 工具会对原生的库文件生成 .klib
格式的包装. 比如, 可以使用 Kotlin/Native 发布中附带的简单的 libgit2.def
原生库定义文件
$ cinterop -def samples/gitchurn/src/nativeInterop/cinterop/libgit2.def -compiler-option -I/usr/local/include -o libgit2
我们可以得到 libgit2.klib
文件.
详情请参见 与 C 代码交互.
klib 工具
klib 库管理工具可以用来查看和安装库.
可用的命令如下:
content
– 列出库的内容:$ klib contents <name>
info
– 查看库的内容细节:$ klib info <name>
install
– 要把库安装到默认的位置, 可以使用:$ klib install <name>
remove
– 从默认的仓库中删除一个库, 可以使用:$ klib remove <name>
以上所有命令都可以接受一个 -repository <directory>
参数, 用来指定默认值以外的仓库位置.
$ klib <command> <name> -repository <directory>
几个例子
首先我们来创建一个库. 把我们这个小小的库的源代码放在 kotlinizer.kt
文件内:
package kotlinizer
val String.kotlinized
get() = "Kotlin $this"
$ kotlinc-native kotlinizer.kt -p library -o kotlinizer
库会被创建到当前目录下:
$ ls kotlinizer.klib
kotlinizer.klib
现在我们来看看库的内容:
$ klib contents kotlinizer
你可以将 kotlinizer
库安装到默认的仓库中:
$ klib install kotlinizer
然后在当前目录中删除它的一切痕迹:
$ rm kotlinizer.klib
编写一个很短的程序, 放在 use.kt
文件中:
import kotlinizer.*
fun main(args: Array<String>) {
println("Hello, ${"world".kotlinized}!")
}
然后编译这个程序, 并链接你刚才创建的库:
$ kotlinc-native use.kt -l kotlinizer -o kohello
然后运行这个程序:
$ ./kohello.kexe
Hello, Kotlin world!
祝你玩得开心!
高级问题
库的查找顺序
当我们指定 -library foo
参数时, 编译器会按照以下顺序查找 foo
库:
当前编译目录, 或一个绝对路径.
通过
-repo
参数指定的所有仓库.默认仓库中安装的所有库.
note
默认仓库是
~/.konan
. You can change it 你可以设置 Gradle 属性kotlin.data.dir
来修改这个值.或者, 也可以使用
-Xkonan-data-dir
编译器选项, 通过cinterop
和konanc
工具来配置你的的自定义目录路径.$installation/klib
目录中安装的所有库.
库文件的格式
Kotlin/Native 库是 zip 文件, 包含预定义的目录结构, 如下:
foo.klib
解压缩到 foo/
目录后会得到以下内容:
- foo/
- $component_name/
- ir/
- 序列化后的 Kotlin IR.
- targets/
- $platform/
- kotlin/
- Kotlin 编译产生的 LLVM bitcode 文件.
- native/
- 其他原生对象的 bitcode 文件.
- $another_platform/
- 可能存在几组平台相关的目录, 其中都包含 kotlin 和 native 目录.
- linkdata/
- 一组 ProtoBuf 文件, 包含序列化链接元数据(serialized linkage metadata).
- resources/
- 一般资源文件, 比如图像文件. (暂时没有使用).
- manifest - 库的描述文件, 使用 java property 格式.
在你的 Kotlin/Native 环境的 klib/stdlib
目录下可以找到这些库文件结构的例子.
在 klib 中使用相对路径
note
klib 中的相对路径功能从 Kotlin 1.6.20 开始可用.
源代码文件的序列化后的 IR 表达是一个 klib
库的一部分. 其中包含文件路径, 用于生成正确的调试信息. 默认情况下, 存储的路径是绝对路径. 使用 -Xklib-relative-path-base
, 你可以修改库的格式, 在 artifact 中只使用相对路径. 要让这个功能有效, 需要向编译器选项的参数传递一个或多个源代码文件基准路径:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
// ...
tasks.named<KotlinCompilationTask<*>>("compileKotlin").configure {
// $base 是源代码文件的基准路径
compilerOptions.freeCompilerArgs.add("-Xklib-relative-path-base=$base")
}
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
// ...
tasks.named('compileKotlin', KotlinCompilationTask) {
compilerOptions {
// $base 是源代码文件的基准路径
freeCompilerArgs.add("-Xklib-relative-path-base=$base")
}
}