# Copyright 2012 The Rust Project Developers. See the COPYRIGHT # file at the top-level directory of this distribution and at # http://rust-lang.org/COPYRIGHT. # # Licensed under the Apache License, Version 2.0 or the MIT license # , at your # option. This file may not be copied, modified, or distributed # except according to those terms. # An explanation of how the build is structured: # # There are multiple build stages (0-3) needed to verify that the # compiler is properly self-hosting. Each stage is divided between # 'host' artifacts and 'target' artifacts, where the stageN host # compiler builds artifacts for 1 or more stageN target architectures. # Once the stageN target compiler has been built for the host # architecture it is promoted (copied) to a stageN+1 host artifact. # # The stage3 host compiler is a compiler that successfully builds # itself and should (in theory) be bitwise identical to the stage2 # host compiler. The process is bootstrapped using a stage0 host # compiler downloaded from a previous snapshot. # # At no time should stageN artifacts be interacting with artifacts # from other stages. For consistency, we use the 'promotion' logic # for all artifacts, even those that don't make sense on non-host # architectures. # # The directory layout for a stage is intended to match the layout # of the installed compiler, and looks like the following: # # stageN - this is the system root, corresponding to, e.g. /usr # bin - binaries compiled for the host # lib - libraries used by the host compiler # rustlib - rustc's own place to organize libraries # $(target) - target-specific artifacts # bin - binaries for target architectures # lib - libraries for target architectures # # A note about host libraries: # # The only libraries that get promoted to stageN/lib are those needed # by rustc. In general, rust programs, even those compiled for the # host architecture will use libraries from the target # directories. This gives rust some freedom to experiment with how # libraries are managed and versioned without polluting the common # areas of the filesystem. # # General rust binaries may stil live in the host bin directory; they # will just link against the libraries in the target lib directory. # # Admittedly this is a little convoluted. STAGES = 0 1 2 3 ###################################################################### # Residual auto-configuration ###################################################################### # Recursive wildcard function # http://blog.jgc.org/2011/07/gnu-make-recursive-wildcard-function.html rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) \ $(filter $(subst *,%,$2),$d)) include config.mk # We track all of the object files we might build so that we can find # and include all of the .d files in one fell swoop. ALL_OBJ_FILES := MKFILE_DEPS := config.stamp $(call rwildcard,$(CFG_SRC_DIR)mk/,*) NON_BUILD_HOST = $(filter-out $(CFG_BUILD),$(CFG_HOST)) NON_BUILD_TARGET = $(filter-out $(CFG_BUILD),$(CFG_TARGET)) ifneq ($(MAKE_RESTARTS),) CFG_INFO := $(info cfg: make restarts: $(MAKE_RESTARTS)) endif CFG_INFO := $(info cfg: build triple $(CFG_BUILD)) CFG_INFO := $(info cfg: host triples $(CFG_HOST)) CFG_INFO := $(info cfg: target triples $(CFG_TARGET)) ifneq ($(wildcard $(NON_BUILD_HOST)),) CFG_INFO := $(info cfg: non-build host triples $(NON_BUILD_HOST)) endif ifneq ($(wildcard $(NON_BUILD_TARGET)),) CFG_INFO := $(info cfg: non-build target triples $(NON_BUILD_TARGET)) endif CFG_RUSTC_FLAGS := $(RUSTFLAGS) CFG_GCCISH_CFLAGS := CFG_GCCISH_LINK_FLAGS := ifdef CFG_DISABLE_OPTIMIZE $(info cfg: disabling rustc optimization (CFG_DISABLE_OPTIMIZE)) CFG_RUSTC_FLAGS += else # The rtopt cfg turns off runtime sanity checks CFG_RUSTC_FLAGS += -O --cfg rtopt endif ifdef CFG_DISABLE_DEBUG CFG_RUSTC_FLAGS += --cfg ndebug CFG_GCCISH_CFLAGS += -DRUST_NDEBUG else $(info cfg: enabling more debugging (CFG_ENABLE_DEBUG)) CFG_RUSTC_FLAGS += --cfg debug CFG_GCCISH_CFLAGS += -DRUST_DEBUG endif ifdef SAVE_TEMPS CFG_RUSTC_FLAGS += --save-temps endif ifdef ASM_COMMENTS CFG_RUSTC_FLAGS += -Z asm-comments endif ifdef TIME_PASSES CFG_RUSTC_FLAGS += -Z time-passes endif ifdef TIME_LLVM_PASSES CFG_RUSTC_FLAGS += -Z time-llvm-passes endif ifdef TRACE CFG_RUSTC_FLAGS += -Z trace endif ifndef DEBUG_BORROWS RUSTFLAGS_STAGE0 += -Z no-debug-borrows RUSTFLAGS_STAGE1 += -Z no-debug-borrows RUSTFLAGS_STAGE2 += -Z no-debug-borrows endif # The executables crated during this compilation process have no need to include # static copies of libstd and libextra. We also generate dynamic versions of all # libraries, so in the interest of space, prefer dynamic linking throughout the # compilation process. # # Note though that these flags are omitted for stage2+. This means that the # snapshot will be generated with a statically linked rustc so we only have to # worry about the distribution of one file (with its native dynamic # dependencies) RUSTFLAGS_STAGE0 += -Z prefer-dynamic RUSTFLAGS_STAGE1 += -Z prefer-dynamic # platform-specific auto-configuration include $(CFG_SRC_DIR)mk/platform.mk # Run the stage1/2 compilers under valgrind ifdef VALGRIND_COMPILE CFG_VALGRIND_COMPILE :=$(CFG_VALGRIND) else CFG_VALGRIND_COMPILE := endif # version-string calculation CFG_GIT_DIR := $(CFG_SRC_DIR).git CFG_RELEASE = 0.9 CFG_VERSION = $(CFG_RELEASE) # windows exe's need numeric versions - don't use anything but # numbers and dots here CFG_VERSION_WIN = 0.9 # since $(CFG_GIT) may contain spaces (especially on Windows), # we need to escape them. (" " to r"\ ") # Note that $(subst ...) ignores space after `subst`, # so we use a hack: define $(SPACE) which contains space character. SPACE := SPACE += ifneq ($(wildcard $(subst $(SPACE),\$(SPACE),$(CFG_GIT))),) ifneq ($(wildcard $(subst $(SPACE),\$(SPACE),$(CFG_GIT_DIR))),) CFG_VERSION += $(shell git --git-dir='$(CFG_GIT_DIR)' log -1 \ --pretty=format:'(%h %ci)') CFG_VER_HASH = $(shell git --git-dir='$(CFG_GIT_DIR)' rev-parse HEAD) endif endif ifdef CFG_ENABLE_VALGRIND $(info cfg: enabling valgrind (CFG_ENABLE_VALGRIND)) else CFG_VALGRIND := endif ifdef CFG_BAD_VALGRIND $(info cfg: disabling valgrind due to its unreliability on this platform) CFG_VALGRIND := endif ###################################################################### # Target-and-rule "utility variables" ###################################################################### ifdef VERBOSE Q := E = else Q := @ E = echo $(1) endif S := $(CFG_SRC_DIR) define DEF_X X_$(1) := $(CFG_EXE_SUFFIX_$(1)) endef $(foreach target,$(CFG_TARGET),\ $(eval $(call DEF_X,$(target)))) # Look in doc and src dirs. VPATH := $(S)doc $(S)src # "Source" files we generate in builddir along the way. GENERATED := # Delete the built-in rules. .SUFFIXES: %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% ###################################################################### # Crates ###################################################################### define DEF_LIBS CFG_RUNTIME_$(1) :=$(call CFG_STATIC_LIB_NAME_$(1),rustrt) CFG_RUSTLLVM_$(1) :=$(call CFG_STATIC_LIB_NAME_$(1),rustllvm) CFG_STDLIB_$(1) :=$(call CFG_LIB_NAME_$(1),std) CFG_EXTRALIB_$(1) :=$(call CFG_LIB_NAME_$(1),extra) CFG_LIBRUSTC_$(1) :=$(call CFG_LIB_NAME_$(1),rustc) CFG_LIBSYNTAX_$(1) :=$(call CFG_LIB_NAME_$(1),syntax) CFG_LIBRUSTPKG_$(1) :=$(call CFG_LIB_NAME_$(1),rustpkg) CFG_LIBRUSTDOC_$(1) :=$(call CFG_LIB_NAME_$(1),rustdoc) CFG_LIBRUSTUV_$(1) :=$(call CFG_LIB_NAME_$(1),rustuv) CFG_LIBGREEN_$(1) :=$(call CFG_LIB_NAME_$(1),green) CFG_LIBNATIVE_$(1) :=$(call CFG_LIB_NAME_$(1),native) EXTRALIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),extra) STDLIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),std) LIBRUSTC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustc) LIBSYNTAX_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),syntax) LIBRUSTPKG_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustpkg) LIBRUSTDOC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustdoc) LIBRUSTUV_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustuv) LIBGREEN_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),green) LIBNATIVE_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),native) EXTRALIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),extra) STDLIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),std) LIBRUSTC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustc) LIBSYNTAX_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),syntax) LIBRUSTPKG_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustpkg) LIBRUSTDOC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustdoc) LIBRUSTUV_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustuv) LIBGREEN_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),green) LIBNATIVE_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),native) EXTRALIB_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,extra) STDLIB_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,std) LIBRUSTUV_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,rustuv) LIBSYNTAX_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,syntax) LIBRUSTC_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,rustc) LIBNATIVE_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,native) LIBGREEN_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,green) endef # $(1) is the path for directory to match against # $(2) is the glob to use in the match # $(3) is filename (usually the target being created) to filter out from match # (i.e. filename is not out-of-date artifact from prior Rust version/build) # # Note that a common bug is to accidentally construct the glob denoted # by $(2) with a space character prefix, which invalidates the # construction $(1)$(2). define CHECK_FOR_OLD_GLOB_MATCHES_EXCEPT $(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then echo "warning: there are previous" \'$(2)\' "libraries:" $$MATCHES; fi endef # Same interface as above, but deletes rather than just listing the files. ifdef VERBOSE define REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT $(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then echo "warning: removing previous" \'$(2)\' "libraries:" $$MATCHES; rm $$MATCHES ; fi endef else define REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT $(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then rm $$MATCHES ; fi endef endif # We use a different strategy for LIST_ALL_OLD_GLOB_MATCHES_EXCEPT # than in the macros above because it needs the result of running the # `ls` command after other rules in the command list have run; the # macro-expander for $(wildcard ...) would deliver its results too # soon. (This is in contrast to the macros above, which are meant to # be run at the outset of a command list in a rule.) ifdef VERBOSE define LIST_ALL_OLD_GLOB_MATCHES_EXCEPT @echo "info: now are following matches for" '$(2)' "libraries:" @( cd $(1) && ( ls $(2) 2>/dev/null || true ) | grep -v $(3) || true ) endef else define LIST_ALL_OLD_GLOB_MATCHES_EXCEPT endef endif $(foreach target,$(CFG_TARGET),\ $(eval $(call DEF_LIBS,$(target)))) ###################################################################### # Standard library variables ###################################################################### STDLIB_CRATE := $(S)src/libstd/lib.rs STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/libstd/, \ *.rs */*.rs */*/*rs */*/*/*rs)) ###################################################################### # Extra library variables ###################################################################### EXTRALIB_CRATE := $(S)src/libextra/lib.rs EXTRALIB_INPUTS := $(wildcard $(addprefix $(S)src/libextra/, \ *.rs */*.rs)) ###################################################################### # Rust UV library variables ###################################################################### LIBRUSTUV_CRATE := $(S)src/librustuv/lib.rs LIBRUSTUV_INPUTS := $(wildcard $(addprefix $(S)src/librustuv/, \ *.rs */*.rs)) ###################################################################### # Green threading library variables ###################################################################### LIBGREEN_CRATE := $(S)src/libgreen/lib.rs LIBGREEN_INPUTS := $(wildcard $(addprefix $(S)src/libgreen/, \ *.rs */*.rs)) ###################################################################### # Native threading library variables ###################################################################### LIBNATIVE_CRATE := $(S)src/libnative/lib.rs LIBNATIVE_INPUTS := $(wildcard $(addprefix $(S)src/libnative/, \ *.rs */*.rs)) ###################################################################### # rustc crate variables ###################################################################### COMPILER_CRATE := $(S)src/librustc/lib.rs COMPILER_INPUTS := $(wildcard $(addprefix $(S)src/librustc/, \ *.rs */*.rs */*/*.rs */*/*/*.rs)) LIBSYNTAX_CRATE := $(S)src/libsyntax/lib.rs LIBSYNTAX_INPUTS := $(wildcard $(addprefix $(S)src/libsyntax/, \ *.rs */*.rs */*/*.rs */*/*/*.rs)) DRIVER_CRATE := $(S)src/driver/driver.rs ###################################################################### # LLVM macros ###################################################################### # FIXME: x86-ism LLVM_COMPONENTS=x86 arm mips ipo bitreader bitwriter linker asmparser jit mcjit \ interpreter instrumentation define DEF_LLVM_VARS # The configure script defines these variables with the target triples # separated by Z. This defines new ones with the expected format. CFG_LLVM_BUILD_DIR_$(1):=$$(CFG_LLVM_BUILD_DIR_$(subst -,_,$(1))) CFG_LLVM_INST_DIR_$(1):=$$(CFG_LLVM_INST_DIR_$(subst -,_,$(1))) # Any rules that depend on LLVM should depend on LLVM_CONFIG LLVM_CONFIG_$(1):=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-config$$(X_$(1)) LLVM_MC_$(1):=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-mc$$(X_$(1)) LLVM_VERSION_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --version) LLVM_BINDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --bindir) LLVM_INCDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --includedir) LLVM_LIBDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --libdir) LLVM_LIBS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --libs $$(LLVM_COMPONENTS)) LLVM_LDFLAGS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --ldflags) # On FreeBSD, it may search wrong headers (that are for pre-installed LLVM), # so we replace -I with -iquote to ensure that it searches bundled LLVM first. LLVM_CXXFLAGS_$(1)=$$(subst -I, -iquote , $$(shell "$$(LLVM_CONFIG_$(1))" --cxxflags)) LLVM_HOST_TRIPLE_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --host-target) LLVM_AS_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-as$$(X_$(1)) LLC_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llc$$(X_$(1)) endef $(foreach host,$(CFG_HOST), \ $(eval $(call DEF_LLVM_VARS,$(host)))) ###################################################################### # Exports for sub-utilities ###################################################################### # Note that any variable that re-configure should pick up needs to be # exported export CFG_SRC_DIR export CFG_BUILD_DIR export CFG_VERSION export CFG_VERSION_WIN export CFG_RELEASE export CFG_BUILD export CFG_LLVM_ROOT export CFG_ENABLE_MINGW_CROSS export CFG_PREFIX export CFG_LIBDIR export CFG_RUSTLIBDIR export LIBDIR_RELATIVE ###################################################################### # Subprograms ###################################################################### ###################################################################### # Per-stage targets and runner ###################################################################### define SREQ # $(1) is the stage number # $(2) is the target triple # $(3) is the host triple # Destinations of artifacts for the host compiler HROOT$(1)_H_$(3) = $(3)/stage$(1) HBIN$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/bin HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/$$(LIBDIR_RELATIVE) # Destinations of artifacts for target architectures TROOT$(1)_T_$(2)_H_$(3) = $$(HLIB$(1)_H_$(3))/$$(CFG_RUSTLIBDIR)/$(2) TBIN$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/bin TLIB$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/lib # The name of the standard and extra libraries used by rustc HSTDLIB_DEFAULT$(1)_H_$(3) = \ $$(HLIB$(1)_H_$(3))/$(CFG_STDLIB_$(3)) TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3) = \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) HEXTRALIB_DEFAULT$(1)_H_$(3) = \ $$(HLIB$(1)_H_$(3))/$(CFG_EXTRALIB_$(3)) TEXTRALIB_DEFAULT$(1)_T_$(2)_H_$(3) = \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)) HLIBRUSTC_DEFAULT$(1)_H_$(3) = \ $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTC_$(3)) TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3) = \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2)) HLIBRUSTUV_DEFAULT$(1)_H_$(3) = \ $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTUV_$(3)) TLIBRUSTUV_DEFAULT$(1)_T_$(2)_H_$(3) = \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTUV_$(2)) HLIBGREEN_DEFAULT$(1)_H_$(3) = \ $$(HLIB$(1)_H_$(3))/$(CFG_LIBGREEN_$(3)) TLIBGREEN_DEFAULT$(1)_T_$(2)_H_$(3) = \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBGREEN_$(2)) HLIBNATIVE_DEFAULT$(1)_H_$(3) = \ $$(HLIB$(1)_H_$(3))/$(CFG_LIBNATIVE_$(3)) TLIBNATIVE_DEFAULT$(1)_T_$(2)_H_$(3) = \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBNATIVE_$(2)) # Preqrequisites for using the stageN compiler ifeq ($(1),0) HSREQ$(1)_H_$(3) = $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) else HSREQ$(1)_H_$(3) = \ $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \ $$(HSTDLIB_DEFAULT$(1)_H_$(3)) \ $$(HEXTRALIB_DEFAULT$(1)_H_$(3)) \ $$(HLIBSYNTAX_DEFAULT$(1)_H_$(3)) \ $$(HLIBRUSTC_DEFAULT$(1)_H_$(3)) \ $$(HLIBRUSTUV_DEFAULT$(1)_H_$(3)) \ $$(HLIBGREEN_DEFAULT$(1)_H_$(3)) \ $$(HLIBNATIVE_DEFAULT$(1)_H_$(3)) \ $$(MKFILE_DEPS) endif # Prerequisites for using the stageN compiler to build target artifacts TSREQ$(1)_T_$(2)_H_$(3) = \ $$(HSREQ$(1)_H_$(3)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a # Prerequisites for a working stageN compiler and libraries, for a specific target SREQ$(1)_T_$(2)_H_$(3) = \ $$(TSREQ$(1)_T_$(2)_H_$(3)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTUV_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBGREEN_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBNATIVE_$(2)) # Prerequisites for a working stageN compiler and libraries, for a specific target CSREQ$(1)_T_$(2)_H_$(3) = \ $$(TSREQ$(1)_T_$(2)_H_$(3)) \ $$(HBIN$(1)_H_$(3))/rustpkg$$(X_$(3)) \ $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \ $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTPKG_$(3)) \ $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTDOC_$(3)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTUV_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBGREEN_$(2)) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBNATIVE_$(2)) ifeq ($(1),0) # Don't run the the stage0 compiler under valgrind - that ship has sailed CFG_VALGRIND_COMPILE$(1) = else CFG_VALGRIND_COMPILE$(1) = $$(CFG_VALGRIND_COMPILE) endif # Add RUSTFLAGS_STAGEN values to the build command EXTRAFLAGS_STAGE$(1) = $$(RUSTFLAGS_STAGE$(1)) CFGFLAG$(1)_T_$(2)_H_$(3) = stage$(1) # Pass --cfg stage0 only for the build->host part of stage0; # if you're building a cross config, the host->* parts are # effectively stage1, since it uses the just-built stage0. ifeq ($(1),0) ifneq ($(strip $(CFG_BUILD)),$(strip $(3))) CFGFLAG$(1)_T_$(2)_H_$(3) = stage1 endif endif STAGE$(1)_T_$(2)_H_$(3) := \ $$(Q)$$(call CFG_RUN_TARG_$(3),$(1), \ $$(CFG_VALGRIND_COMPILE$(1)) \ $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \ --cfg $$(CFGFLAG$(1)_T_$(2)_H_$(3)) \ $$(CFG_RUSTC_FLAGS) $$(EXTRAFLAGS_STAGE$(1)) --target=$(2)) \ $$(RUSTC_FLAGS_$(2)) PERF_STAGE$(1)_T_$(2)_H_$(3) := \ $$(Q)$$(call CFG_RUN_TARG_$(3),$(1), \ $$(CFG_PERF_TOOL) \ $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \ --cfg $$(CFGFLAG$(1)_T_$(2)_H_$(3)) \ $$(CFG_RUSTC_FLAGS) $$(EXTRAFLAGS_STAGE$(1)) --target=$(2)) \ $$(RUSTC_FLAGS_$(2)) endef $(foreach build,$(CFG_HOST), \ $(eval $(foreach target,$(CFG_TARGET), \ $(eval $(foreach stage,$(STAGES), \ $(eval $(call SREQ,$(stage),$(target),$(build)))))))) ###################################################################### # rustc-H-targets # # Builds a functional Rustc for the given host. ###################################################################### define DEF_RUSTC_STAGE_TARGET # $(1) == architecture # $(2) == stage rustc-stage$(2)-H-$(1): \ $$(foreach target,$$(CFG_TARGET), \ $$(SREQ$(2)_T_$$(target)_H_$(1))) endef $(foreach host,$(CFG_HOST), \ $(eval $(foreach stage,1 2 3, \ $(eval $(call DEF_RUSTC_STAGE_TARGET,$(host),$(stage)))))) rustc-stage1: rustc-stage1-H-$(CFG_BUILD) rustc-stage2: rustc-stage2-H-$(CFG_BUILD) rustc-stage3: rustc-stage3-H-$(CFG_BUILD) define DEF_RUSTC_TARGET # $(1) == architecture rustc-H-$(1): rustc-stage2-H-$(1) endef $(foreach host,$(CFG_TARGET), \ $(eval $(call DEF_RUSTC_TARGET,$(host)))) rustc-stage1: rustc-stage1-H-$(CFG_BUILD) rustc-stage2: rustc-stage2-H-$(CFG_BUILD) rustc-stage3: rustc-stage3-H-$(CFG_BUILD) rustc: rustc-H-$(CFG_BUILD) rustc-H-all: $(foreach host,$(CFG_HOST),rustc-H-$(host)) ###################################################################### # Entrypoint rule ###################################################################### .DEFAULT_GOAL := all ifneq ($(CFG_IN_TRANSITION),) CFG_INFO := $(info cfg:) CFG_INFO := $(info cfg: *** compiler is in snapshot transition ***) CFG_INFO := $(info cfg: *** stage2 and later will not be built ***) CFG_INFO := $(info cfg:) #XXX This is surely busted all: $(SREQ1$(CFG_BUILD)) $(GENERATED) docs else define ALL_TARGET_N ifneq ($$(findstring $(1),$$(CFG_HOST)),) # This is a host all-target-$(1)-host-$(2): $$(CSREQ2_T_$(1)_H_$(2)) else # This is a target only all-target-$(1)-host-$(2): $$(SREQ2_T_$(1)_H_$(2)) endif endef $(foreach target,$(CFG_TARGET), \ $(foreach host,$(CFG_HOST), \ $(eval $(call ALL_TARGET_N,$(target),$(host))))) ALL_TARGET_RULES = $(foreach target,$(CFG_TARGET), \ $(foreach host,$(CFG_HOST), \ all-target-$(target)-host-$(host))) all: $(ALL_TARGET_RULES) $(GENERATED) docs endif ###################################################################### # Re-configuration ###################################################################### ifndef CFG_DISABLE_MANAGE_SUBMODULES # This is a pretty expensive operation but I don't see any way to avoid it NEED_GIT_RECONFIG=$(shell cd "$(CFG_SRC_DIR)" && "$(CFG_GIT)" submodule status | grep -c '^\(+\|-\)') else NEED_GIT_RECONFIG=0 endif ifeq ($(NEED_GIT_RECONFIG),0) else # If the submodules have changed then always execute config.mk .PHONY: config.stamp endif Makefile config.mk: config.stamp config.stamp: $(S)configure $(S)Makefile.in $(S)src/snapshots.txt @$(call E, cfg: reconfiguring) $(Q)$(S)configure $(CFG_CONFIGURE_ARGS) ###################################################################### # Primary-target makefiles ###################################################################### # Issue #9531: If you change the order of any of the following (or add # new definitions), make sure definitions always precede their uses, # especially for the dependency lists of recipes. include $(CFG_SRC_DIR)mk/rt.mk include $(CFG_SRC_DIR)mk/target.mk include $(CFG_SRC_DIR)mk/host.mk include $(CFG_SRC_DIR)mk/stage0.mk include $(CFG_SRC_DIR)mk/rustllvm.mk include $(CFG_SRC_DIR)mk/tools.mk include $(CFG_SRC_DIR)mk/docs.mk include $(CFG_SRC_DIR)mk/llvm.mk ###################################################################### # Secondary makefiles, conditionalized for speed ###################################################################### ifneq ($(strip $(findstring dist,$(MAKECMDGOALS)) \ $(findstring check,$(MAKECMDGOALS)) \ $(findstring test,$(MAKECMDGOALS)) \ $(findstring tidy,$(MAKECMDGOALS)) \ $(findstring clean,$(MAKECMDGOALS))),) CFG_INFO := $(info cfg: including dist rules) include $(CFG_SRC_DIR)mk/dist.mk endif ifneq ($(strip $(findstring snap,$(MAKECMDGOALS)) \ $(findstring clean,$(MAKECMDGOALS))),) CFG_INFO := $(info cfg: including snap rules) include $(CFG_SRC_DIR)mk/snap.mk endif ifneq ($(strip $(findstring check,$(MAKECMDGOALS)) \ $(findstring test,$(MAKECMDGOALS)) \ $(findstring perf,$(MAKECMDGOALS)) \ $(findstring tidy,$(MAKECMDGOALS))),) CFG_INFO := $(info cfg: including test rules) include $(CFG_SRC_DIR)mk/tests.mk endif ifneq ($(findstring perf,$(MAKECMDGOALS)),) CFG_INFO := $(info cfg: including perf rules) include $(CFG_SRC_DIR)mk/perf.mk endif ifneq ($(findstring clean,$(MAKECMDGOALS)),) CFG_INFO := $(info cfg: including clean rules) include $(CFG_SRC_DIR)mk/clean.mk endif ifneq ($(findstring install,$(MAKECMDGOALS)),) CFG_INFO := $(info cfg: including install rules) include $(CFG_SRC_DIR)mk/install.mk endif ifneq ($(strip $(findstring TAGS.emacs,$(MAKECMDGOALS)) \ $(findstring TAGS.vi,$(MAKECMDGOALS))),) CFG_INFO := $(info cfg: including ctags rules) include $(CFG_SRC_DIR)mk/ctags.mk endif # Find all of the .d files and include them to add information about # header file dependencies. ALL_DEP_FILES := $(ALL_OBJ_FILES:%.o=%.d) -include $(ALL_DEP_FILES)