Skip to main content
Version: 0.2

Common development practices

Development environment

There are only one option to code both in Kotlin and Rust in a single IDE: IntelliJ IDEA Ultimate, which needs a paid subscription. Fleet was another option, but JetBrains announced that they are dropping the KMP support in Fleet.

Therefore, most users may use different IDEs for Kotlin and Rust when developing with this project. For Kotlin, you can use Android Studio or IntelliJ IDEA, and for Rust, you can use rust-analyzer with Visual Studio Code or RustRover. In normal cases, Kotlin handles the part interacting with users such as UI while Rust handles the core business logic, so using two IDEs won't harm the developer experience that much.

Separate the Rust part for shorter build time and separation of concerns

Since building Rust takes much more time than compiling Kotlin, try separating the Kotlin part that uses Rust directly as a core library. You can build and publish the core library using the maven-publish plugin and the other Kotlin part can download it from a Maven repository.

To learn about how to consume the published Rust library, please refer to Publishing JAR artifacts containing the Rust dynamic libraries. If you are managing your project using multi-project builds, please refer to Use the Rust plugin to configure multi-project builds properly.

Watch out for excessive disk usage

The more platforms you target, the larger the build result will be. Ensure your CI has enough space to build your project. Gradle caches files from the build in ~/.gradle/caches. If you encounter much more No space left on device errors after using this project, try removing ~/.gradle/caches. Since Gradle still tries to find cached files in ~/.gradle/caches after you remove it, remove all .gradle and build directories in your project as well. On macOS & Linux:

find . -name .gradle | xargs rm -rf
find . -name "build" | grep -v '^./target' | xargs -r rm -rf

In PowerShell on Windows:

Get-ChildItem . -Attributes Directory -Recurse |
Where-Object { $_.Name -eq ".gradle" } |
ForEach-Object { Remove-Item -Recurse -Force $_ }
Get-ChildItem . -Attributes Directory -Recurse |
Where-Object { $_.Name -eq "build" } |
Where-Object { -not $_.FullName.Contains("\target\") } |
ForEach-Object { Remove-Item -Recurse -Force $_ }

When you build iOS apps, Xcode generates files in /private/var/folders/zz, which are removed automatically after every reboot. Try restart your Mac if you still have the disk space issue after removing the Gradle caches.

Fix the Rust version you use for better reproducibility

In your Cargo.toml file, you can specify the minimum supported Rust version (MSRV) for your package using the rust-version field in the [package] section. For example:

[package]
rust-version = "1.82"

While the rust-version field defines the required MSRV to compile your crate, it does not enforce the use of that specific version. You (or CI systems) can still use newer versions of Rust to build the package. This can lead to situations where your code is compiled with a Rust version that hasn't been explicitly tested, resulting in unexpected linter warnings that varies depending on the CI pipeline's environment.

You can set a specific Rust version for your entire system using rustup, but this can be problematic if you have other Rust projects on your system that rely on different Rust versions.

> rustup target add 1.81
> rustup default 1.81
> rustc --version --verbose
rustc 1.81.0 (eeb90cda1 2024-09-04)
binary: rustc
commit-hash: eeb90cda1969383f56a2637cbd3037bdf598841c
commit-date: 2024-09-04
host: aarch64-apple-darwin
release: 1.81.0
LLVM version: 18.1.7

The most environment-agnostic and project-specific way to fix the Rust version is by creating a rust-toolchain.toml file in the root directory of your project. When rustup detects a rust-toolchain.toml file in the current directory or any parent directory, it automatically uses the toolchain specified in that file for that project, overriding the global default. For more details about rustup overrides, please refer to the official documentation.

[toolchain]
channel = "1.82" # A specific version, "stable", "nighlty", etc.

You can also set the toolchain directory via the toolchainDirectory property in the rust {} block, so consider using this if you are using a custom toolchain installed in a non-standard directory.