From 28117fee12e84aac5b95e371295b8498037fb7c2 Mon Sep 17 00:00:00 2001 From: Waylon Cude Date: Sun, 28 Feb 2016 22:44:04 -0800 Subject: [PATCH] Added rust support Rust relies on atomic builtins, which are not implemented in libgcc for ARM. One is implemented in rust, which is sufficient to get the current rust test to run. Issue #1899 --- repos/base/mk/generic.mk | 9 +++++- repos/base/mk/global.mk | 11 +++++++ repos/base/mk/lib.mk | 29 +++++++++++++++---- repos/base/mk/prg.mk | 16 +++++++++- repos/base/run/rust.run | 27 +++++++++++++++++ .../src/lib/rust-targets/spec/arm/target.json | 9 ++++++ .../lib/rust-targets/spec/riscv/target.json | 8 +++++ .../lib/rust-targets/spec/x86_32/target.json | 7 +++++ .../lib/rust-targets/spec/x86_64/target.json | 8 +++++ repos/base/src/test/rust/main.rs | 22 ++++++++++++++ repos/base/src/test/rust/printf.cc | 4 +++ repos/base/src/test/rust/target.mk | 4 +++ .../lib/import/import-libcore-rust.mk | 18 ++++++++++++ repos/libports/lib/mk/liballoc-rust.mk | 3 ++ repos/libports/lib/mk/liballoc_system-rust.mk | 4 +++ repos/libports/lib/mk/libcollections-rust.mk | 3 ++ repos/libports/lib/mk/libcore-rust.mk | 3 ++ repos/libports/lib/mk/liblibc-rust.mk | 4 +++ .../libports/lib/mk/librustc_unicode-rust.mk | 3 ++ repos/libports/lib/mk/rust.inc | 4 +++ repos/libports/ports/rust.hash | 1 + repos/libports/ports/rust.port | 8 +++++ 22 files changed, 198 insertions(+), 7 deletions(-) create mode 100644 repos/base/run/rust.run create mode 100644 repos/base/src/lib/rust-targets/spec/arm/target.json create mode 100644 repos/base/src/lib/rust-targets/spec/riscv/target.json create mode 100644 repos/base/src/lib/rust-targets/spec/x86_32/target.json create mode 100644 repos/base/src/lib/rust-targets/spec/x86_64/target.json create mode 100644 repos/base/src/test/rust/main.rs create mode 100644 repos/base/src/test/rust/printf.cc create mode 100644 repos/base/src/test/rust/target.mk create mode 100644 repos/libports/lib/import/import-libcore-rust.mk create mode 100644 repos/libports/lib/mk/liballoc-rust.mk create mode 100644 repos/libports/lib/mk/liballoc_system-rust.mk create mode 100644 repos/libports/lib/mk/libcollections-rust.mk create mode 100644 repos/libports/lib/mk/libcore-rust.mk create mode 100644 repos/libports/lib/mk/liblibc-rust.mk create mode 100644 repos/libports/lib/mk/librustc_unicode-rust.mk create mode 100644 repos/libports/lib/mk/rust.inc create mode 100644 repos/libports/ports/rust.hash create mode 100644 repos/libports/ports/rust.port diff --git a/repos/base/mk/generic.mk b/repos/base/mk/generic.mk index aa2a897cb..96a7c7713 100644 --- a/repos/base/mk/generic.mk +++ b/repos/base/mk/generic.mk @@ -7,7 +7,7 @@ # Collect object files and avoid duplicates (by using 'sort') # SRC_O += $(addprefix binary_,$(addsuffix .o,$(notdir $(SRC_BIN)))) -SRC = $(sort $(SRC_C) $(SRC_CC) $(SRC_ADA) $(SRC_S) $(SRC_O)) +SRC = $(sort $(SRC_C) $(SRC_CC) $(SRC_ADA) $(SRC_RS) $(SRC_S) $(SRC_O)) OBJECTS = $(addsuffix .o,$(basename $(SRC))) # @@ -71,6 +71,13 @@ endif $(MSG_COMP)$@ $(VERBOSE)gnatmake -q -c $(CC_ADA_OPT) $(INCLUDES) $< +# +# Compiling Rust sources +# +%.o: %.rs + $(MSG_COMP)$@ + $(VERBOSE)rustc $(CC_RUSTC_OPT) -o $@ $< + # # Assembler files that must be preprocessed are fed to the C compiler. # diff --git a/repos/base/mk/global.mk b/repos/base/mk/global.mk index 8ee576da0..9f9da6949 100644 --- a/repos/base/mk/global.mk +++ b/repos/base/mk/global.mk @@ -117,6 +117,16 @@ CC_CXX_OPT += $(CC_OPT) CC_C_OPT += $(CC_OPT) CC_ADA_OPT += $(CC_OLEVEL) $(CC_WARN) +# +# Use the correct linker +# +CC_RUSTC_OPT += -C linker=$(LD) + +# +# Include dependencies +# +CC_RUSTC_OPT += $(foreach lib,$(LIBS),-L$(LIB_CACHE_DIR)/$(lib)) + # # Enable C++11 by default # @@ -181,6 +191,7 @@ VERBOSE_DIR ?= --no-print-directory MSG_LINK = @$(ECHO) " LINK " MSG_COMP = @$(ECHO) " COMPILE " MSG_BUILD = @$(ECHO) " BUILD " +MSG_RENAME = @$(ECHO) " RENAME " MSG_MERGE = @$(ECHO) " MERGE " MSG_CONVERT = @$(ECHO) " CONVERT " MSG_CONFIG = @$(ECHO) " CONFIG " diff --git a/repos/base/mk/lib.mk b/repos/base/mk/lib.mk index 8520ce7f6..623b14d36 100644 --- a/repos/base/mk/lib.mk +++ b/repos/base/mk/lib.mk @@ -23,6 +23,15 @@ include $(BASE_DIR)/mk/base-libs.mk # all: +# +# Make a rlib or dylib instead of object file +# +ifndef SHARED_LIB + CC_RUSTC_OPT += --crate-type rlib +else + CC_RUSTC_OPT += --crate-type dylib +endif + # # Include common utility functions # @@ -66,13 +75,16 @@ include $(BASE_DIR)/mk/global.mk # # Name of .lib.a or .lib.so file to create # -ifndef SHARED_LIB -LIB_A := $(addsuffix .lib.a,$(LIB)) -LIB_FILENAME := $(LIB_A) -else +ifdef SHARED_LIB LIB_SO := $(addsuffix .lib.so,$(LIB)) INSTALL_SO := $(INSTALL_DIR)/$(LIB_SO) LIB_FILENAME := $(LIB_SO) +else ifdef SRC_RS +LIB_RLIB := $(addsuffix .rlib,$(LIB)) +LIB_FILENAME := $(LIB_RLIB) +else +LIB_A := $(addsuffix .lib.a,$(LIB)) +LIB_FILENAME := $(LIB_A) endif LIB_TAG := $(addsuffix .lib.tag,$(LIB)) @@ -118,7 +130,7 @@ all: $(LIB_TAG) # $(LIB_TAG) $(OBJECTS): $(HOST_TOOLS) -$(LIB_TAG): $(LIB_A) $(LIB_SO) $(INSTALL_SO) +$(LIB_TAG): $(LIB_A) $(LIB_SO) $(INSTALL_SO) $(LIB_RLIB) @touch $@ include $(BASE_DIR)/mk/generic.mk @@ -134,6 +146,13 @@ include $(BASE_DIR)/mk/generic.mk $(LIB_A): $(OBJECTS) $(MSG_MERGE)$(LIB_A) $(VERBOSE)$(AR) -rc $@ $(OBJECTS) +# +# Rename from object to rlib +# +$(LIB_RLIB): $(OBJECTS) + $(MSG_RENAME)$(LIB_RLIB) + $(VERBOSE)cp $(OBJECTS) $(LIB_RLIB) + # # Don't link base libraries against shared libraries except for ld.lib.so diff --git a/repos/base/mk/prg.mk b/repos/base/mk/prg.mk index 2df8f8dd4..45322530d 100644 --- a/repos/base/mk/prg.mk +++ b/repos/base/mk/prg.mk @@ -19,6 +19,11 @@ # all: +# +# Tell rust to make an object file instead of anything else +# +CC_RUSTC_OPT += --emit obj + # # Include common utility functions # @@ -148,6 +153,13 @@ LD_CMD += $(addprefix $(LD_SCRIPT_PREFIX), $(LD_SCRIPTS)) STATIC_LIBS := $(foreach l,$(FILTER_DEPS),$(LIB_CACHE_DIR)/$l/$l.lib.a) STATIC_LIBS := $(sort $(wildcard $(STATIC_LIBS))) +# +# --whole-archive does not work with rlibs +# +RUST_LIBS := $(foreach l,$(FILTER_DEPS),$(LIB_CACHE_DIR)/$l/$l.rlib) +RUST_LIBS := $(sort $(wildcard $(RUST_LIBS))) +SHORT_RUST_LIBS := $(subst $(LIB_CACHE_DIR),$$libs,$(RUST_LIBS)) + # # For hybrid Linux/Genode programs, prevent the linkage Genode's cxx and base # library because these functionalities are covered by the glibc or by @@ -181,7 +193,9 @@ $(LINK_ITEMS) $(TARGET): $(HOST_TOOLS) LD_CMD += -Wl,--whole-archive -Wl,--start-group LD_CMD += $(SHORT_LINK_ITEMS) LD_CMD += $(EXT_OBJECTS) -LD_CMD += -Wl,--end-group -Wl,--no-whole-archive +LD_CMD += -Wl,--no-whole-archive +LD_CMD += $(SHORT_RUST_LIBS) +LD_CMD += -Wl,--end-group # # Link libgcc to each program diff --git a/repos/base/run/rust.run b/repos/base/run/rust.run new file mode 100644 index 000000000..c58b12531 --- /dev/null +++ b/repos/base/run/rust.run @@ -0,0 +1,27 @@ +build "core init test/rust" + +create_boot_directory + +install_config { + + + + + + + + + + + + + +} + +build_boot_image "core init rust-test ld.lib.so libc.lib.so" + +append qemu_args "-nographic -m 64" + +run_genode_until { 42 } 10 + +puts "Test succeeded" diff --git a/repos/base/src/lib/rust-targets/spec/arm/target.json b/repos/base/src/lib/rust-targets/spec/arm/target.json new file mode 100644 index 000000000..513902106 --- /dev/null +++ b/repos/base/src/lib/rust-targets/spec/arm/target.json @@ -0,0 +1,9 @@ +{ + "llvm-target": "arm-pc-genode-elf", + "target-endian": "little", + "target-pointer-width": "32", + "arch": "arm", + "os": "genode", + "cpu": "generic", + "no_compiler_rt": true +} diff --git a/repos/base/src/lib/rust-targets/spec/riscv/target.json b/repos/base/src/lib/rust-targets/spec/riscv/target.json new file mode 100644 index 000000000..fa852b542 --- /dev/null +++ b/repos/base/src/lib/rust-targets/spec/riscv/target.json @@ -0,0 +1,8 @@ +{ + "pre-link-args": ["-mriscv=RV64IAMFD"], + "llvm-target": "riscv-pc-genode-elf", + "target-endian": "little", + "target-pointer-width": "64", + "arch": "riscv", + "os": "genode" +} diff --git a/repos/base/src/lib/rust-targets/spec/x86_32/target.json b/repos/base/src/lib/rust-targets/spec/x86_32/target.json new file mode 100644 index 000000000..4dfef36b7 --- /dev/null +++ b/repos/base/src/lib/rust-targets/spec/x86_32/target.json @@ -0,0 +1,7 @@ +{ + "llvm-target": "i686-pc-genode-elf", + "target-endian": "little", + "target-pointer-width": "32", + "arch": "x86", + "os": "genode" +} diff --git a/repos/base/src/lib/rust-targets/spec/x86_64/target.json b/repos/base/src/lib/rust-targets/spec/x86_64/target.json new file mode 100644 index 000000000..1220c400a --- /dev/null +++ b/repos/base/src/lib/rust-targets/spec/x86_64/target.json @@ -0,0 +1,8 @@ +{ + "pre-link-args": ["-m64"], + "llvm-target": "x86_64-pc-genode-elf", + "target-endian": "little", + "target-pointer-width": "64", + "arch": "x86_64", + "os": "genode" +} diff --git a/repos/base/src/test/rust/main.rs b/repos/base/src/test/rust/main.rs new file mode 100644 index 000000000..efe8a6ec6 --- /dev/null +++ b/repos/base/src/test/rust/main.rs @@ -0,0 +1,22 @@ +#![no_std] +#![feature(lang_items,collections)] +extern crate collections; +extern crate libc; +extern "C"{ + fn print_num(num: libc::c_int); +} +#[no_mangle] +pub fn main() -> libc::c_int{ + unsafe { + print_num(42); + } + 0 +} + +#[lang="panic_fmt"] +#[no_mangle] +pub fn panic_fmt() -> ! { loop{} } + +#[lang="eh_personality"] +#[no_mangle] +pub fn eh_personality() -> ! { loop{} } diff --git a/repos/base/src/test/rust/printf.cc b/repos/base/src/test/rust/printf.cc new file mode 100644 index 000000000..060c85fe5 --- /dev/null +++ b/repos/base/src/test/rust/printf.cc @@ -0,0 +1,4 @@ +#include +extern "C" void print_num(int num) { + Genode::printf("Number from rust: %d \n",num); +} diff --git a/repos/base/src/test/rust/target.mk b/repos/base/src/test/rust/target.mk new file mode 100644 index 000000000..224d9555c --- /dev/null +++ b/repos/base/src/test/rust/target.mk @@ -0,0 +1,4 @@ +TARGET = rust-test +SRC_RS = main.rs +SRC_CC = printf.cc +LIBS = libcore-rust libcollections-rust base libc librustc_unicode-rust liballoc-rust liblibc-rust liballoc_system-rust diff --git a/repos/libports/lib/import/import-libcore-rust.mk b/repos/libports/lib/import/import-libcore-rust.mk new file mode 100644 index 000000000..2c1ab35a9 --- /dev/null +++ b/repos/libports/lib/import/import-libcore-rust.mk @@ -0,0 +1,18 @@ +TARGET_DIR = src/lib/rust-targets/spec +ifeq ($(filter-out $(SPECS),x86),) + ifeq ($(filter-out $(SPECS),32bit),) + CC_RUSTC_OPT += --target $(call select_from_repositories,$(TARGET_DIR)/x86_32/target.json) + endif # 32bit + + ifeq ($(filter-out $(SPECS),64bit),) + CC_RUSTC_OPT += --target $(call select_from_repositories,$(TARGET_DIR)/x86_64/target.json) + endif # 64bit +endif # x86 + +ifeq ($(filter-out $(SPECS),arm),) + CC_RUSTC_OPT += --target $(call select_from_repositories,$(TARGET_DIR)/arm/target.json) +endif # ARM + +ifeq ($(filter-out $(SPECS),riscv),) + CC_RUSTC_OPT += --target $(call select_from_repositories,$(TARGET_DIR)/riscv/target.json) +endif # RISCV diff --git a/repos/libports/lib/mk/liballoc-rust.mk b/repos/libports/lib/mk/liballoc-rust.mk new file mode 100644 index 000000000..d35db1af4 --- /dev/null +++ b/repos/libports/lib/mk/liballoc-rust.mk @@ -0,0 +1,3 @@ +LIBS = libcore-rust liballoc_system-rust +RLIB = liballoc +include $(REP_DIR)/lib/mk/rust.inc diff --git a/repos/libports/lib/mk/liballoc_system-rust.mk b/repos/libports/lib/mk/liballoc_system-rust.mk new file mode 100644 index 000000000..0e7760360 --- /dev/null +++ b/repos/libports/lib/mk/liballoc_system-rust.mk @@ -0,0 +1,4 @@ +LIBS = libcore-rust liblibc-rust +CC_RUSTC_OPT += --allow unused_features +RLIB = liballoc_system +include $(REP_DIR)/lib/mk/rust.inc diff --git a/repos/libports/lib/mk/libcollections-rust.mk b/repos/libports/lib/mk/libcollections-rust.mk new file mode 100644 index 000000000..71dd5347f --- /dev/null +++ b/repos/libports/lib/mk/libcollections-rust.mk @@ -0,0 +1,3 @@ +LIBS = libcore-rust liballoc-rust librustc_unicode-rust +RLIB = libcollections +include $(REP_DIR)/lib/mk/rust.inc diff --git a/repos/libports/lib/mk/libcore-rust.mk b/repos/libports/lib/mk/libcore-rust.mk new file mode 100644 index 000000000..49114f989 --- /dev/null +++ b/repos/libports/lib/mk/libcore-rust.mk @@ -0,0 +1,3 @@ +RLIB=libcore +include $(REP_DIR)/lib/mk/rust.inc +include $(REP_DIR)/lib/import/import-libcore-rust.mk diff --git a/repos/libports/lib/mk/liblibc-rust.mk b/repos/libports/lib/mk/liblibc-rust.mk new file mode 100644 index 000000000..51900b0bc --- /dev/null +++ b/repos/libports/lib/mk/liblibc-rust.mk @@ -0,0 +1,4 @@ +LIBS = libcore-rust libc ldso-startup +RLIB = liblibc/src +CC_RUSTC_OPT += --cfg 'target_os = "netbsd"' +include $(REP_DIR)/lib/mk/rust.inc diff --git a/repos/libports/lib/mk/librustc_unicode-rust.mk b/repos/libports/lib/mk/librustc_unicode-rust.mk new file mode 100644 index 000000000..d04161d56 --- /dev/null +++ b/repos/libports/lib/mk/librustc_unicode-rust.mk @@ -0,0 +1,3 @@ +LIBS = libcore-rust +RLIB = librustc_unicode +include $(REP_DIR)/lib/mk/rust.inc diff --git a/repos/libports/lib/mk/rust.inc b/repos/libports/lib/mk/rust.inc new file mode 100644 index 000000000..744d5b8b5 --- /dev/null +++ b/repos/libports/lib/mk/rust.inc @@ -0,0 +1,4 @@ +SRC_RS = lib.rs +vpath % $(call select_from_ports,rust)/src/lib/rust/src/$(RLIB) + +# vi: set ft=make : diff --git a/repos/libports/ports/rust.hash b/repos/libports/ports/rust.hash new file mode 100644 index 000000000..90724a6fb --- /dev/null +++ b/repos/libports/ports/rust.hash @@ -0,0 +1 @@ +613098635ba8ed06c7f8723670e240982ad0f112 diff --git a/repos/libports/ports/rust.port b/repos/libports/ports/rust.port new file mode 100644 index 000000000..1d688b9dd --- /dev/null +++ b/repos/libports/ports/rust.port @@ -0,0 +1,8 @@ +LICENSE := MIT +VERSION := nightly +DATE := 2016-03-03 +DOWNLOADS := rust.archive + +URL(rust) := http://static.rust-lang.org/dist/$(DATE)/rustc-$(VERSION)-src.tar.gz +SHA(rust) := c75656f1238ce82e1cdede174d9cbc05f0b98ae2 +DIR(rust) := src/lib/rust