A Gradle Plugin to build Rust projects using Gradle as the Build Environment instead of natively using Cargo. Gradle is a powerful build tool and utilizing it for Rust projects brings massive benefits as it reduces the complexity especially when it comes to projects working with multiple programming languages. Such an example is an Android app that compiles Rust code to JNI binaries.
This plugin aims to make it seamless to run Rust projects with Gradle while maintaining a familiar environment to Rust developers.
(Note: This is not a fork of rust-gradle-plugin. This was made and designed from scratch.)
Note
Due to the complexity of Cargo, this plugin should be considered 'beta' until version 1.0.0. There are still many features missing and hasn't been thoroughly tested yet. In the future, I'd like to port large OSS Rust projects into Gradle using my plugin as a final compatibility test. Checkout my Rust project utilizing this plugin for more details KeccakRust.
This project follows the Semantic Versioning 2.0 when updating the version number. As it stands, the project is still under development and the API might change between MINOR versions(that is the y in x.y.z).
| Plugin Task | Gradle Task | Cargo Equivalent | Status | Since | Remarks |
|---|---|---|---|---|---|
CargoBuild |
gradle build |
cargo build |
Full | 0.1.0 | Based on Cargo Docs* |
CargoClean |
gradle clean |
cargo clean |
Full | 0.4.0 | Based on Cargo Docs* |
CargoBench |
gradle bench |
cargo bench |
Full | 0.1.0 | Based on Cargo Docs* |
CargoTest |
gradle test |
cargo test |
Full | 0.1.0 | Based on Cargo Docs* |
CargoPublish |
gradle publish |
cargo publish |
Full | 0.1.0 | Based on Cargo Docs* |
CargoManifestGenerate |
gradle generateCargoManifest |
N/A | Semi | 0.2.0 | Not all fields** |
CargoDoc |
gradle rustdoc |
cargo doc |
WIP | N/A | Will be implemented soon. |
CargoReport |
gradle report |
cargo report |
TBD | N/A | Not prioritized. |
CargoFix |
gradle fix |
cargo fix |
TBD | N/A | Not prioritized. |
* Based on Cargo Docs.
** Based on Cargo Manifest Docs. The implemented features
are limited to the whole package section(except for resolver field), the whole dependency tables(except for target
because of its complexity), and limited support for lib section.
| Status | Definition |
|---|---|
| Full | Fully supported all command options. |
| Semi | Limited support that might not allow command options. |
| WIP | It is being implemented at the moment. |
| TBD | Planned to be done in the future. |
| No Plan | Avoided implementing due to design or logic reasons. |
As of version 0.5.7, Neo Rust Gradle Plugin can build, test, benchmark, publish(?), and run most Rust projects without requiring a Cargo.toml file. Additionally, users can use local Gradle modules as crate dependencies
Key capabilities:
- Full support for basic Cargo commands (build, test, bench, publish(?)).
- Gradle-style dependency management for Rust crates.
- Custom Cargo.toml manifest generation.
- Crate features support
- Run built binaries directly from Gradle
- Build only the library or the binary you want
- Idiomatic crate dependency declaration
- Latest Gradle 9.2.1 support
- Gradle Parallel Build support (allow tasks to run in different threads at the same time)
- Gradle Configuration Cache support (faster task run)
- Gradle Incremental Build support (only runs build when source files are updated, including dependency source files)
- Sub-module support (Declare Gradle projects as crate dependency)
- Task wiring for projects and sub-projects
We're actively working on expanding support for more complex Rust project structures and additional Cargo features. If you need a feature now, consider contributing or submitting an issue!
project-root/
├── build.gradle.kts # Gradle build file where you configure the plugin
├── settings.gradle.kts # Gradle settings file
└── src/
└── main/
└── rust/
└── main.rs # Your main Rust file (location configurable)
build.gradle.kts
plugins {
id("asia.hombre.neorust") version "0.5.7"
}import asia.hombre.neorust.task.CargoBench
import asia.hombre.neorust.task.CargoBuild
import asia.hombre.neorust.task.CargoPublish
import asia.hombre.neorust.task.CargoTest
plugins {
id("asia.hombre.neorust") version "0.5.7"
}
dependencies {
crate("jni:0.21.1") {
path.set("../jni-rs")
}
//If jni-rs is a Gradle neo-rust-gradle-plugin project
crate(project(":jni-rs")) {
//You can configure it further here.
}
crate("tokio-quiche:0.12.0") {
git = "https://github.com/cloudflare/quiche.git"
rev = "862ab1af92accf15613ad5d2a9bb62660fe8cd82" //Specify the commit (optional)
}
//Or just keep it like this if you don't need to configure it further
crate(project(":jni-rs"))
//devCrate("name:version")
//buildCrate("name:version")
}
//Rust Configuration (Global-level)
rust {
target.set("x86-unknown-linux-gnu")
//This replaces the Cargo.toml and generates it in the ./build/ folder.
manifest {
packaging {
name.set("neorust") //This is automatically configured from the Gradle project name
authors.add("Ron Lauren Hombre <[email protected]>")
edition.set("2024")
}
lib {
crateType.add("cdylib")
}
binaries {
register("rusty") //Uses the default setting which is RELEASE
register("rusty") { //Uses the DEV setting and makes a buildRustyDev and a runRustyDev task
buildProfile = BuildProfile.DEV
}
}
}
features {
feature("your-feature")
feature("your-feature-2", listOf("value1", "value2"))
}
benchmarking {
//Benchmarking Configuration (Top-level)
packageSelect.set("packageb")
}
building {
//Building Configuration (Top-level)
packageSelect.set("packagea")
release.set(true)
target.set("x86_64-unknown-linux-gnu")
}
publishing {
//Publishing Configuration (Top-level)
token.set("TOKEN")
}
testing {
//Testing Configuration (Top-level)
packageSelect.set("packageb")
}
}
tasks.getByName<CargoBench>("bench") { //Becomes benchRust if conflicting a task name.
//Benchmarking Configuration (Task-level)
target.set("armeabi-unknown-linux-gnu")
noRun.set(true)
}
tasks.getByName<CargoBuild>("build") { //Becomes buildRust if conflicting a task name.
//Building Configuration (Task-level)
target.set("armeabi-unknown-linux-gnu")
workspace.set(true)
}
tasks.getByName<CargoPublish>("publish") { //Becomes publishRust if conflicting a task name.
//Publishing Configuration (Task-level)
dryRun.set(true)
target.set("armeabi-unknown-linux-gnu")
token.set("TOKEN")
}
tasks.getByName<CargoTest>("test") { //Becomes testRust if conflicting a task name.
//Testing Configuration (Task-level)
target.set("armeabi-unknown-linux-gnu")
testThreads.set(2)
}- Global-level Configurations are automatically assigned to Top-level and then Task-level Configurations.
- Top-level Configurations override Global-level Configurations and are automatically assigned to Task-level Configurations.
- Task-level Configurations override both Global-level and Top-level Configurations above it.
Neo Rust Gradle Plugin was designed this way to allow fine-level control over the command options where developers need it.
- Cargo (and its dependencies)
- Gradle
- JDK 17.0+ (8 if you're simply using the plugin)
These haven't been concretely determined. Please try it out and tell me if it works or not!
- Fork the Repository.
- Write your code in that forked repository. (Make sure it follows the structure of the source code.)
- Test and make sure it works.
- Create an issue detailing the feature added or problem you fixed.
- Create a pull request mentioning the issue number.
- Wait for a maintainer to accept or request additional changes.
- Voila!
Hire me at Linkedin if you want exclusive development on this project
Copyright 2025 Ron Lauren Hombre (and the neo-rust-gradle-plugin contributors)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
and included as LICENSE.txt in this Project.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.