aboutsummaryrefslogtreecommitdiff
path: root/circuitpython/py/py.mk
diff options
context:
space:
mode:
Diffstat (limited to 'circuitpython/py/py.mk')
-rw-r--r--circuitpython/py/py.mk310
1 files changed, 310 insertions, 0 deletions
diff --git a/circuitpython/py/py.mk b/circuitpython/py/py.mk
new file mode 100644
index 0000000..f1864e5
--- /dev/null
+++ b/circuitpython/py/py.mk
@@ -0,0 +1,310 @@
+# 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
+
+TRANSLATION ?= en_US
+
+# 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
+SRC_USERMOD :=
+SRC_USERMOD_CXX :=
+CFLAGS_USERMOD :=
+CXXFLAGS_USERMOD :=
+LDFLAGS_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_MOD += $(patsubst $(USER_C_MODULES)/%.c,%.c,$(SRC_USERMOD))
+SRC_MOD_CXX += $(patsubst $(USER_C_MODULES)/%.cpp,%.cpp,$(SRC_USERMOD_CXX))
+CFLAGS_MOD += $(CFLAGS_USERMOD)
+CXXFLAGS_MOD += $(CXXFLAGS_USERMOD)
+LDFLAGS_MOD += $(LDFLAGS_USERMOD)
+endif
+
+ifeq ($(CIRCUITPY_ULAB),1)
+ULAB_SRCS := $(shell find $(TOP)/extmod/ulab/code -type f -name "*.c")
+SRC_MOD += $(patsubst $(TOP)/%,%,$(ULAB_SRCS))
+CFLAGS_MOD += -DCIRCUITPY_ULAB=1 -DMODULE_ULAB_ENABLED=1 -DULAB_HAS_USER_MODULE=0 -iquote $(TOP)/extmod/ulab/code
+$(BUILD)/extmod/ulab/code/%.o: CFLAGS += -Wno-missing-declarations -Wno-missing-prototypes -Wno-unused-parameter -Wno-float-equal -Wno-sign-compare -Wno-cast-align -Wno-shadow -DCIRCUITPY
+endif
+
+# py object files
+PY_CORE_O_BASENAME = $(addprefix py/,\
+ mpstate.o \
+ nlr.o \
+ nlrx86.o \
+ nlrx64.o \
+ nlrthumb.o \
+ nlraarch64.o \
+ nlrpowerpc.o \
+ nlrxtensa.o \
+ nlrsetjmp.o \
+ malloc.o \
+ gc.o \
+ gc_long_lived.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 \
+ enum.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 \
+ objtraceback.o \
+ objtuple.o \
+ objtype.o \
+ objzip.o \
+ opmethods.o \
+ proto.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 \
+ moduerrno.o \
+ modthread.o \
+ vm.o \
+ bc.o \
+ showbc.o \
+ repl.o \
+ smallint.o \
+ frozenmod.o \
+ )
+
+PY_EXTMOD_O_BASENAME = \
+ extmod/moduasyncio.o \
+ extmod/moductypes.o \
+ extmod/modujson.o \
+ extmod/modure.o \
+ extmod/moduzlib.o \
+ extmod/moduheapq.o \
+ extmod/modutimeq.o \
+ extmod/moduhashlib.o \
+ extmod/modubinascii.o \
+ extmod/modurandom.o \
+ extmod/moduselect.o \
+ extmod/modframebuf.o \
+ extmod/vfs.o \
+ extmod/vfs_blockdev.o \
+ extmod/vfs_reader.o \
+ extmod/vfs_posix.o \
+ extmod/vfs_posix_file.o \
+ extmod/vfs_fat.o \
+ extmod/vfs_fat_diskio.o \
+ extmod/vfs_fat_file.o \
+ extmod/vfs_lfs.o \
+ extmod/utime_mphal.o \
+ shared/libc/abort_.o \
+ shared/libc/printf.o \
+
+# prepend the build destination prefix to the py object files
+PY_CORE_O = $(addprefix $(BUILD)/, $(PY_CORE_O_BASENAME))
+PY_EXTMOD_O = $(addprefix $(BUILD)/, $(PY_EXTMOD_O_BASENAME))
+
+# this is a convenience variable for ports that want core, extmod and frozen code
+PY_O = $(PY_CORE_O) $(PY_EXTMOD_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_EMITNATIVE = py/emitn%
+SRC_QSTR += $(SRC_MOD) $(filter-out $(SRC_QSTR_IGNORE),$(PY_CORE_O_BASENAME:.o=.c)) $(PY_EXTMOD_O_BASENAME:.o=.c)
+# Sources that only hold QSTRs after pre-processing.
+SRC_QSTR_PREPROCESSOR = $(addprefix $(TOP)/, $(filter $(SRC_QSTR_EMITNATIVE),$(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)
+ $(STEPECHO) "GEN $@"
+ $(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)
+
+$(HEADER_BUILD)/$(TRANSLATION).mo: $(TOP)/locale/$(TRANSLATION).po | $(HEADER_BUILD)
+ $(Q)msgfmt -o $@ $^
+
+$(HEADER_BUILD)/qstrdefs.preprocessed.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) mpconfigport.h $(MPCONFIGPORT_MK) $(PY_SRC)/mpconfig.h | $(HEADER_BUILD)
+ $(STEPECHO) "GEN $@"
+ $(Q)cat $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) | $(SED) 's/^Q(.*)/"&"/' | $(CPP) $(CFLAGS) - | $(SED) 's/^"\(Q(.*)\)"/\1/' > $@
+
+# qstr data
+$(HEADER_BUILD)/qstrdefs.enum.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h
+ $(STEPECHO) "GEN $@"
+ $(Q)$(PYTHON) $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@
+
+# 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.
+$(HEADER_BUILD)/qstrdefs.generated.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h
+ $(STEPECHO) "GEN $@"
+ $(Q)$(PYTHON) $(PY_SRC)/makeqstrdata.py --compression_filename $(HEADER_BUILD)/compression.generated.h --translation $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@
+
+$(PY_BUILD)/qstr.o: $(HEADER_BUILD)/qstrdefs.generated.h
+
+
+# build a list of registered modules for py/objmodule.c.
+$(HEADER_BUILD)/moduledefs.h: $(SRC_QSTR) $(QSTR_GLOBAL_DEPENDENCIES) | $(HEADER_BUILD)/mpversion.h
+ @$(ECHO) "GEN $@"
+ $(Q)$(PYTHON) $(PY_SRC)/makemoduledefs.py --vpath="., $(TOP), $(USER_C_MODULES)" $(SRC_QSTR) > $@
+
+# 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
+ifndef SUPEROPT_GC
+ SUPEROPT_GC = 1
+endif
+
+ifeq ($(SUPEROPT_GC),1)
+$(PY_BUILD)/gc.o: CFLAGS += $(CSUPEROPT)
+endif
+
+# optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster)
+ifndef SUPEROPT_VM
+ SUPEROPT_VM = 1
+endif
+
+ifeq ($(SUPEROPT_VM),1)
+$(PY_BUILD)/vm.o: CFLAGS += $(CSUPEROPT)
+endif
+
+# 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
+
+# Include rules for extmod related code
+include $(TOP)/extmod/extmod.mk