SakulFlee / Rust-Multi-Platform-Project-Template

Other
0 stars 0 forks source link

Rust Multi-Platform: Base Project Template

Multiplatform Build

This repository is a template. It's main purpose is to make it easier to get started with Rust for multiple platforms.

This project is supported by the following platforms:

To use this template simply fork it (button in top right corner) into your own namespace. If you need some more advanced setup check out the forking guide. We also include a checklist for what to do after forking.

Licenses

This project is dual licensed in Rust's fashion:

For your own project you can chose whichever fits you better. For templates/examples we recommend to also dual-licensing.

Project layout

Folder Description
./ Workspace root; Cargo.toml contains all project folders (internal crates)
platform/ Platform projects root. Contains every platform this demonstration is supported on incl. instructions on how to build and use them.
platform/android/ Contains the Android platform project and instructions on how to build this project for Android and run it.
platform/ios/ Contains the iOS platform project and instructions on how to build this project for iOS and run it.
platform/linux/ Contains the Linux platform project and instructions on how to build this project for Linux and run it.
platform/macos/ Contains the macOS platform project and instructions on how to build this project for macOS and run it.
platform/windows/ Contains the Windows platform project and instructions on how to build this project for Windows and run it.
platform/webassembly/ Contains the WebAssembly platform project and instructions on how to build this project for Websites and run it.
shared/ Contains the shared code between all projects.

To break this down: The shared/ folder contains our cross/multi-platform code. 99.9% of what we do in this project will happen there.

Each of the projects inside platform/ are representing a platform specific project. In most cases, like for Windows, Linux and macOS, there is nothing else to do but call our shared code and compile a binary. However, on certain platforms, like Android and iOS, we have to use some special commands and tools to get an e.g. .APK (Android) or .APP (iOS) file. Furthermore, on those systems resources/assets may need to be specially loaded and their Cargo.toml will be much more extensive. Simply said: For those special platforms we will use some cargo extensions which will automatically generate a native project in the background. Values from Cargo.toml will be used to generate those.

Please check the README.md inside each platform to see how each platform is build, run and what you will need to do so.

Targets & Architectures

This project is aiming to work across all platforms and targets. All Tier 1 targets are tested in CI's of this repository. Additionally, some Tier 2 targets are tested.

However, this should work on all targets. If you find an issue please report it.

Rust's Tier Policies Rust's Platform Support & Targets

Building & Running

Building & Running all projects at once only works if your host platform has all required packages installed. Unfortunately, do to Apple's restrictions, macOS and iOS platforms can only be build on macOS. This also means that macOS is the only host platform that can build all platforms at once.

However, we can build and run individual parts (packages) matching our host platform and we can use a combination of cross-compilation, Docker and/or Virtual Machines (VM) to build everything on one host platform.

Host (top) vs. Target (left) compatibility matrix:

Host: Windows Host: Linux Host: macOS
Target: Windows ✅: Visual Studio 🔀: MinGW 🔀: MinGW
Target: Linux ⚠️: WSL or VM or Docker ✅: GCC or Clang 🔀: Docker or VM
Target: macOS ⚠️: Docker-OSX (inside WSL with Docker) or OSX-KVM (inside WSL or VM) or macOS-VirtualBox (inside/with WSL and/or MSYS2/MinGW) ⚠️: Docker-OSX or OSX-KVM or macOS-VirtualBox ✅: XCode
Target: Android 🔀: Android Studio or Android CommandLine-Tools 🔀: Android Studio or Android CommandLine-Tools 🔀: Android Studio or Android CommandLine-Tools
Target: iOS ⚠️: Docker-OSX (inside WSL with Docker) or OSX-KVM (inside WSL or VM) or macOS-VirtualBox (inside/with WSL and/or MSYS2/MinGW) ⚠️: Docker-OSX or OSX-KVM or macOS-VirtualBox ✅: XCode
Target: WebAssembly ✅: Wasm-Pack ✅: Wasm-Pack ✅: Wasm-Pack

✅ = Natively supported. 🔀 = Cross-Compilation & Toolchain needed. ⚠️ = Possible, but takes some more effort and/or special setups or VM to work.

Building can be done via:

cargo build --package <package>

Or run it directly (running will build the project beforehand!):

cargo run --package <package>

If there are tests present for the project, we can test them:

cargo test --package <package>

Or check if the project configuration is valid & build-able:

cargo check --package <package>

Note: Adding --release to either of the commands will build a release version, instead of a debug version.

Do note that some platforms (like iOS and Android) require special tools and cargo extensions to properly build. While we could do that step manually, it is much more convenient and easier to use this way. Check the README.md of a platform to learn more about requirements and tools.

Since we can't build for all target platforms on a single host platform (without major modification; see above), the --package <package> part is very important. Simply replace <package> with the package name inside the Cargo.toml to build it. Names commonly will be platform_<platform> for platform-specific packages (e.g. platform_windows or platform_ios) or shared for the shared code. In case multiple shared projects are present, check their Cargo.toml for their name (commonly: folder name).

However, since we share most of our code on all target platforms, we only really need to validate the code working on one platform (ideally your host platform for best performance or main target platform). Only rarely should we need platform-specific code which, if it exists, needs to be tested. Though, a continuous integration pipeline (CI) can take care of that for you mostly! Check Continuous Integration for more.

Continuous Integration

Multiplatform Build

This project utilizes the GitHub Actions CI (= Continuous Integration) to showcase how to build for all platforms. For most platforms we just need a runner on the target platform (Windows, Linux or macOS) and install Rust. This can be simply done by following rustup.rs (check the other install options for automatically installing inside an CI). Something like:

curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable --profile full -y

should work for most platforms.

Note that we may need more tools installed depending on the CI provider and platform. Check the host <-> target matrix at Building & Running

Additionally, often we have to source the profile changes. Something like:

source $HOME/.cargo/env

Coverage

A combination of grcov and codecov.io is used to provide code-to-test coverage.
Please note that it is impossible to reach 100% coverage on some platforms as e.g. bindgen-code (i.e. dynamically generated code / macros) is NOT covered by grcov and certain platform specific tools (like cargo-apk) generate additional code that also is NOT included in the coverage.

Test-to-Code coverage status: codecov

Below are several charts showing/highlighting the distribution of all platforms.

Sunburst

Sunburst

Grid

Grid

Icicle

Icicle

Contributing & Getting Help

We welcome any help we get and try to answer questions as good as possible! Generally speaking, please open an issue here on GitHub or contact me directly. No matter the problem or question.

In case you've got an idea/request for an example/template, please do open an issue here on GitHub.

Want to add your own example/template project to the organization and use our CI's? Please open an issue here on GitHub.