diff --git a/Makefile.in b/Makefile.in index ad96251ac26..1869476165b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -11,34 +11,183 @@ endif CFG_INFO := $(info cfg: building on $(CFG_OSTYPE) $(CFG_CPUTYPE)) -ifdef CFG_OCAMLC_OPT - $(info cfg: using ocaml native compiler) - OPT=.opt -else - $(info cfg: using ocaml bytecode compiler) +CFG_GCC_CFLAGS := +CFG_GCC_LINK_FLAGS := +CFG_BOOT_FLAGS := $(BOOT_FLAGS) +CFG_RUSTC_FLAGS := -nowarn + +# On Darwin, we need to run dsymutil so the debugging information ends +# up in the right place. On other platforms, it automatically gets +# embedded into the executable, so use a no-op command. +CFG_DSYMUTIL := true + +ifeq ($(CFG_OSTYPE), FreeBSD) + LIB := lib$(1).so + CFG_GCC_CFLAGS += -fPIC -march=i686 -I/usr/local/include + CFG_GCC_LINK_FLAGS += -shared -fPIC -lpthread -lrt + ifeq ($(CFG_CPUTYPE), x86_64) + CFG_GCC_CFLAGS += -m32 + CFG_GCC_LINK_FLAGS += -m32 + endif + CFG_UNIXY := 1 endif -ifdef PROFILE_BOOT - $(info cfg: building bootstrap compiler with profiling (forcing native)) - CFG_NATIVE_BOOT := 1 +ifeq ($(CFG_OSTYPE), Linux) + LIB := lib$(1).so + CFG_GCC_CFLAGS += -fPIC -march=i686 + CFG_GCC_LINK_FLAGS += -shared -fPIC -ldl -lpthread -lrt + ifeq ($(CFG_CPUTYPE), x86_64) + CFG_GCC_CFLAGS += -m32 + CFG_GCC_LINK_FLAGS += -m32 + endif + CFG_UNIXY := 1 +endif + +ifeq ($(CFG_OSTYPE), Darwin) + LIB := lib$(1).dylib + CFG_UNIXY := 1 + CFG_GCC_LINK_FLAGS += -dynamiclib -lpthread + # Darwin has a very blurry notion of "64 bit", and claims it's running + # "on an i386" when the whole userspace is 64-bit and the compiler + # emits 64-bit binaries by default. So we just force -m32 here. Smarter + # approaches welcome! + CFG_GCC_CFLAGS += -m32 + CFG_GCC_LINK_FLAGS += -m32 + CFG_DSYMUTIL := dsymutil +endif + +ifneq ($(findstring MINGW,$(CFG_OSTYPE)),) + CFG_WINDOWSY := 1 +endif + +ifdef CFG_WINDOWSY + CFG_INFO := $(info cfg: windows-y environment) + + CFG_EXE_SUFFIX := .exe + CFG_LIB_NAME=$(1).dll + CFG_RUN_PROGRAM=$(1) + + CFG_PATH_MUNGE := | sed -e 's/\\\(.\)/\/\1/g' + ifdef CFG_FLEXLINK + CFG_BOOT_NATIVE := 1 + endif + CFG_GCC_CFLAGS += -march=i686 + CFG_GCC_LINK_FLAGS += -shared -fPIC +endif + +ifdef CFG_UNIXY + CFG_INFO := $(info cfg: unix-y environment) + + CFG_EXE_SUFFIX := + CFG_RUN_PROGRAM = LD_LIBRARY_PATH=$(dir $(1)) $(CFG_VALGRIND) $(1) + + CFG_BOOT_NATIVE := 1 + + ifdef MINGW_CROSS + CFG_EXE_SUFFIX := .exe + CFG_LIB_NAME=$(1).dll + CFG_RUN_PROGRAM=$(1) + + CFG_INFO := $(info cfg: mingw-cross) + CFG_GCC_CROSS := i586-mingw32msvc- + CFG_BOOT_FLAGS += -t win32-x86-pe + ifdef CFG_VALGRIND + CFG_VALGRIND += wine + endif + CFG_GCC_CFLAGS := -march=i686 + CFG_GCC_LINK_FLAGS := -shared + ifeq ($(CFG_CPUTYPE), x86_64) + CFG_GCC_CFLAGS += -m32 + CFG_GCC_LINK_FLAGS += -m32 + endif + endif + ifdef CFG_VALGRIND + CFG_VALGRIND += --leak-check=full \ + --error-exitcode=1 \ + --quiet --vex-iropt-level=0 \ + --suppressions=etc/x86.supp + endif +endif + +CFG_RUNTIME :=$(call CFG_LIB_NAME,rustrt) +CFG_LLVMEXT :=$(call CFG_LIB_NAME,llvmext) +CFG_STDLIB :=$(call CFG_LIB_NAME,std) + +ifdef CFG_GCC + CFG_INFO := $(info cfg: using gcc) + CFG_GCC_CFLAGS += -Wall -Werror -fno-rtti -fno-exceptions -g + CFG_GCC_LINK_FLAGS += -g + CFG_COMPILE_C = $(CFG_GCC_CROSS)g++ $(CFG_GCC_CFLAGS) -c -o $(1) $(2) + CFG_LINK_C = $(CFG_GCC_CROSS)g++ $(CFG_GCC_LINK_FLAGS) -o $(1) + CFG_DEPEND_C = $(CFG_GCC_CROSS)g++ $(CFG_GCC_CFLAGS) -MT "$(1)" -MM $(2) +else + CFG_ERR := $(error please try on a system with gcc) +endif + +ifdef CFG_OCAMLC_OPT + $(info cfg: have ocaml native compiler) + OPT=.opt +else + $(info cfg: have only ocaml bytecode compiler) +endif + +ifdef BOOT_PROFILE + $(info cfg: forcing native bootstrap compiler (BOOT_PROFILE)) + CFG_BOOT_NATIVE := 1 CFG_OCAMLOPT_PROFILE_FLAGS := -p endif -ifdef DEBUG - $(info cfg: forcing bytecode bootstrap compiler) - CFG_NATIVE_BOOT := +ifdef BOOT_DEBUG + $(info cfg: forcing bytecode bootstrap compiler (DEBUG)) + CFG_BOOT_NATIVE := endif -ifdef CFG_NATIVE_BOOT +ifdef CFG_BOOT_NATIVE $(info cfg: building native bootstrap compiler) else $(info cfg: building bytecode bootstrap compiler) endif ifdef NO_VALGRIND - CFG_VALGRIND := + $(info cfg: disabling valgrind (NO_VALGRIND)) + CFG_VALGRIND := endif +###################################################################### +# Target-and-rule "utility variables" +###################################################################### + +ifdef VERBOSE + Q := + E = +else + Q := @ + E = echo $(1) +endif + +R := $(CFG_RUN_PROGRAM) +S := $(CFG_SRC_DIR) +X := $(CFG_EXE_SUFFIX) + +# Look in doc and src dirs. +VPATH := $(S)doc $(S)src + +# Compilers we build, we now know how to run. +BOOT := $(Q)OCAMLRUNPARAM="b1" boot/rustboot$(X) $(CFG_BOOT_FLAGS) +STAGE0 := $(Q)stage0/rustc$(X) $(CFG_RUSTC_FLAGS) +STAGE1 := $(Q)stage1/rustc$(X) $(CFG_RUSTC_FLAGS) +STAGE2 := $(Q)stage2/rustc$(X) $(CFG_RUSTC_FLAGS) + +# "Source" files we generate in builddir along the way. +GENERATED := boot/fe/lexer.ml boot/version.ml + +# Delete the built-in rules. +.SUFFIXES: +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% ###################################################################### # Bootstrap compiler variables @@ -66,72 +215,172 @@ BOOT_CMXS := $(BOOT_MLS:.ml=.cmx) BOOT_OBJS := $(BOOT_MLS:.ml=.o) BOOT_CMIS := $(BOOT_MLS:.ml=.cmi) -BOOT_ML_DEP_INCS := -I boot \ - -I $(S)boot/fe -I $(S)boot/me \ - -I $(S)boot/be -I $(S)boot/driver \ - -I $(S)boot/util +BS := $(S)/src/boot/ + +BOOT_ML_DEP_INCS := -I $(BS)/fe -I $(BS)/me \ + -I $(BS)/be -I $(BS)/driver \ + -I $(BS)/util -I boot + +BOOT_ML_INCS := -I boot/fe -I boot/me \ + -I boot/be -I boot/driver \ + -I boot/util -I boot -BOOT_ML_INCS := $(BOOT_ML_DEP_INCS) BOOT_ML_LIBS := unix.cma nums.cma bigarray.cma BOOT_ML_NATIVE_LIBS := unix.cmxa nums.cmxa bigarray.cmxa BOOT_OCAMLC_FLAGS := -g $(BOOT_ML_INCS) -w Ael -warn-error Ael - +BOOT_OCAMLOPT_FLAGS := -g $(BOOT_ML_INCS) -w Ael -warn-error Ael ###################################################################### -# Target-and-rule "utility variables" +# Runtime (C++) library variables ###################################################################### -ifdef VERBOSE - Q := - E = -else - Q := @ - E = echo $(1) -endif +RUNTIME_CS := rt/sync/timer.cpp \ + rt/sync/sync.cpp \ + rt/sync/lock_and_signal.cpp \ + rt/rust.cpp \ + rt/rust_builtin.cpp \ + rt/rust_run_program.cpp \ + rt/rust_crate.cpp \ + rt/rust_crate_cache.cpp \ + rt/rust_crate_reader.cpp \ + rt/rust_comm.cpp \ + rt/rust_dom.cpp \ + rt/rust_task.cpp \ + rt/rust_task_list.cpp \ + rt/rust_proxy.cpp \ + rt/rust_chan.cpp \ + rt/rust_port.cpp \ + rt/rust_upcall.cpp \ + rt/rust_log.cpp \ + rt/rust_message.cpp \ + rt/rust_timer.cpp \ + rt/circular_buffer.cpp \ + rt/isaac/randport.cpp \ + rt/rust_srv.cpp \ + rt/rust_kernel.cpp \ + rt/memory_region.cpp \ + rt/test/rust_test_harness.cpp \ + rt/test/rust_test_runtime.cpp \ + rt/test/rust_test_util.cpp -S := $(CFG_SRC_DIR) -X := $(CFG_EXE_SUFFIX) +RUNTIME_HDR := rt/globals.h \ + rt/rust.h \ + rt/rust_dwarf.h \ + rt/rust_internal.h \ + rt/rust_util.h \ + rt/rust_chan.h \ + rt/rust_port.h \ + rt/rust_dom.h \ + rt/rust_task.h \ + rt/rust_task_list.h \ + rt/rust_proxy.h \ + rt/rust_log.h \ + rt/rust_message.h \ + rt/circular_buffer.h \ + rt/util/array_list.h \ + rt/util/indexed_list.h \ + rt/util/synchronized_indexed_list.h \ + rt/util/hash_map.h \ + rt/sync/sync.h \ + rt/sync/timer.h \ + rt/sync/lock_free_queue.h \ + rt/rust_srv.h \ + rt/rust_kernel.h \ + rt/memory_region.h \ + rt/memory.h \ + rt/test/rust_test_harness.h \ + rt/test/rust_test_runtime.h \ + rt/test/rust_test_util.h -# Look in doc and src dirs. -VPATH := $(CFG_SRC_DIR)/doc $(CFG_SRC_DIR)/src - -# Delete the built-in rules. -.SUFFIXES: -%:: %,v -%:: RCS/%,v -%:: RCS/% -%:: s.% -%:: SCCS/s.% +RUNTIME_INCS := -I $(S)src/rt/isaac -I $(S)src/rt/uthash +RUNTIME_OBJS := $(RUNTIME_CS:.cpp=.o) ###################################################################### -# Targets and rules +# rustc LLVM-extensions (C++) library variables ###################################################################### -all: boot/rustboot$(X) +LLVMEXT_CS := $(addprefix llvmext/, \ + MachOObjectFile.cpp Object.cpp RustWrapper.cpp) -ifdef CFG_NATIVE_BOOT +LLVMEXT_HDR := llvmext/include/llvm-c/Object.h + +LLVMEXT_INCS := -iquote $(CFG_LLVM_INCDIR) -iquote llvmext/include +LLVMEXT_OBJS := $(LLVMEXT_CS:.cpp=.o) +LLVMEXT_LIBS := $(CFG_LLVM_LDFLAGS) $(CFG_LLVM_LIBS) + +###################################################################### +# Standard library variables +###################################################################### + +STDLIB_CRATE := lib/std.rc +STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/lib/,*.rc *.rs */*.rs)) + +###################################################################### +# rustc crate variables +###################################################################### + +COMPILER_CRATE := comp/rustc.rc +COMPILER_INPUTS := $(wildcard $(addprefix $(S)/src/comp/, \ + rustc.rc *.rs */*.rs)) + +###################################################################### +# Single-target rules +###################################################################### + +all: boot/rustboot$(X) rt/$(CFG_RUNTIME) llvmext/$(CFG_LLVMEXT) + +rt/$(CFG_RUNTIME): $(RUNTIME_OBJS) $(MKFILES) $(RUNTIME_HDR) + @$(call E, link: $@) + $(Q)$(call CFG_LINK_C, $@) $(RUNTIME_OBJS) + +llvmext/$(CFG_LLVMEXT): $(LLVMEXT_OBJS) $(MKFILES) $(LLVMEXT_HDR) + @$(call E, link: $@) + $(Q)$(call CFG_LINK_C, $@ $(LLVMEXT_OBJS) \ + $(CFG_LLVM_LIBS) $(CFG_LLVM_LDFLAGS)) + +ifdef CFG_BOOT_NATIVE boot/rustboot$(X): $(BOOT_CMXS) $(MKFILES) - @$(call E, compile: $@) - $(Q)ocamlopt$(OPT) -o $@ $(BOOT_OCAMLOPT_FLAGS) $(ML_NATIVE_LIBS) \ + @$(call E, link: $@) + $(Q)ocamlopt$(OPT) -o $@ $(BOOT_OCAMLOPT_FLAGS) $(BOOT_ML_NATIVE_LIBS) \ $(BOOT_CMXS) else boot/rustboot$(X): $(BOOT_CMOS) $(MKFILES) - @$(call E, compile: $@) + @$(call E, link: $@) $(Q)ocamlc$(OPT) -o $@ $(BOOT_OCAMLC_FLAGS) $(BOOT_ML_LIBS) $(BOOT_CMOS) endif - boot/version.ml: $(MKFILES) @$(call E, git: $@) $(Q)git log -1 \ --pretty=format:'let version = "prerelease (%h %ci)";;' >$@ || exit 1 + +###################################################################### +# Pattern rules +###################################################################### + +rt/%.o: rt/%.cpp $(MKFILES) + @$(call E, compile: $@) + $(Q)$(call CFG_COMPILE_C, $@, $(RUNTIME_INCS)) $< + +llvmext/%.o: llvmext/%.cpp $(MKFILES) + @$(call E, compile: $@) + $(Q)$(call CFG_COMPILE_C, $@, $(CFG_LLVM_CXXFLAGS) \ + $(SUPPORT_INCS)) $< + %.cmo: %.ml $(MKFILES) @$(call E, compile: $@) $(Q)ocamlc$(OPT) -c -o $@ $(BOOT_OCAMLC_FLAGS) $< %.cmo: %.cmi $(MKFILES) +%.cmx %.o: %.ml $(MKFILES) + @$(call E, compile: $@) + $(Q)ocamlopt$(OPT) -c -o $@ $(BOOT_OCAMLOPT_FLAGS) $< + +%.ml: %.mll $(MKFILES) + @$(call E, lex-gen: $@) + $(Q)ocamllex$(OPT) -q -o $@ $< ###################################################################### diff --git a/configure b/configure index 0e584f35eca..1672375e678 100755 --- a/configure +++ b/configure @@ -3,41 +3,40 @@ CFG_SRC_DIR=${0%${0##*/}} CFG_BUILD_DIR=$PWD -echo "configure: recreating config.mk" -echo '' >config.mk +msg() { + echo "configure: $1" +} -echo "configure: making directories" -for i in \ - doc \ - boot/fe boot/me boot/be boot/driver boot/util \ - rt/isaac rt/bigint rt/sync rt/test -do - mkdir -p -v $i -done +err() { + echo "configure: error: $1" + exit 1 +} + +make_dir() { + if [ ! -d $1 ] + then + msg "mkdir -p $1" + mkdir -p $1 + fi +} + +copy() { + msg "cp $1 $1" + cp $1 $2 +} make_test_subdirs() { for t in run-pass run-fail compile-fail do - mkdir -p -v $1/test/$t + make_dir $1/test/$t done } -make_test_subdirs boot - -for i in 0 1 2 -do - mkdir -p -v stage$i - make_test_subdirs stage$i -done - -echo "configure: copying Makefile" -cp -v ${CFG_SRC_DIR}Makefile.in ./Makefile - putvar() { local T eval T=\$$1 - printf "%-20s := %s\n" $1 $T - printf "%-20s := %s\n" $1 $T >>config.mk + printf "%-20s := %s\n" $1 "$T" + printf "%-20s := %s\n" $1 "$T" >>config.mk } probe() { @@ -53,7 +52,39 @@ probe() { putvar $V } -echo "configure: inspecting environment" +probe_need() { + local V=$1 + local P=$2 + probe $1 $2 + eval VV=\$$V + if [ -z "$VV" ] + then + err "required program '$P' not found" + fi +} + + +msg "recreating config.mk" +echo '' >config.mk + +msg "making directories" +for i in \ + doc \ + boot/fe boot/me boot/be boot/driver boot/util \ + rt/isaac rt/bigint rt/sync rt/test +do + make_dir $i +done + +make_test_subdirs boot + +for i in 0 1 2 +do + make_dir stage$i + make_test_subdirs stage$i +done + +msg "inspecting environment" CFG_OSTYPE=$(uname -s) CFG_CPUTYPE=$(uname -m) @@ -63,13 +94,40 @@ putvar CFG_BUILD_DIR putvar CFG_OSTYPE putvar CFG_CPUTYPE -echo "configure: looking for programs" +msg "looking for programs" +probe_need CFG_GCC gcc +probe_need CFG_LLVM_CONFIG llvm-config +probe_need CFG_OCAMLC ocamlc +probe_need CFG_PERL perl +probe_need CFG_SED sed + probe CFG_VALGRIND valgrind -probe CFG_OCAMLC ocamlc -probe CFG_OCAMLC_OPT ocamlc.opt probe CFG_OCAMLOPT ocamlopt +probe CFG_OCAMLC_OPT ocamlc.opt probe CFG_OCAMLOPT_OPT ocamlopt.opt probe CFG_FLEXLINK flexlink -probe CFG_LLVM_CONFIG llvm-config + +CFG_LLVM_VERSION=$(llvm-config --version) +case $CFG_LLVM_VERSION in + (3.0svn | 3.0) + msg "found ok version of LLVM: $CFG_LLVM_VERSION" + ;; + (*) + err "bad LLVM version: $CFG_LLVM_VERSION, need >=3.0svn" + ;; +esac +CFG_LLVM_INCDIR=$(llvm-config --includedir) +CFG_LLVM_BINDIR=$(llvm-config --bindir) +CFG_LLVM_CXXFLAGS=$(llvm-config --cxxflags) +CFG_LLVM_LDFLAGS=$(llvm-config --ldflags) +CFG_LLVM_LIBS=$(llvm-config --libs) + +putvar CFG_LLVM_INCDIR +putvar CFG_LLVM_BINDIR +putvar CFG_LLVM_CXXFLAGS +putvar CFG_LLVM_LDFLAGS +putvar CFG_LLVM_LIBS + +copy ${CFG_SRC_DIR}Makefile.in ./Makefile echo "configure: complete"