circuitpython/py/py.mk

267 lines
6.9 KiB
Makefile
Raw Normal View History

# 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
# 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 :=
CFLAGS_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))
CFLAGS_MOD += $(CFLAGS_USERMOD)
LDFLAGS_MOD += $(LDFLAGS_USERMOD)
endif
# py object files
PY_CORE_O_BASENAME = $(addprefix py/,\
mpstate.o \
nlr.o \
nlrx86.o \
nlrx64.o \
nlrthumb.o \
2014-11-27 15:29:33 -05:00
nlrxtensa.o \
nlrsetjmp.o \
malloc.o \
gc.o \
py: Introduce a Python stack for scoped allocation. This patch introduces the MICROPY_ENABLE_PYSTACK option (disabled by default) which enables a "Python stack" that allows to allocate and free memory in a scoped, or Last-In-First-Out (LIFO) way, similar to alloca(). A new memory allocation API is introduced along with this Py-stack. It includes both "local" and "nonlocal" LIFO allocation. Local allocation is intended to be equivalent to using alloca(), whereby the same function must free the memory. Nonlocal allocation is where another function may free the memory, so long as it's still LIFO. Follow-up patches will convert all uses of alloca() and VLA to the new scoped allocation API. The old behaviour (using alloca()) will still be available, but when MICROPY_ENABLE_PYSTACK is enabled then alloca() is no longer required or used. The benefits of enabling this option are (or will be once subsequent patches are made to convert alloca()/VLA): - Toolchains without alloca() can use this feature to obtain correct and efficient scoped memory allocation (compared to using the heap instead of alloca(), which is slower). - Even if alloca() is available, enabling the Py-stack gives slightly more efficient use of stack space when calling nested Python functions, due to the way that compilers implement alloca(). - Enabling the Py-stack with the stackless mode allows for even more efficient stack usage, as well as retaining high performance (because the heap is no longer used to build and destroy stackless code states). - With Py-stack and stackless enabled, Python-calling-Python is no longer recursive in the C mp_execute_bytecode function. The micropython.pystack_use() function is included to measure usage of the Python stack.
2017-11-26 07:28:40 -05:00
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 \
2014-08-16 16:55:53 -04:00
asmarm.o \
emitnarm.o \
asmxtensa.o \
emitnxtensa.o \
emitinlinextensa.o \
formatfloat.o \
parsenumbase.o \
parsenum.o \
emitglue.o \
persistentcode.o \
runtime.o \
runtime_utils.o \
scheduler.o \
nativeglue.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 \
2014-01-14 18:55:01 -05:00
objenumerate.o \
objexcept.o \
2014-01-14 20:37:08 -05:00
objfilter.o \
objfloat.o \
objfun.o \
objgenerator.o \
objgetitemiter.o \
objint.o \
objint_longlong.o \
objint_mpz.o \
objlist.o \
2014-01-14 20:10:09 -05:00
objmap.o \
objmodule.o \
2014-03-22 17:31:28 -04:00
objobject.o \
objpolyiter.o \
objproperty.o \
objnone.o \
objnamedtuple.o \
objrange.o \
objreversed.o \
objset.o \
objsingleton.o \
objslice.o \
objstr.o \
objstrunicode.o \
2014-04-26 13:26:14 -04:00
objstringio.o \
objtuple.o \
objtype.o \
objzip.o \
opmethods.o \
sequence.o \
stream.o \
binary.o \
builtinimport.o \
2014-02-03 17:44:10 -05:00
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/moductypes.o \
extmod/modujson.o \
extmod/modure.o \
extmod/moduzlib.o \
extmod/moduheapq.o \
extmod/modutimeq.o \
extmod/moduhashlib.o \
extmod/moducryptolib.o \
extmod/modubinascii.o \
extmod/virtpin.o \
extmod/machine_mem.o \
extmod/machine_pinbase.o \
extmod/machine_signal.o \
extmod/machine_pulse.o \
extmod/machine_i2c.o \
extmod/machine_spi.o \
extmod/modbluetooth.o \
extmod/modussl_axtls.o \
extmod/modussl_mbedtls.o \
extmod/modurandom.o \
extmod/moduselect.o \
extmod/moduwebsocket.o \
extmod/modwebrepl.o \
extmod/modframebuf.o \
extmod/vfs.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/utime_mphal.o \
extmod/uos_dupterm.o \
lib/embed/abort_.o \
lib/utils/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 files
ifneq ($(FROZEN_DIR),)
PY_O += $(BUILD)/$(BUILD)/frozen.o
endif
# object file for frozen bytecode (frozen .mpy files)
ifneq ($(FROZEN_MPY_DIR),)
PY_O += $(BUILD)/$(BUILD)/frozen_mpy.o
endif
# Sources that may contain qstrings
SRC_QSTR_IGNORE = py/nlr%
SRC_QSTR += $(SRC_MOD) $(filter-out $(SRC_QSTR_IGNORE),$(PY_CORE_O_BASENAME:.o=.c)) $(PY_EXTMOD_O_BASENAME:.o=.c)
2014-04-03 19:32:58 -04:00
# 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 $@
2014-04-03 19:32:58 -04:00
# 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 > $@
# 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) > $@
SRC_QSTR += $(HEADER_BUILD)/moduledefs.h
# 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.
2018-11-30 16:23:53 -05:00
# 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