Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial Rust support #5740

Closed
wants to merge 7 commits into from
Closed
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
6 changes: 5 additions & 1 deletion Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ ifeq (,$(RIOTNOLINK))
ifeq ($(BUILDOSXNATIVE),1)
$(AD)$(if $(CPPMIX),$(CXX),$(LINK)) $(UNDEF) -o $(ELFFILE) $$(find $(BASELIBS) -size +8c) $(LINKFLAGS) $(LINKFLAGPREFIX)-no_pie
else
$(AD)$(if $(CPPMIX),$(CXX),$(LINK)) $(UNDEF) -o $(ELFFILE) $(LINKFLAGPREFIX)--start-group $(BASELIBS) -lm $(LINKFLAGPREFIX)--end-group $(LINKFLAGPREFIX)-Map=$(BINDIR)/$(APPLICATION).map $(LINKFLAGPREFIX)--cref $(LINKFLAGS)
$(AD)$(if $(CPPMIX),$(CXX),$(LINK)) $(UNDEF) -o $(ELFFILE) $(LINKFLAGPREFIX)--start-group $(BASELIBS) -lm $$(test -d $(BINDIR)/_extra_libs && find $(BINDIR)/_extra_libs -name '*.a') $(LINKFLAGPREFIX)--end-group $(LINKFLAGPREFIX)-Map=$(BINDIR)/$(APPLICATION).map $(LINKFLAGPREFIX)--cref $(LINKFLAGS)
endif
$(AD)$(SIZE) $(ELFFILE)
$(AD)$(OBJCOPY) $(OFLAGS) $(ELFFILE) $(HEXFILE)
Expand Down Expand Up @@ -521,3 +521,7 @@ endif
CFLAGS := $(patsubst -D%,,$(CFLAGS))
CFLAGS := $(patsubst -U%,,$(CFLAGS))
CFLAGS += -include '$(RIOTBUILD_CONFIG_HEADER_C)'

ifeq (1,$(CARGO_BUILD))
include $(RIOTBASE)/Makefile.rust
endif
28 changes: 28 additions & 0 deletions Makefile.rust
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# RIOT rust support makefile

# make RIOT's linker hook path known to rustc
export RUST_TARGET_PATH ?= $(RIOTBASE)/dist/rust/targets

# (unfortunately with this set, Cargo somehow fails. Thus we need to keep
# Cargo's build directory in ./target)
#export CARGO_TARGET_DIR ?= $(BINDIR)/_cargo

# the rust riot crate depends on fmt
USEMODULE += fmt

ifneq (,$(filter $(CPU_ARCH), cortex-m0plus cortex-m4f))
RUST_TARGET=$(CPU_ARCH)
else ifeq ($(CPU_ARCH),native)
$(error Makefile.rust: RIOT rust on native is currently broken.)
RUST_TARGET=i586-unknown-linux-gnu
endif

ifeq (, $(RUST_TARGET))
$(error Makefile.rust: cannot determine rust target triple!)
endif

all: xargo

xargo:
@mkdir -p $(BINDIR)/_extra_libs
@PATH=$${PATH}:$(RIOTBASE)/dist/rust xargo build --target $(RUST_TARGET) ${CARGO_FLAGS}
3 changes: 3 additions & 0 deletions cpu/Makefile.include.cortexm_common
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ include $(RIOTCPU)/cortexm_common/Makefile.include
USEMODULE += newlib_nano
export USE_NANO_SPECS = 1

# all Cortex-M are supported by RIOT's Rust integration
FEATURES_PROVIDED += rust_support

# Avoid overriding the default rule:
all:

Expand Down
21 changes: 21 additions & 0 deletions dist/rust/riot-rust-linker-hook
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Iff (sic, please argue for it) bash is really needed, at least invoke it like #!/usr/bin/env bash.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see below.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least you can be nice to non-linux people and change to #!/usr/bin/env bash as requested ;-)


[ -z "$BINDIR" ] && {
echo "$0: BINDIR not defined!" 1&>2
exit 1
}

_EXTRA_LIBS=${BINDIR}/_extra_libs
mkdir -p ${_EXTRA_LIBS}

while true; do
[ -z "$1" ] && exit 0
[ -f "$1" ] && {
if [[ "$1" == *.o ]]; then
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line breaks on dash (and thus probably on posix shells).
Any other nice portable way of comparing the suffix?

Copy link
Contributor

@Kijewski Kijewski Aug 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Untested:

case "${1}" in
    *.o)
        echo Ends with .o
        ;;
    foo*)
        echo Starts with foo
        ;;
    *)
        echo Neither ...
        ;;
esac

C.f. http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html (ctrl+f Case Conditional Construct)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kaspar030 any reason why are not using single []?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to match a pattern, that's why I'm using the bashism.

-----Original Message-----
From: Martine Lenders [email protected]
To: RIOT-OS/RIOT [email protected]
Cc: Kaspar Schleiser [email protected], Mention [email protected]
Sent: Fr., 02 Sep. 2016 11:59
Subject: Re: [RIOT-OS/RIOT] initial Rust support (#5740)

@@ -0,0 +1,21 @@
+#!/bin/bash
+
+[ -z "$BINDIR" ] && {

  • echo "$0: BINDIR not defined!" 1&>2
  • exit 1
    +}

+_EXTRA_LIBS=${BINDIR}/_extra_libs
+mkdir -p ${_EXTRA_LIBS}
+
+while true; do

  • [ -z "$1" ] && exit 0
  • [ -f "$1" ] && {
  •    if [[ "$1" == *.o ]]; then
    

@kaspar030 any reason why are not using single []?

You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
https://github.com/RIOT-OS/RIOT/pull/5740/files/bb0eedf0f0506f01cd968d64cec35b7478b18944#r77322526

${AR} r ${_EXTRA_LIBS}/_objects.a $1
elif [[ "$1" == *.rlib ]]; then
cp $1 ${_EXTRA_LIBS}/$(basename $1).a
fi
}
shift
done
14 changes: 14 additions & 0 deletions dist/rust/targets/cortex-m0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"arch": "arm",
"cpu": "cortex-m0",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"executables": true,
"linker": "riot-rust-linker-hook",
"llvm-target": "thumbv6m-none-eabi",
"no-compiler-rt": true,
"os": "none",
"pre-link-args": [],
"relocation-model": "static",
"target-endian": "little",
"target-pointer-width": "32"
}
14 changes: 14 additions & 0 deletions dist/rust/targets/cortex-m0plus.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"arch": "arm",
"cpu": "cortex-m0plus",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"executables": true,
"linker": "riot-rust-linker-hook",
"llvm-target": "thumbv6m-none-eabi",
"no-compiler-rt": true,
"os": "none",
"pre-link-args": [ ],
"relocation-model": "static",
"target-endian": "little",
"target-pointer-width": "32"
}
14 changes: 14 additions & 0 deletions dist/rust/targets/cortex-m1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"arch": "arm",
"cpu": "cortex-m1",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"executables": true,
"linker": "riot-rust-linker-hook",
"llvm-target": "thumbv6m-none-eabi",
"no-compiler-rt": true,
"os": "none",
"pre-link-args": [],
"relocation-model": "static",
"target-endian": "little",
"target-pointer-width": "32"
}
14 changes: 14 additions & 0 deletions dist/rust/targets/cortex-m3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"arch": "arm",
"cpu": "cortex-m3",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"executables": true,
"linker": "riot-rust-linker-hook",
"llvm-target": "thumbv7m-none-eabi",
"no-compiler-rt": true,
"os": "none",
"pre-link-args": [],
"relocation-model": "static",
"target-endian": "little",
"target-pointer-width": "32"
}
15 changes: 15 additions & 0 deletions dist/rust/targets/cortex-m4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"arch": "arm",
"cpu": "cortex-m4",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"executables": true,
"features": "+soft-float",
"linker": "riot-rust-linker-hook",
"llvm-target": "thumbv7em-none-eabi",
"no-compiler-rt": true,
"os": "none",
"pre-link-args": [],
"relocation-model": "static",
"target-endian": "little",
"target-pointer-width": "32"
}
14 changes: 14 additions & 0 deletions dist/rust/targets/cortex-m4f.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"arch": "arm",
"cpu": "cortex-m4",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"executables": true,
"linker": "riot-rust-linker-hook",
"llvm-target": "thumbv7em-none-eabi",
"no-compiler-rt": true,
"os": "none",
"pre-link-args": [],
"relocation-model": "static",
"target-endian": "little",
"target-pointer-width": "32"
}
15 changes: 15 additions & 0 deletions dist/rust/targets/cortex-m7.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"arch": "arm",
"cpu": "cortex-m7",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"executables": true,
"features": "+soft-float",
"linker": "riot-rust-linker-hook",
"llvm-target": "thumbv7em-none-eabi",
"no-compiler-rt": true,
"os": "none",
"pre-link-args": [],
"relocation-model": "static",
"target-endian": "little",
"target-pointer-width": "32"
}
15 changes: 15 additions & 0 deletions dist/rust/targets/cortex-m7f-sp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"arch": "arm",
"cpu": "cortex-m7",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"executables": true,
"features": "+fp-only-sp",
"linker": "riot-rust-linker-hook",
"llvm-target": "thumbv7em-none-eabi",
"no-compiler-rt": true,
"os": "none",
"pre-link-args": [],
"relocation-model": "static",
"target-endian": "little",
"target-pointer-width": "32"
}
14 changes: 14 additions & 0 deletions dist/rust/targets/cortex-m7f.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"arch": "arm",
"cpu": "cortex-m7",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"executables": true,
"linker": "riot-rust-linker-hook",
"llvm-target": "thumbv7em-none-eabi",
"no-compiler-rt": true,
"os": "none",
"pre-link-args": [],
"relocation-model": "static",
"target-endian": "little",
"target-pointer-width": "32"
}
12 changes: 12 additions & 0 deletions examples/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "app"
version = "0.1.0"
authors = ["Kaspar Schleiser <[email protected]>"]

[dependencies]
riot = "0.1.1"

[profile.release]
panic = "abort"
lto = true
opt-level = "s"
23 changes: 23 additions & 0 deletions examples/rust/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# name of your application
APPLICATION = rust

# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..

# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1

#
FEATURES_REQUIRED += rust_support

# If no BOARD is found in the environment, use this default:
BOARD ?= samr21-xpro

# use this to enable rust support.
# the current directory will be built using xargo.
CARGO_BUILD=1

# set extra flags if needed
#CARGO_FLAGS += --release

include $(RIOTBASE)/Makefile.include
41 changes: 41 additions & 0 deletions examples/rust/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Introduction

"Rust is a systems programming language that runs blazingly fast, prevents
segfaults, and guarantees thread safety."

This example shows how to write a RIOT application using Rust.

# Status

As Rust's libstd is too fat for our little MCUs, it is currently only possible
to write Rust applications using ```#![no_std]```.
There's a crate on crate.io trying to map RIOT's API to rust, but that is in
very early stages.

# Prerequisites

You'll need a Rust nightly toolchain and xargo.

This should get you started:

# curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain=nightly
# . ~/.cargo/env
# cargo install xargo

# Trying the example

As always,

# BOARD=samr21-xpro make clean all flash term

is all you need.

# Internals

RIOT's make system intercepts cargo's linking step and just copies the objects
and archives cargo tries to link into RIOT's build dir, then just links
everything together.

# Known issues

- currently this works only for Cortex-M platforms
20 changes: 20 additions & 0 deletions examples/rust/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#![feature(lang_items)]
#![no_main]
#![no_std]

mod lang_items {
#[lang = "panic_fmt"]
extern fn panic_fmt() {}

#[lang = "eh_personality"]
fn eh_personality() {}
}

// user code starts here

extern crate riot;

#[no_mangle]
pub fn main() {
riot::fmt::print("Hello from RUST!\n");
}