mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-26 23:50:16 +08:00
Configure Rust interop
This commit is contained in:
parent
be8100fc9a
commit
ee71263f41
@ -16,6 +16,9 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPI
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||
import java.io.File
|
||||
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
@ -60,16 +63,18 @@ fun Project.configureHMPPJvm() {
|
||||
|
||||
val nativeMainSets = mutableListOf<KotlinSourceSet>()
|
||||
val nativeTestSets = mutableListOf<KotlinSourceSet>()
|
||||
val nativeTargets = mutableListOf<KotlinNativeTarget>()
|
||||
|
||||
if (ideaActive) {
|
||||
when {
|
||||
val target = when {
|
||||
Os.isFamily(Os.FAMILY_MAC) -> if (Os.isArch("aarch64")) macosArm64("native") else macosX64("native")
|
||||
Os.isFamily(Os.FAMILY_WINDOWS) -> mingwX64("native")
|
||||
else -> linuxX64("native")
|
||||
}
|
||||
nativeTargets.add(target)
|
||||
} else {
|
||||
// 1.6.0
|
||||
val nativeTargets: List<String> = arrayOf(
|
||||
val nativeTargetNames: List<String> = arrayOf(
|
||||
// serialization doesn't support those commented targets
|
||||
// "androidNativeArm32, androidNativeArm64, androidNativeX86, androidNativeX64",
|
||||
"iosArm32, iosArm64, iosX64, iosSimulatorArm64",
|
||||
@ -80,11 +85,12 @@ fun Project.configureHMPPJvm() {
|
||||
"mingwX64",
|
||||
// "wasm32" // linuxArm32Hfp, mingwX86
|
||||
).flatMap { it.split(",") }.map { it.trim() }
|
||||
presets.filter { it.name in nativeTargets }
|
||||
presets.filter { it.name in nativeTargetNames }
|
||||
.forEach { preset ->
|
||||
val target = targetFromPreset(preset, preset.name)
|
||||
val target = targetFromPreset(preset, preset.name) as KotlinNativeTarget
|
||||
nativeMainSets.add(target.compilations[MAIN_COMPILATION_NAME].kotlinSourceSets.first())
|
||||
nativeTestSets.add(target.compilations[TEST_COMPILATION_NAME].kotlinSourceSets.first())
|
||||
nativeTargets.add(target)
|
||||
}
|
||||
|
||||
if (!ideaActive) {
|
||||
@ -98,31 +104,8 @@ fun Project.configureHMPPJvm() {
|
||||
}
|
||||
}
|
||||
|
||||
// nativeTarget.apply {
|
||||
// val myrust by compilations.getByName("main").cinterops.creating {
|
||||
// headers(project.projectDir.resolve("untitled/myrust.h"))
|
||||
// }
|
||||
//
|
||||
// binaries {
|
||||
// sharedLib {
|
||||
// linkerOpts("-v")
|
||||
// linkerOpts("-L${project.projectDir.resolve("untitled/target/debug/").absolutePath}")
|
||||
//// linkerOpts("-lmyrust")
|
||||
// linkerOpts("-Wl,-undefined,dynamic_lookup") // resolve symbols in runtime
|
||||
// baseName = "mykotlin"
|
||||
// }
|
||||
//
|
||||
// executable {
|
||||
//
|
||||
// linkerOpts("-v")
|
||||
// linkerOpts("-L${project.projectDir.resolve("untitled/target/debug/").absolutePath}")
|
||||
//// linkerOpts("-lmyrust")
|
||||
// linkerOpts("-Wl,-undefined,dynamic_lookup") // resolve symbols in runtime
|
||||
// baseName = "KotlinExecutable"
|
||||
// entryPoint = "main.main"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
configureNativeInterop("main", projectDir.resolve("src/nativeMainInterop"), nativeTargets)
|
||||
configureNativeInterop("test", projectDir.resolve("src/nativeTestInterop"), nativeTargets)
|
||||
|
||||
|
||||
val sourceSets = kotlinSourceSets.orEmpty()
|
||||
@ -151,4 +134,107 @@ fun Project.configureHMPPJvm() {
|
||||
nativeMain.dependsOn(commonMain)
|
||||
nativeTest.dependsOn(commonTest)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.configureNativeInterop(
|
||||
compilationName: String,
|
||||
nativeInteropDir: File,
|
||||
nativeTargets: MutableList<KotlinNativeTarget>
|
||||
) {
|
||||
if (nativeInteropDir.exists() && nativeInteropDir.isDirectory && nativeInteropDir.resolve("build.rs").exists()) {
|
||||
val crateName = project.name.replace("-", "_")
|
||||
|
||||
val headerName = "$crateName.h"
|
||||
val rustLibDir = nativeInteropDir.resolve("target/debug/")
|
||||
|
||||
configure(nativeTargets) {
|
||||
compilations.getByName(compilationName).cinterops.create(compilationName) {
|
||||
val headerFile = nativeInteropDir.resolve(headerName)
|
||||
if (headerFile.exists()) headers(headerFile)
|
||||
defFile(nativeInteropDir.resolve("interop.def"))
|
||||
}
|
||||
|
||||
binaries {
|
||||
sharedLib {
|
||||
linkerOpts("-v")
|
||||
linkerOpts("-L${rustLibDir.absolutePath.replace("\\", "/")}")
|
||||
// linkerOpts("-lmyrust")
|
||||
linkerOpts("-Wl,-undefined,dynamic_lookup") // resolve symbols in runtime
|
||||
baseName = project.name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val cbindgen = tasks.register("cbindgen${compilationName.titlecase()}") {
|
||||
group = "mirai"
|
||||
inputs.files(nativeInteropDir.resolve("src"))
|
||||
outputs.file(nativeInteropDir.resolve(headerName))
|
||||
doLast {
|
||||
exec {
|
||||
workingDir(nativeInteropDir)
|
||||
commandLine(
|
||||
"cbindgen",
|
||||
"--config", "cbindgen.toml",
|
||||
"--crate", crateName,
|
||||
"--output", headerName
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val bindgen = tasks.register("bindgen${compilationName.titlecase()}") {
|
||||
group = "mirai"
|
||||
val bindingsPath = nativeInteropDir.resolve("src/bindings.rs")
|
||||
inputs.files(nativeInteropDir.resolve("src"))
|
||||
outputs.file(bindingsPath)
|
||||
doLast {
|
||||
exec {
|
||||
workingDir(nativeInteropDir)
|
||||
// bindgen input.h -o bindings.rs
|
||||
commandLine(
|
||||
"bindgen",
|
||||
buildDir.resolve("bin/native/debugShared/lib${crateName}_api.h"),
|
||||
"-o", bindingsPath,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var targetCompilation: KotlinNativeCompilation? = null
|
||||
configure(nativeTargets) {
|
||||
val compilations = compilations.filter { nativeInteropDir.name.contains(it.name, ignoreCase = true) }
|
||||
check(compilations.isNotEmpty()) { "Should be at lease one corresponding native compilation, but found 0" }
|
||||
targetCompilation = compilations.single()
|
||||
targetCompilation!!.compileKotlinTask.dependsOn(cbindgen)
|
||||
// tasks.getByName("cinteropNative$name").dependsOn(cbindgen)
|
||||
}
|
||||
targetCompilation!!
|
||||
|
||||
val compileRust = tasks.register("compileRust${compilationName.titlecase()}") {
|
||||
group = "mirai"
|
||||
inputs.files(nativeInteropDir.resolve("src"))
|
||||
outputs.file(rustLibDir.resolve("lib$crateName.dynlib"))
|
||||
dependsOn(targetCompilation!!.compileKotlinTask)
|
||||
dependsOn(bindgen)
|
||||
dependsOn(tasks.findByName("linkDebugSharedNative"))
|
||||
doLast {
|
||||
exec {
|
||||
workingDir(nativeInteropDir)
|
||||
commandLine(
|
||||
"cargo",
|
||||
"build",
|
||||
"--all"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.getByName("assemble").dependsOn(compileRust)
|
||||
}
|
||||
}
|
||||
|
||||
fun String.titlecase(): String {
|
||||
if (this.isEmpty()) return this
|
||||
val c = get(0)
|
||||
return replaceFirst(c, Character.toTitleCase(c))
|
||||
}
|
11
install.sh
Normal file
11
install.sh
Normal file
@ -0,0 +1,11 @@
|
||||
#
|
||||
# Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
#
|
||||
# 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
# Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
#
|
||||
# https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
#
|
||||
|
||||
cargo install --force cbindgen
|
||||
cargo install bindgen
|
8
mirai-core/src/nativeMainInterop/.gitignore
vendored
Normal file
8
mirai-core/src/nativeMainInterop/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/target
|
||||
Cargo.lock
|
||||
myrust.h
|
||||
|
||||
*.iml
|
||||
|
||||
src/bindings.rs
|
||||
/*.h
|
14
mirai-core/src/nativeMainInterop/Cargo.toml
Normal file
14
mirai-core/src/nativeMainInterop/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "mirai_core"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lib]
|
||||
name = "mirai_core"
|
||||
crate-type = ["cdylib"] # Creates dynamic lib
|
||||
# crate-type = ["staticlib"] # Creates static lib
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.53.1"
|
||||
cbindgen = "0.20.0"
|
32
mirai-core/src/nativeMainInterop/build.rs
Normal file
32
mirai-core/src/nativeMainInterop/build.rs
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
extern crate bindgen;
|
||||
extern crate cbindgen;
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use cbindgen::Config;
|
||||
use cbindgen::Language::C;
|
||||
|
||||
fn main() {
|
||||
// let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
|
||||
// cbindgen::Builder::new()
|
||||
// .with_crate(crate_dir)
|
||||
// .with_language(C)
|
||||
// .generate()
|
||||
// .expect("Unable to generate bindings")
|
||||
// .write_to_file("nativeInterop.h");
|
||||
|
||||
|
||||
println!("cargo:rustc-link-search=../../build/bin/native/debugShared");
|
||||
println!("cargo:rustc-link-lib=mirai_core");
|
||||
}
|
10
mirai-core/src/nativeMainInterop/cbindgen.toml
Normal file
10
mirai-core/src/nativeMainInterop/cbindgen.toml
Normal file
@ -0,0 +1,10 @@
|
||||
# This is a template cbindgen.toml file with all of the default values.
|
||||
# Some values are commented out because their absence is the real default.
|
||||
#
|
||||
# See https://github.com/eqrion/cbindgen/blob/master/docs.md#cbindgentoml
|
||||
# for detailed documentation of every option here.
|
||||
|
||||
|
||||
|
||||
language = "C"
|
||||
|
0
mirai-core/src/nativeMainInterop/interop.def
Normal file
0
mirai-core/src/nativeMainInterop/interop.def
Normal file
11
mirai-core/src/nativeMainInterop/src/lib.rs
Normal file
11
mirai-core/src/nativeMainInterop/src/lib.rs
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
/// cbindgen:ignore
|
||||
mod bindings;
|
Loading…
Reference in New Issue
Block a user