Skip to content

Commit

Permalink
Add Makefile for Rust, cargo and cargo-rumpbake
Browse files Browse the repository at this point in the history
  • Loading branch information
gandro committed Sep 26, 2015
1 parent fc98244 commit b0a7e26
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 0 deletions.
103 changes: 103 additions & 0 deletions rust/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
include ../Makefile.inc
RUST_GIT=https://github.com/rust-lang/rust.git
RUST_VER=c9c79084

CARGO_GIT=https://github.com/rust-lang/cargo.git
CARGO_VER=0.5.0

CARGO_RUMPBAKE_GIT=https://github.com/gandro/cargo-rumpbake.git
CARGO_RUMPAKE_VER=0.5.0

ifneq (x86_64-rumprun-netbsd,$(RUMPRUN_TOOLCHAIN_TUPLE))
$(error Rust currently only supports x86_64-rumprun-netbsd)
endif

RUST_DESTDIR ?= $(abspath build/destdir)
CARGO_HOME := $(RUST_DESTDIR)/cargo

all: rust cargo cargo-rumpbake

######################################################################
# rust - The Rust compiler and standard library
######################################################################

.PHONY: rust
rust: $(RUST_DESTDIR)/bin/rustc rustenv.sh

$(RUST_DESTDIR)/bin/rustc: build/rust/config.stamp
mkdir -p $(RUST_DESTDIR)
(cd build/rust; $(MAKE) && $(MAKE) install)

RUST_CONF_OPTS += \
--target=$(RUMPRUN_TOOLCHAIN_TUPLE) \
--prefix=$(RUST_DESTDIR) \
--enable-debug

build/rust/config.stamp: build/rust/configure
(cd build/rust; ./configure $(RUST_CONF_OPTS))

build/rust/configure:
mkdir -p build
(cd build && \
git clone $(RUST_GIT) && \
git checkout $(RUST_VER))

.PHONY: rustenv.sh
rustenv.sh: $(RUST_DESTDIR)/bin/rustc
echo 'export PATH=$(RUST_DESTDIR)/bin:$${PATH}' > rustenv.sh
echo 'export LD_LIBRARY_PATH="$(RUST_DESTDIR)/lib:$${LD_LIBRARY_PATH}"' >> rustenv.sh
echo 'export DYLD_LIBRARY_PATH="$(RUST_DESTDIR)/lib:$${DYLD_LIBRARY_PATH}"' >> rustenv.sh

######################################################################
# cargo - The Rust package manager and build tool
######################################################################

.PHONY: cargo
cargo: $(RUST_DESTDIR)/bin/cargo

$(RUST_DESTDIR)/bin/cargo: build/cargo/config.stamp
mkdir -p $(RUST_DESTDIR)
(cd build/cargo; \
export CARGO_HOME=$(CARGO_HOME) && \
$(MAKE) && \
$(MAKE) install && \
echo 'export CARGO_HOME=$(CARGO_HOME)' >> rustenv.sh)

CARGO_CONF_OPTS += \
--local-rust-root=$(RUST_DESTDIR) \
--prefix=$(RUST_DESTDIR)

build/cargo/config.stamp: build/cargo/configure
(cd build/cargo; \
git submodule update --init && \
./configure $(CARGO_CONF_OPTS))

build/cargo/configure: rust
(cd build && git clone --branch $(CARGO_VER) $(CARGO_GIT))

######################################################################
# cargo-rumpbake - Cargo subcommand for invoking rumpbake
######################################################################

.PHONY: cargo-rumpbake
cargo-rumpbake: $(RUST_DESTDIR)/bin/cargo-rumpbake

$(RUST_DESTDIR)/bin/cargo-rumpbake: build/cargo-rumpbake/Cargo.toml
(cd build/cargo-rumpbake && \
sh -c '. ../../rustenv.sh ; cargo build --release' && \
cp target/release/cargo-rumpbake "$@")

build/cargo-rumpbake/Cargo.toml: cargo
mkdir -p build
(cd build && \
git clone --branch $(CARGO_RUMPBAKE_VER) $(CARGO_RUMPBAKE_GIT))

.PHONY: clean
clean:
-$(MAKE) -C build/rust clean
-$(MAKE) -C build/cargo clean
rm -f rustenv.sh

.PHONY: cleandir
cleandir: clean
rm -rf build
85 changes: 85 additions & 0 deletions rust/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
Overview
========

This document explains how to build a Rust cross-compiler and the cargo package
manager for rumprun. The Rust compiler version is a 1.5.0-dev snapshot, cargo
and cargo-rumpbake are version 0.5.0.

This package also fetches and builds a copy of
[cargo-rumpbake](https://github.com/gandro/cargo-rumpbake), a small wrapper
around `cargo build` and `rumpbake` which simplifies building and baking when
using `cargo` as a build tool.

Instructions
============

Running `make` will build a Rust cross-compiler for Rumprun, including the
standard library. The cargo package manager and the cargo-rumpbake subcommand
are also included by default. To build Rust without cargo, run `make rust`.

Make sure the `app-tools` folder of your Rumprun build is in `$PATH`.

cd rumprun-packages/rust
make -j4

Rust has the following dependencies:

* `g++` 4.7 or `clang++` 3.x
* `python` 2.6 or later (but not 3.x)
* GNU `make` 3.81 or later
* `curl`
* `git`

You will also need a decent Internet connection, at least 1.5 GB of RAM and
around five GB of disk space. Be aware, compiling Rust can easily take two
hours or more.

The toolchain will be installed in `build/destdir`. In order to use it, you
will need to set `LD_LIBRARY_PATH`. The following command sets the appropriate
environment variables to invoke `rustc` and `cargo` directly:

. ./rustenv.sh

> **Tip**: If you are using [multirust](https://github.com/brson/multirust),
> you can configure a custom toolchain instead of using the script.
> `multirust update rumprun --link-local $(readlink -f build/destdir/)`
Advanced users can also build Rust with `--enable-rpath` instead of setting
`LD_LIBRARY_PATH`. However, this might cause issues with cargo build scripts.

Examples
========

To cross-compile for Rumprun, always make sure you have `app-tools` in your
path, because `rustc` will invoke `x86_64-rumprun-netbsd-{gcc,ar}`.

When compiling manually with `rustc` or `cargo build`, make sure to compile
for the Rumprun target with `--target=x86_64-rumprun-netbsd`. For example:

cd examples/hello
rustc --target=x86_64-rumprun-netbsd hello.rs
rumpbake hw_virtio hello.img hello
rumprun qemu -i hello.img

### cargo rumpbake

When building with cargo, you can use `cargo rumpbake`, a tool which invokes
rumpbake automatically. To build the example TCP/IP server, proceed as follows:

cd examples/hello-tcp
cargo rumpbake hw_virtio

This will build and bake a `hello-tcp.img` unikernel image. To run it, make sure
you configure the network correctly. For example on Linux:

sudo ip tuntap add tap0 mode tap
sudo ip addr add 10.0.23.2/24 dev tap0
sudo ip link set dev tap0 up
rumprun qemu \
-I if,vioif,'-net tap,script=no,ifname=tap0' \
-W if,inet,static,10.0.23.1/24 \
-i hello-tcp.img

You can connect to the server with telnet:

telnet 10.0.23.1 9023
4 changes: 4 additions & 0 deletions rust/examples/hello-tcp/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "hello-tcp"
version = "0.1.0"
authors = ["Sebastian Wicki <gandro@gmx.net>"]
25 changes: 25 additions & 0 deletions rust/examples/hello-tcp/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use std::io::{BufReader, BufRead, Write, Result};
use std::net::{TcpListener, TcpStream};
use std::thread;

fn handle(stream: Result<TcpStream>) -> Result<()> {
let mut stream = try!(stream);
try!(stream.write_all(b"Hello, this is rumprun. Who are you?\r\n"));

let mut name = String::new();
try!(BufReader::new(&mut stream).read_line(&mut name));

write!(&mut stream, "Nice to meet you, {}!\r\n", name.trim_right())
}

fn main() {
let listener = TcpListener::bind("0.0.0.0:9023").unwrap();
println!("listening on port 9023 started, ready to accept");
for stream in listener.incoming() {
thread::spawn(|| {
if let Err(err) = handle(stream) {
println!("an error occured: {}", err);
}
});
}
}
6 changes: 6 additions & 0 deletions rust/examples/hello/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
hello: hello.rs
rustc --target=x86_64-rumprun-netbsd $<

.PHONY: clean
clean:
rm -f hello
3 changes: 3 additions & 0 deletions rust/examples/hello/hello.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, rumprun!");
}

0 comments on commit b0a7e26

Please sign in to comment.