Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,17 @@ rustJni{
| Minimum version | `>=1.64.0` | Accepts any version greater than or equal to this |
| Wildcard version | `1.86.*`, `1.*.*` | Allows flexibility within minor and/or patch versions |

### How to define a custom path for rust?

By default, Rust is installed in the following directory:

- **macOS/Linux**: `~/.cargo/bin`
- **Windows**: `%USERPROFILE%\.cargo\bin`

However, you can specify a custom installation directory by setting it in your **`local.properties`** file. For example:

`cargo.dir=/Users/<user>/cargo_tmp/.cargo/bin`

### How can I take a look at some samples?

- [Java](./sample/java) - A java sample with 1 method
Expand Down
2 changes: 1 addition & 1 deletion gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repositories {
google()
}

version = "0.0.25"
version = "0.0.26"
group = "io.github.andrefigas.rustjni"

gradlePlugin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.github.andrefigas.rustjni
import io.github.andrefigas.rustjni.reflection.ReflectionJVM
import io.github.andrefigas.rustjni.reflection.ReflectionNative
import io.github.andrefigas.rustjni.utils.FileUtils
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
import java.io.ByteArrayOutputStream
Expand All @@ -27,7 +28,6 @@ class RustJNI : Plugin<Project> {

project.afterEvaluate {
val helper = Helper(project, extension)
helper.validateRustVersion()
helper.registerCompileTask()
helper.registerInitTask()
helper.configureAndroidSettings()
Expand Down Expand Up @@ -69,22 +69,27 @@ class RustJNI : Plugin<Project> {
executable: String,
arguments: List<String>,
dir: File = rustDir,
outputProcessor: ((String) -> Unit)? = null
outputProcessor: ((String) -> Unit)? = null,
extraEnv: Map<String, String> = emptyMap()
) {
val userHome = System.getProperty("user.home")
val isWindows = System.getProperty("os.name").lowercase().contains("win")
val execExt = if (isWindows) ".exe" else ""
val executablePath = "$userHome${File.separator}.cargo${File.separator}bin${File.separator}$executable$execExt"

val executablePath = "${getCargoDir()}$executable$execExt"

val executableFile = File(executablePath)
if (!executableFile.exists()) {
throw IllegalStateException("Executable not found at: $executablePath")
}

val fullCommand = listOf(executablePath) + arguments
val fullCommand = listOf(executableFile.absolutePath) + arguments

try {
println("Running $executable command: ${fullCommand.joinToString(" ")} in $dir")
if (extraEnv.isNotEmpty()) {
println("With environment overrides:")
extraEnv.forEach { (k, v) -> println(" $k = $v") }
}

val output = if (outputProcessor != null) ByteArrayOutputStream() else null

Expand All @@ -94,6 +99,7 @@ class RustJNI : Plugin<Project> {
isIgnoreExitValue = true
output?.let { standardOutput = it }
errorOutput = System.err
environment(extraEnv)
}

if (result.exitValue != 0) {
Expand Down Expand Up @@ -170,6 +176,66 @@ class RustJNI : Plugin<Project> {
}
}

private fun validateRustExecutable(file: File) {
if (!file.exists()) {
throw GradleException("Expected Rust executable not found: ${file.absolutePath}")
}

if (!file.canExecute()) {
throw GradleException("Rust executable is not executable: ${file.absolutePath}")
}

val process = try {
ProcessBuilder(file.absolutePath, "--version")
.redirectErrorStream(true)
.start()
} catch (e: Exception) {
throw GradleException("Failed to launch ${file.name} from path: ${file.absolutePath}", e)
}

val output = process.inputStream.bufferedReader().readText()
val exitCode = process.waitFor()

if (exitCode != 0) {
throw GradleException("${file.name} failed to execute with exit code $exitCode: $output")
}

}


/** Gets the cargo directory from `local.properties` or defaults to `$HOME/.cargo/bin/`.
*
* Throws an exception if the directory does not exist.
*/
private fun getCargoDir(): String {
val props = Properties()
project.file("${project.rootProject.projectDir}${File.separator}local.properties")
.inputStream().use { props.load(it) }

var cargoDir = props.getProperty("cargo.dir")

if (cargoDir.isNullOrEmpty()) {
val userHome = System.getProperty("user.home")
cargoDir = "$userHome${File.separator}.cargo${File.separator}bin"
}

if (!cargoDir.endsWith(File.separator)) {
cargoDir += File.separator
}

val cargoDirFile = File(cargoDir)
if (!cargoDirFile.exists() || !cargoDirFile.isDirectory) {
throw GradleException("Cargo directory does not exist: $cargoDir")
}

val executables = listOf("cargo", "rustc", "rustup")
for (exe in executables) {
validateRustExecutable(File(cargoDirFile, exe))
}

return cargoDir
}

private fun parseVersion(version: String): Triple<Int, Int, Int> {
val parts = version.split(".")
if (parts.size != 3) throw IllegalArgumentException("Version must be in format x.y.z")
Expand Down Expand Up @@ -246,6 +312,7 @@ class RustJNI : Plugin<Project> {
}

private fun compileRustCode() {
validateRustVersion()
validateArchitectures()
addRustTargets()
cleanBuildDirectory()
Expand Down
2 changes: 1 addition & 1 deletion sample/java/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import io.github.andrefigas.rustjni.reflection.Visibility
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
id("io.github.andrefigas.rustjni") version "0.0.25"
id("io.github.andrefigas.rustjni") version "0.0.26"
}

rustJni{
Expand Down
2 changes: 1 addition & 1 deletion sample/kotlin/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import io.github.andrefigas.rustjni.reflection.Visibility
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
id("io.github.andrefigas.rustjni") version "0.0.25"
id("io.github.andrefigas.rustjni") version "0.0.26"
}

rustJni{
Expand Down