diff --git a/ports/webassembly/Makefile b/ports/webassembly/Makefile index 4e1d53b0cc..e8f27d862b 100644 --- a/ports/webassembly/Makefile +++ b/ports/webassembly/Makefile @@ -1,23 +1,67 @@ +################################################################################ +# Initial setup of Makefile environment. + +# Select the variant to build for: +ifdef VARIANT_DIR +# Custom variant path - remove trailing slash and get the final component of +# the path as the variant name. +VARIANT ?= $(notdir $(VARIANT_DIR:/=)) +else +# If not given on the command line, then default to standard. +VARIANT ?= standard +VARIANT_DIR ?= variants/$(VARIANT) +endif + +ifeq ($(wildcard $(VARIANT_DIR)/.),) +$(error Invalid VARIANT specified: $(VARIANT_DIR)) +endif + +# If the build directory is not given, make it reflect the variant name. +BUILD ?= build-$(VARIANT) + include ../../py/mkenv.mk +include $(VARIANT_DIR)/mpconfigvariant.mk -CROSS = 0 - +# Qstr definitions (must come before including py.mk). QSTR_DEFS = qstrdefsport.h +# Include py core make definitions. include $(TOP)/py/py.mk include $(TOP)/extmod/extmod.mk +################################################################################ +# Project specific settings and compiler/linker flags. + CC = emcc LD = emcc +TERSER ?= npx terser INC += -I. INC += -I$(TOP) INC += -I$(BUILD) +INC += -I$(VARIANT_DIR) CFLAGS += -std=c99 -Wall -Werror -Wdouble-promotion -Wfloat-conversion CFLAGS += -Os -DNDEBUG CFLAGS += $(INC) +JSFLAGS += -s EXPORTED_FUNCTIONS="\ + _mp_js_init,\ + _mp_js_init_repl,\ + _mp_js_do_str,\ + _mp_js_process_char,\ + _mp_hal_get_interrupt_char,\ + _mp_sched_keyboard_interrupt$(EXPORTED_FUNCTIONS_EXTRA)" +JSFLAGS += -s EXPORTED_RUNTIME_METHODS="\ + ccall,\ + cwrap,\ + FS$(EXPORTED_RUNTIME_METHODS_EXTRA)" +JSFLAGS += --js-library library.js +JSFLAGS += -s SUPPORT_LONGJMP=emscripten + +################################################################################ +# Source files and libraries. + SRC_SHARED = $(addprefix shared/,\ runtime/interrupt_char.c \ runtime/stdout_helpers.c \ @@ -26,33 +70,41 @@ SRC_SHARED = $(addprefix shared/,\ timeutils/timeutils.c \ ) -SRC_C = \ +SRC_C += \ main.c \ mphalport.c \ +# List of sources for qstr extraction. SRC_QSTR += $(SRC_C) $(SRC_SHARED) +SRC_JS ?= wrapper.js + OBJ += $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) -JSFLAGS += -s ASYNCIFY -JSFLAGS += -s EXPORTED_FUNCTIONS="['_mp_js_init', '_mp_js_init_repl', '_mp_js_do_str', '_mp_js_process_char', '_mp_hal_get_interrupt_char', '_mp_sched_keyboard_interrupt']" -JSFLAGS += -s EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap', 'FS']" -JSFLAGS += --js-library library.js +################################################################################ +# Main targets. + +.PHONY: all min test all: $(BUILD)/micropython.js -$(BUILD)/micropython.js: $(OBJ) library.js wrapper.js - $(ECHO) "LINK $(BUILD)/firmware.js" - $(Q)emcc $(LDFLAGS) -o $(BUILD)/firmware.js $(OBJ) $(JSFLAGS) - cat wrapper.js $(BUILD)/firmware.js > $@ +$(BUILD)/micropython.js: $(OBJ) library.js $(SRC_JS) + $(ECHO) "LINK $@" + $(Q)emcc $(LDFLAGS) -o $@ $(OBJ) $(JSFLAGS) + $(Q)cat $(SRC_JS) >> $@ -min: $(BUILD)/micropython.js - uglifyjs $< -c -o $(BUILD)/micropython.min.js +$(BUILD)/micropython.min.js: $(BUILD)/micropython.js + $(TERSER) $< --compress --module -o $@ + +min: $(BUILD)/micropython.min.js test: $(BUILD)/micropython.js $(TOP)/tests/run-tests.py $(eval DIRNAME=ports/$(notdir $(CURDIR))) cd $(TOP)/tests && MICROPY_MICROPYTHON=../ports/webassembly/node_run.sh ./run-tests.py -j1 +################################################################################ +# Remaining make rules. + include $(TOP)/py/mkrules.mk diff --git a/ports/webassembly/mpconfigport.h b/ports/webassembly/mpconfigport.h index d026136239..abfbbca794 100644 --- a/ports/webassembly/mpconfigport.h +++ b/ports/webassembly/mpconfigport.h @@ -25,17 +25,18 @@ * THE SOFTWARE. */ +// Options to control how MicroPython is built for this port, overriding +// defaults in py/mpconfig.h. + #include #include // for malloc, for MICROPY_GC_SPLIT_HEAP_AUTO -// options to control how MicroPython is built +// Variant-specific definitions. +#include "mpconfigvariant.h" +#ifndef MICROPY_CONFIG_ROM_LEVEL #define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES) - -// You can disable the built-in MicroPython compiler by setting the following -// config option to 0. If you do this then you won't get a REPL prompt, but you -// will still be able to execute pre-compiled scripts, compiled with mpy-cross. -#define MICROPY_ENABLE_COMPILER (1) +#endif #define MICROPY_ALLOC_PATH_MAX (256) #define MICROPY_READER_VFS (MICROPY_VFS) @@ -69,6 +70,13 @@ mp_handle_pending(true); \ } while (0); +// Whether the VM will periodically call mp_js_hook(), which checks for +// interrupt characters on stdin (or equivalent input). +#ifndef MICROPY_VARIANT_ENABLE_JS_HOOK +#define MICROPY_VARIANT_ENABLE_JS_HOOK (0) +#endif + +#if MICROPY_VARIANT_ENABLE_JS_HOOK #define MICROPY_VM_HOOK_COUNT (10) #define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT; #define MICROPY_VM_HOOK_POLL if (--vm_hook_divisor == 0) { \ @@ -78,6 +86,7 @@ } #define MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_POLL #define MICROPY_VM_HOOK_RETURN MICROPY_VM_HOOK_POLL +#endif // type definitions for the specific machine diff --git a/ports/webassembly/variants/standard/mpconfigvariant.h b/ports/webassembly/variants/standard/mpconfigvariant.h new file mode 100644 index 0000000000..7be62ea7f4 --- /dev/null +++ b/ports/webassembly/variants/standard/mpconfigvariant.h @@ -0,0 +1 @@ +#define MICROPY_VARIANT_ENABLE_JS_HOOK (1) diff --git a/ports/webassembly/variants/standard/mpconfigvariant.mk b/ports/webassembly/variants/standard/mpconfigvariant.mk new file mode 100644 index 0000000000..62ee161907 --- /dev/null +++ b/ports/webassembly/variants/standard/mpconfigvariant.mk @@ -0,0 +1 @@ +JSFLAGS += -s ASYNCIFY