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