-CFG_GCCISH_CFLAGS := -fno-strict-aliasing
+# Create variables HOST_<triple> containing the host part
+# of each target triple. For example, the triple i686-darwin-macos
+# would create a variable HOST_i686-darwin-macos with the value
+# i386.
+define DEF_HOST_VAR
+ HOST_$(1) = $(subst i686,i386,$(word 1,$(subst -, ,$(1))))
+endef
+$(foreach t,$(CFG_TARGET_TRIPLES),$(eval $(call DEF_HOST_VAR,$(t))))
+$(foreach t,$(CFG_TARGET_TRIPLES),$(info Host for $(t) is $(HOST_$(t))))
+
+CFG_GCCISH_FLAGS := -fno-strict-aliasing
CFG_GCCISH_LINK_FLAGS :=
# On Darwin, we need to run dsymutil so the debugging information ends
CFG_GCCISH_CFLAGS += -fPIC -march=i686 -I/usr/local/include
CFG_GCCISH_LINK_FLAGS += -shared -fPIC -lpthread -lrt
ifeq ($(CFG_CPUTYPE), x86_64)
- CFG_GCCISH_CFLAGS += -m32
- CFG_GCCISH_LINK_FLAGS += -m32
+ CFG_GCCISH_CFLAGS_i386 += -m32
+ CFG_GCCISH_LINK_FLAGS_i386 += -m32
+ CFG_GCCISH_CFLAGS_x86_64 += -m32
+ CFG_GCCISH_LINK_FLAGS_x86_64 += -m32
endif
CFG_UNIXY := 1
CFG_LDENV := LD_LIBRARY_PATH
# -znoexecstack is here because librt is for some reason being created
# with executable stack and Fedora (or SELinux) doesn't like that (#798)
CFG_GCCISH_POST_LIB_FLAGS := -Wl,-no-whole-archive -Wl,-znoexecstack
- ifeq ($(CFG_CPUTYPE), x86_64)
- CFG_GCCISH_CFLAGS += -m32
- CFG_GCCISH_LINK_FLAGS += -m32
- endif
+ CFG_GCCISH_CFLAGS_i386 = -m32
+ CFG_GCCISH_LINK_FLAGS_i386 = -m32
+ CFG_GCCISH_CFLAGS_x86_64 = -m64
+ CFG_GCCISH_LINK_FLAGS_x86_64 = -m64
CFG_UNIXY := 1
CFG_LDENV := LD_LIBRARY_PATH
CFG_DEF_SUFFIX := .linux.def
# approaches welcome!
#
# NB: Currently GCC's optimizer breaks rustrt (task-comm-1 hangs) on Darwin.
- CFG_GCC_CFLAGS += -m32
- CFG_CLANG_CFLAGS += -m32
- ifeq ($(CFG_CPUTYPE), x86_64)
- CFG_GCCISH_CFLAGS += -arch i386
- CFG_GCCISH_LINK_FLAGS += -arch i386
- endif
- CFG_GCCISH_LINK_FLAGS += -m32
+ CFG_GCCISH_CFLAGS_i386 := -m32 -arch i386
+ CFG_GCCISH_CFLAGS_x86_64 := -m64 -arch x86_64
+ CFG_GCCISH_LINK_FLAGS_i386 := -m32
+ CFG_GCCISH_LINK_FLAGS_x86_64 := -m64
CFG_DSYMUTIL := dsymutil
CFG_DEF_SUFFIX := .darwin.def
# Mac requires this flag to make rpath work
CXX=clang++
CFG_GCCISH_CFLAGS += -Wall -Werror -fno-rtti -g
CFG_GCCISH_LINK_FLAGS += -g
- CFG_COMPILE_C = $(CFG_GCCISH_CROSS)$(CXX) $(CFG_GCCISH_CFLAGS) \
- $(CFG_CLANG_CFLAGS) -c -o $(1) $(2)
CFG_DEPEND_C = $(CFG_GCCISH_CROSS)$(CXX) $(CFG_GCCISH_CFLAGS) -MT "$(1)" \
-MM $(2)
- CFG_LINK_C = $(CFG_GCCISH_CROSS)$(CXX) $(CFG_GCCISH_LINK_FLAGS) -o $(1) \
- $(CFG_GCCISH_DEF_FLAG)$(3) $(2) $(call CFG_INSTALL_NAME,$(4))
+
+ define CFG_MAKE_CC
+ CFG_COMPILE_C_$(1) = $$(CFG_GCCISH_CROSS)$$(CXX) \
+ $$(CFG_GCCISH_CFLAGS) $$(CFG_CLANG_CFLAGS) \
+ $$(CFG_GCCISH_CFLAGS_$$(HOST_$(1))) \
+ $$(CFG_CLANG_CFLAGS_$$(HOST_$(1))) \
+ -c -o $$(1) $$(2)
+ CFG_LINK_C_$(1) = $$(CFG_GCCISH_CROSS)$$(CXX) \
+ $$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
+ $$(CFG_GCCISH_LINK_FLAGS_$$(HOST_$(1))) \
+ $$(CFG_GCCISH_DEF_FLAG)$$(3) $$(2) \
+ $$(call CFG_INSTALL_NAME,$$(4))
+ endef
+
+ $(foreach target,$(CFG_TARGET_TRIPLES), \
+ $(eval $(call CFG_MAKE_CC,$(target))))
else
ifeq ($(CFG_C_COMPILER),gcc)
CC=gcc
CXX=g++
CFG_GCCISH_CFLAGS += -Wall -Werror -fno-rtti -g
CFG_GCCISH_LINK_FLAGS += -g
- CFG_COMPILE_C = $(CFG_GCCISH_CROSS)$(CXX) $(CFG_GCCISH_CFLAGS) \
- $(CFG_GCC_CFLAGS) -c -o $(1) $(2)
CFG_DEPEND_C = $(CFG_GCCISH_CROSS)$(CXX) $(CFG_GCCISH_CFLAGS) -MT "$(1)" \
-MM $(2)
- CFG_LINK_C = $(CFG_GCCISH_CROSS)$(CXX) $(CFG_GCCISH_LINK_FLAGS) -o $(1) \
- $(CFG_GCCISH_DEF_FLAG)$(3) $(2) $(call CFG_INSTALL_NAME,$(4))
+
+ define CFG_MAKE_CC
+ CFG_COMPILE_C_$(1) = $$(CFG_GCCISH_CROSS)$$(CXX) \
+ $$(CFG_GCCISH_CFLAGS) \
+ $$(CFG_GCCISH_CFLAGS_$$(HOST_$(1))) \
+ $$(CFG_GCC_CFLAGS) \
+ $$(CFG_GCC_CFLAGS_$$(HOST_$(1))) \
+ -c -o $$(1) $$(2)
+ CFG_LINK_C_$(1) = $$(CFG_GCCISH_CROSS)$$(CXX) \
+ $$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
+ $$(CFG_GCCISH_LINK_FLAGS_$$(HOST_$(1))) \
+ $$(CFG_GCCISH_DEF_FLAG)$$(3) $$(2) \
+ $$(call CFG_INSTALL_NAME,$$(4))
+ endef
+
+ $(foreach target,$(CFG_TARGET_TRIPLES), \
+ $(eval $(call CFG_MAKE_CC,$(target))))
else
CFG_ERR := $(error please try on a system with gcc or clang)
endif
endif
+
+# This is a procedure to define the targets for building
+# the runtime.
+#
+# Argument 1 is the target triple.
+#
+# This is not really the right place to explain this, but
+# for those of you who are not Makefile gurus, let me briefly
+# cover the $ expansion system in use here, because it
+# confused me for a while! The variable DEF_RUNTIME_TARGETS
+# will be defined once and then expanded with different
+# values substituted for $(1) each time it is called.
+# That resulting text is then eval'd.
+#
+# For most variables, you could use a single $ sign. The result
+# is that the substitution would occur when the CALL occurs,
+# I believe. The problem is that the automatic variables $< and $@
+# need to be expanded-per-rule. Therefore, for those variables at
+# least, you need $$< and $$@ in the variable text. This way, after
+# the CALL substitution occurs, you will have $< and $@. This text
+# will then be evaluated, and all will work as you like.
+#
+# Reader beware, this explanantion could be wrong, but it seems to
+# fit the experimental data (i.e., I was able to get the system
+# working under these assumptions).
+
+define DEF_RUNTIME_TARGETS
+
######################################################################
# Runtime (C++) library variables
######################################################################
-RUNTIME_CS := rt/sync/timer.cpp \
+RUNTIME_CS_$(1) := \
+ rt/sync/timer.cpp \
rt/sync/sync.cpp \
rt/sync/lock_and_signal.cpp \
rt/rust.cpp \
rt/test/rust_test_harness.cpp \
rt/test/rust_test_runtime.cpp \
rt/test/rust_test_util.cpp \
- rt/arch/i386/context.cpp
-
-RUNTIME_LL :=
+ rt/arch/$$(HOST_$(1))/context.cpp
-RUNTIME_S := rt/arch/i386/_context.S \
- rt/arch/i386/ccall.S \
- rt/arch/i386/morestack.S
+RUNTIME_S_$(1) := rt/arch/$$(HOST_$(1))/_context.S \
+ rt/arch/$$(HOST_$(1))/ccall.S \
+ rt/arch/$$(HOST_$(1))/morestack.S
-RUNTIME_HDR := rt/globals.h \
+RUNTIME_HDR_$(1) := rt/globals.h \
rt/rust.h \
rt/rust_abi.h \
rt/rust_cc.h \
rt/test/rust_test_harness.h \
rt/test/rust_test_runtime.h \
rt/test/rust_test_util.h \
- rt/arch/i386/context.h
+ rt/arch/$$(HOST_$(1))/context.h
-ifeq ($(CFG_WINDOWSY), 1)
- LIBUV_OSTYPE := win
- LIBUV_ARCH := ia32
- LIBUV_LIB := rt/libuv/Default/obj.target/src/rt/libuv/libuv.a
-else ifeq ($(CFG_OSTYPE), apple-darwin)
- LIBUV_OSTYPE := mac
- LIBUV_ARCH := ia32
- LIBUV_LIB := rt/libuv/Default/libuv.a
+ifeq ($$(HOST_$(1)), i386)
+ LIBUV_ARCH_$(1) := ia32
else
- LIBUV_OSTYPE := unix
- LIBUV_ARCH := ia32
- LIBUV_LIB := rt/libuv/Default/obj.target/src/rt/libuv/libuv.a
+ LIBUV_ARCH_$(1) := x86_64
endif
-RUNTIME_DEF := rt/rustrt$(CFG_DEF_SUFFIX)
-RUNTIME_INCS := -I $(S)src/rt/isaac -I $(S)src/rt/uthash \
- -I $(S)src/rt/arch/i386 \
- -I $(S)src/rt/libuv/include
-RUNTIME_OBJS := $(RUNTIME_CS:.cpp=.o) $(RUNTIME_LL:.ll=.o) $(RUNTIME_S:.S=.o)
-RUNTIME_LIBS := $(LIBUV_LIB)
-
-RT_COMPILE_C := $(call CFG_COMPILE_C, $(0), $(1) -I $(S)src/rt/arch/$(2))
-
-rt/%.o: rt/%.cpp $(MKFILES)
- @$(call E, compile: $@)
- $(Q)$(call CFG_COMPILE_C, $@, $(RUNTIME_INCS)) $<
-
-rt/%.o: rt/%.S $(MKFILES)
- @$(call E, compile: $@)
- $(Q)$(call CFG_COMPILE_C, $@, $(RUNTIME_INCS)) $<
-
-rt/%.o: rt/%.ll $(MKFILES)
- @$(call E, llc: $@)
- $(Q)$(LLC) -filetype=obj -relocation-model=pic -march=x86 -o $@ $<
+ifeq ($$(CFG_WINDOWSY), 1)
+ LIBUV_OSTYPE_$(1) := win
+ LIBUV_LIB_$(1) := rt/$(1)/libuv/Default/obj.target/src/rt/libuv/libuv.a
+else ifeq ($(CFG_OSTYPE), apple-darwin)
+ LIBUV_OSTYPE_$(1) := mac
+ LIBUV_LIB_$(1) := rt/$(1)/libuv/Default/libuv.a
+else
+ LIBUV_OSTYPE_$(1) := unix
+ LIBUV_LIB_$(1) := rt/$(1)/libuv/Default/obj.target/src/rt/libuv/libuv.a
+endif
-rt/$(CFG_RUNTIME): $(RUNTIME_OBJS) $(MKFILES) $(RUNTIME_HDR) $(RUNTIME_DEF) $(RUNTIME_LIBS)
- @$(call E, link: $@)
- $(Q)$(call CFG_LINK_C,$@, $(RUNTIME_OBJS) \
- $(CFG_GCCISH_POST_LIB_FLAGS) $(RUNTIME_LIBS) \
- $(CFG_LIBUV_LINK_FLAGS),$(RUNTIME_DEF),$(CFG_RUNTIME))
+RUNTIME_DEF_$(1) := rt/rustrt$$(CFG_DEF_SUFFIX)
+RUNTIME_INCS_$(1) := -I $$(S)src/rt/isaac -I $$(S)src/rt/uthash \
+ -I $$(S)src/rt/arch/$$(HOST_$(1)) \
+ -I $$(S)src/rt/libuv/include
+RUNTIME_OBJS_$(1) := $$(RUNTIME_CS_$(1):rt/%.cpp=rt/$(1)/%.o) \
+ $$(RUNTIME_S_$(1):rt/%.S=rt/$(1)/%.o)
+RUNTIME_LIBS_$(1) := $$(LIBUV_LIB_$(1))
+
+rt/$(1)/%.o: rt/%.cpp $$(MKFILES)
+ @$$(call E, compile: $$@)
+ $$(Q)$$(call CFG_COMPILE_C_$(1), $$@, $$(RUNTIME_INCS_$(1))) $$<
+
+rt/$(1)/%.o: rt/%.S $$(MKFILES)
+ @$$(call E, compile: $$@)
+ $$(Q)$$(call CFG_COMPILE_C_$(1), $$@, $$(RUNTIME_INCS_$(1))) $$<
+
+rt/$(1)/$(CFG_RUNTIME): $$(RUNTIME_OBJS_$(1)) $$(MKFILES) \
+ $$(RUNTIME_HDR_$(1)) \
+ $$(RUNTIME_DEF_$(1)) \
+ $$(RUNTIME_LIBS_$(1))
+ @$$(call E, link: $$@)
+ $$(Q)$$(call CFG_LINK_C_$(1),$$@, $$(RUNTIME_OBJS_$(1)) \
+ $$(CFG_GCCISH_POST_LIB_FLAGS) $$(RUNTIME_LIBS_$(1)) \
+ $$(CFG_LIBUV_LINK_FLAGS),$$(RUNTIME_DEF_$(1)),$$(CFG_RUNTIME))
# FIXME: For some reason libuv's makefiles can't figure out the correct definition
# of CC on the mingw I'm using, so we are explicitly using gcc. Also, we
# have to list environment variables first on windows... mysterious
-$(LIBUV_LIB): $(wildcard \
- $(S)src/rt/libuv/* \
- $(S)src/rt/libuv/*/* \
- $(S)src/rt/libuv/*/*/* \
- $(S)src/rt/libuv/*/*/*/*)
- $(Q)$(MAKE) -C $(S)mk/libuv/$(LIBUV_ARCH)/$(LIBUV_OSTYPE) \
- CFLAGS="-m32" LDFLAGS="-m32" \
- CC="$(CFG_GCCISH_CROSS)$(CC)" \
- CXX="$(CFG_GCCISH_CROSS)$(CXX)" \
- AR="$(CFG_GCCISH_CROSS)$(AR)" \
- builddir_name="$(CFG_BUILD_DIR)/rt/libuv" \
- V=$(VERBOSE) FLOCK= uv
+$$(LIBUV_LIB_$(1)): $$(wildcard \
+ $$(S)src/rt/libuv/* \
+ $$(S)src/rt/libuv/*/* \
+ $$(S)src/rt/libuv/*/*/* \
+ $$(S)src/rt/libuv/*/*/*/*)
+ $$(Q)$$(MAKE) -C $$(S)mk/libuv/$$(LIBUV_ARCH_$(1))/$$(LIBUV_OSTYPE_$(1)) \
+ CFLAGS="$$(TAR_CFLAGS)" LDFLAGS="-m32" \
+ CC="$$(CFG_GCCISH_CROSS)$$(CC)" \
+ CXX="$$(CFG_GCCISH_CROSS)$$(CXX)" \
+ AR="$$(CFG_GCCISH_CROSS)$$(AR)" \
+ builddir_name="$$(CFG_BUILD_DIR)/rt/$(1)/libuv" \
+ V=$$(VERBOSE) FLOCK= uv
# These could go in rt.mk or rustllvm.mk, they're needed for both.
-%.linux.def: %.def.in $(MKFILES)
- @$(call E, def: $@)
- $(Q)echo "{" > $@
- $(Q)sed 's/.$$/&;/' $< >> $@
- $(Q)echo "};" >> $@
+%.linux.def: %.def.in $$(MKFILES)
+ @$$(call E, def: $$@)
+ $$(Q)echo "{" > $$@
+ $$(Q)sed 's/.$$/&;/' $$< >> $$@
+ $$(Q)echo "};" >> $$@
-%.darwin.def: %.def.in $(MKFILES)
- @$(call E, def: $@)
- $(Q)sed 's/^./_&/' $< > $@
+%.darwin.def: %.def.in $$(MKFILES)
+ @$$(call E, def: $$@)
+ $$(Q)sed 's/^./_&/' $$< > $$@
ifdef CFG_WINDOWSY
-%.def: %.def.in $(MKFILES)
- @$(call E, def: $@)
- $(Q)echo LIBRARY $* > $@
- $(Q)echo EXPORTS >> $@
- $(Q)sed 's/^./ &/' $< >> $@
+%.def: %.def.in $$(MKFILES)
+ @$$(call E, def: $$@)
+ $$(Q)echo LIBRARY $$* > $$@
+ $$(Q)echo EXPORTS >> $$@
+ $$(Q)sed 's/^./ &/' $$< >> $$@
endif
+
+endef
+
+# Instantiate template for all stages
+$(foreach target,$(CFG_TARGET_TRIPLES), \
+ $(eval $(call DEF_RUNTIME_TARGETS,$(target))))