# where py object files go (they have a name prefix to prevent filename clashes) PY_BUILD = $(BUILD)/py # where autogenerated header files go HEADER_BUILD = $(BUILD)/genhdr # file containing qstr defs for the core Python bit PY_QSTR_DEFS = $(PY_SRC)/qstrdefs.h # If qstr autogeneration is not disabled we specify the output header # for all collected qstrings. ifneq ($(QSTR_AUTOGEN_DISABLE),1) QSTR_DEFS_COLLECTED = $(HEADER_BUILD)/qstrdefs.collected.h endif # Any files listed by these variables will cause a full regeneration of qstrs # DEPENDENCIES: included in qstr processing; REQUIREMENTS: not included QSTR_GLOBAL_DEPENDENCIES += $(PY_SRC)/mpconfig.h mpconfigport.h QSTR_GLOBAL_REQUIREMENTS += $(HEADER_BUILD)/mpversion.h # some code is performance bottleneck and compiled with other optimization options CSUPEROPT = -O3 # Enable building 32-bit code on 64-bit host. ifeq ($(MICROPY_FORCE_32BIT),1) CC += -m32 CXX += -m32 LD += -m32 endif # External modules written in C. ifneq ($(USER_C_MODULES),) # pre-define USERMOD variables as expanded so that variables are immediate # expanded as they're added to them # C/C++ files that are included in the QSTR/module build SRC_USERMOD_C := SRC_USERMOD_CXX := # Other C/C++ files (e.g. libraries or helpers) SRC_USERMOD_LIB_C := SRC_USERMOD_LIB_CXX := # Optionally set flags CFLAGS_USERMOD := CXXFLAGS_USERMOD := LDFLAGS_USERMOD := # Backwards compatibility with older user c modules that set SRC_USERMOD # added to SRC_USERMOD_C below SRC_USERMOD := $(foreach module, $(wildcard $(USER_C_MODULES)/*/micropython.mk), \ $(eval USERMOD_DIR = $(patsubst %/,%,$(dir $(module))))\ $(info Including User C Module from $(USERMOD_DIR))\ $(eval include $(module))\ ) SRC_USERMOD_C += $(SRC_USERMOD) SRC_USERMOD_PATHFIX_C += $(patsubst $(USER_C_MODULES)/%.c,%.c,$(SRC_USERMOD_C)) SRC_USERMOD_PATHFIX_CXX += $(patsubst $(USER_C_MODULES)/%.cpp,%.cpp,$(SRC_USERMOD_CXX)) SRC_USERMOD_PATHFIX_LIB_C += $(patsubst $(USER_C_MODULES)/%.c,%.c,$(SRC_USERMOD_LIB_C)) SRC_USERMOD_PATHFIX_LIB_CXX += $(patsubst $(USER_C_MODULES)/%.cpp,%.cpp,$(SRC_USERMOD_LIB_CXX)) CFLAGS += $(CFLAGS_USERMOD) CXXFLAGS += $(CXXFLAGS_USERMOD) LDFLAGS += $(LDFLAGS_USERMOD) SRC_QSTR += $(SRC_USERMOD_PATHFIX_C) $(SRC_USERMOD_PATHFIX_CXX) PY_O += $(addprefix $(BUILD)/, $(SRC_USERMOD_PATHFIX_C:.c=.o)) PY_O += $(addprefix $(BUILD)/, $(SRC_USERMOD_PATHFIX_CXX:.cpp=.o)) PY_O += $(addprefix $(BUILD)/, $(SRC_USERMOD_PATHFIX_LIB_C:.c=.o)) PY_O += $(addprefix $(BUILD)/, $(SRC_USERMOD_PATHFIX_LIB_CXX:.cpp=.o)) endif # py object files PY_CORE_O_BASENAME = $(addprefix py/,\ mpstate.o \ nlr.o \ nlrx86.o \ nlrx64.o \ nlrthumb.o \ nlraarch64.o \ nlrmips.o \ nlrpowerpc.o \ nlrxtensa.o \ nlrsetjmp.o \ malloc.o \ gc.o \ pystack.o \ qstr.o \ vstr.o \ mpprint.o \ unicode.o \ mpz.o \ reader.o \ lexer.o \ parse.o \ scope.o \ compile.o \ emitcommon.o \ emitbc.o \ asmbase.o \ asmx64.o \ emitnx64.o \ asmx86.o \ emitnx86.o \ asmthumb.o \ emitnthumb.o \ emitinlinethumb.o \ asmarm.o \ emitnarm.o \ asmxtensa.o \ emitnxtensa.o \ emitinlinextensa.o \ emitnxtensawin.o \ formatfloat.o \ parsenumbase.o \ parsenum.o \ emitglue.o \ persistentcode.o \ runtime.o \ runtime_utils.o \ scheduler.o \ nativeglue.o \ pairheap.o \ ringbuf.o \ stackctrl.o \ argcheck.o \ warning.o \ profile.o \ map.o \ obj.o \ objarray.o \ objattrtuple.o \ objbool.o \ objboundmeth.o \ objcell.o \ objclosure.o \ objcomplex.o \ objdeque.o \ objdict.o \ objenumerate.o \ objexcept.o \ objfilter.o \ objfloat.o \ objfun.o \ objgenerator.o \ objgetitemiter.o \ objint.o \ objint_longlong.o \ objint_mpz.o \ objlist.o \ objmap.o \ objmodule.o \ objobject.o \ objpolyiter.o \ objproperty.o \ objnone.o \ objnamedtuple.o \ objrange.o \ objreversed.o \ objset.o \ objsingleton.o \ objslice.o \ objstr.o \ objstrunicode.o \ objstringio.o \ objtuple.o \ objtype.o \ objzip.o \ opmethods.o \ sequence.o \ stream.o \ binary.o \ builtinimport.o \ builtinevex.o \ builtinhelp.o \ modarray.o \ modbuiltins.o \ modcollections.o \ modgc.o \ modio.o \ modmath.o \ modcmath.o \ modmicropython.o \ modstruct.o \ modsys.o \ moderrno.o \ modthread.o \ vm.o \ bc.o \ showbc.o \ repl.o \ smallint.o \ frozenmod.o \ ) # prepend the build destination prefix to the py object files PY_CORE_O = $(addprefix $(BUILD)/, $(PY_CORE_O_BASENAME)) # this is a convenience variable for ports that want core, extmod and frozen code PY_O += $(PY_CORE_O) # object file for frozen code specified via a manifest ifneq ($(FROZEN_MANIFEST),) PY_O += $(BUILD)/$(BUILD)/frozen_content.o endif # Sources that may contain qstrings SRC_QSTR_IGNORE = py/nlr% SRC_QSTR += $(filter-out $(SRC_QSTR_IGNORE),$(PY_CORE_O_BASENAME:.o=.c)) # Anything that depends on FORCE will be considered out-of-date FORCE: .PHONY: FORCE $(HEADER_BUILD)/mpversion.h: FORCE | $(HEADER_BUILD) $(Q)$(PYTHON) $(PY_SRC)/makeversionhdr.py $@ # mpconfigport.mk is optional, but changes to it may drastically change # overall config, so they need to be caught MPCONFIGPORT_MK = $(wildcard mpconfigport.mk) # qstr data # Adding an order only dependency on $(HEADER_BUILD) causes $(HEADER_BUILD) to get # created before we run the script to generate the .h # Note: we need to protect the qstr names from the preprocessor, so we wrap # the lines in "" and then unwrap after the preprocessor is finished. # See more information about this process in docs/develop/qstr.rst. $(HEADER_BUILD)/qstrdefs.generated.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) $(PY_SRC)/makeqstrdata.py mpconfigport.h $(MPCONFIGPORT_MK) $(PY_SRC)/mpconfig.h | $(HEADER_BUILD) $(ECHO) "GEN $@" $(Q)$(CAT) $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) | $(SED) 's/^Q(.*)/"&"/' | $(CPP) $(CFLAGS) - | $(SED) 's/^\"\(Q(.*)\)\"/\1/' > $(HEADER_BUILD)/qstrdefs.preprocessed.h $(Q)$(PYTHON) $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ $(HEADER_BUILD)/compressed.data.h: $(HEADER_BUILD)/compressed.collected $(ECHO) "GEN $@" $(Q)$(PYTHON) $(PY_SRC)/makecompresseddata.py $< > $@ # build a list of registered modules for py/objmodule.c. $(HEADER_BUILD)/moduledefs.h: $(HEADER_BUILD)/moduledefs.collected @$(ECHO) "GEN $@" $(Q)$(PYTHON) $(PY_SRC)/makemoduledefs.py $< > $@ # build a list of registered root pointers for py/mpstate.h. $(HEADER_BUILD)/root_pointers.h: $(HEADER_BUILD)/root_pointers.collected $(PY_SRC)/make_root_pointers.py @$(ECHO) "GEN $@" $(Q)$(PYTHON) $(PY_SRC)/make_root_pointers.py $< > $@ # Standard C functions like memset need to be compiled with special flags so # the compiler does not optimise these functions in terms of themselves. CFLAGS_BUILTIN ?= -ffreestanding -fno-builtin -fno-lto $(BUILD)/shared/libc/string0.o: CFLAGS += $(CFLAGS_BUILTIN) # Force nlr code to always be compiled with space-saving optimisation so # that the function preludes are of a minimal and predictable form. $(PY_BUILD)/nlr%.o: CFLAGS += -Os # optimising gc for speed; 5ms down to 4ms on pybv2 $(PY_BUILD)/gc.o: CFLAGS += $(CSUPEROPT) # optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster) $(PY_BUILD)/vm.o: CFLAGS += $(CSUPEROPT) # Optimizing vm.o for modern deeply pipelined CPUs with branch predictors # may require disabling tail jump optimization. This will make sure that # each opcode has its own dispatching jump which will improve branch # branch predictor efficiency. # https://marc.info/?l=lua-l&m=129778596120851 # http://hg.python.org/cpython/file/b127046831e2/Python/ceval.c#l828 # http://www.emulators.com/docs/nx25_nostradamus.htm #-fno-crossjumping