1# Select the variant to build for. 2VARIANT ?= standard 3 4# If the build directory is not given, make it reflect the variant name. 5BUILD ?= build-$(VARIANT) 6 7VARIANT_DIR ?= variants/$(VARIANT) 8ifeq ($(wildcard $(VARIANT_DIR)/.),) 9$(error Invalid VARIANT specified: $(VARIANT_DIR)) 10endif 11 12include ../../py/mkenv.mk 13-include mpconfigport.mk 14include $(VARIANT_DIR)/mpconfigvariant.mk 15 16# use FROZEN_MANIFEST for new projects, others are legacy 17FROZEN_MANIFEST ?= variants/manifest.py 18FROZEN_DIR = 19FROZEN_MPY_DIR = 20 21# This should be configured by the mpconfigvariant.mk 22PROG ?= micropython 23 24# qstr definitions (must come before including py.mk) 25QSTR_DEFS = qstrdefsport.h 26QSTR_GLOBAL_DEPENDENCIES = $(VARIANT_DIR)/mpconfigvariant.h 27 28# OS name, for simple autoconfig 29UNAME_S := $(shell uname -s) 30 31# include py core make definitions 32include $(TOP)/py/py.mk 33 34GIT_SUBMODULES += lib/axtls lib/berkeley-db-1.xx lib/libffi 35 36INC += -I. 37INC += -I$(TOP) 38INC += -I$(BUILD) 39 40# compiler settings 41CWARN = -Wall 42CWARN += -Wextra -Wno-unused-parameter -Wpointer-arith -Wdouble-promotion -Wfloat-conversion 43CFLAGS += $(INC) $(CWARN) -std=gnu99 -DUNIX $(CFLAGS_MOD) $(COPT) -I$(VARIANT_DIR) $(CFLAGS_EXTRA) 44 45# Debugging/Optimization 46ifdef DEBUG 47COPT ?= -O0 48else 49COPT ?= -Os 50COPT += -DNDEBUG 51endif 52 53# Remove unused sections. 54COPT += -fdata-sections -ffunction-sections 55 56# Always enable symbols -- They're occasionally useful, and don't make it into the 57# final .bin/.hex/.dfu so the extra size doesn't matter. 58CFLAGS += -g 59 60ifndef DEBUG 61# _FORTIFY_SOURCE is a feature in gcc/glibc which is intended to provide extra 62# security for detecting buffer overflows. Some distros (Ubuntu at the very least) 63# have it enabled by default. 64# 65# gcc already optimizes some printf calls to call puts and/or putchar. When 66# _FORTIFY_SOURCE is enabled and compiling with -O1 or greater, then some 67# printf calls will also be optimized to call __printf_chk (in glibc). Any 68# printfs which get redirected to __printf_chk are then no longer synchronized 69# with printfs that go through mp_printf. 70# 71# In MicroPython, we don't want to use the runtime library's printf but rather 72# go through mp_printf, so that stdout is properly tied into streams, etc. 73# This means that we either need to turn off _FORTIFY_SOURCE or provide our 74# own implementation of __printf_chk. We've chosen to turn off _FORTIFY_SOURCE. 75# It should also be noted that the use of printf in MicroPython is typically 76# quite limited anyways (primarily for debug and some error reporting, etc 77# in the unix version). 78# 79# Information about _FORTIFY_SOURCE seems to be rather scarce. The best I could 80# find was this: https://securityblog.redhat.com/2014/03/26/fortify-and-you/ 81# Original patchset was introduced by 82# https://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html . 83# 84# Turning off _FORTIFY_SOURCE is only required when compiling with -O1 or greater 85CFLAGS += -U _FORTIFY_SOURCE 86endif 87 88# On OSX, 'gcc' is a symlink to clang unless a real gcc is installed. 89# The unix port of MicroPython on OSX must be compiled with clang, 90# while cross-compile ports require gcc, so we test here for OSX and 91# if necessary override the value of 'CC' set in py/mkenv.mk 92ifeq ($(UNAME_S),Darwin) 93ifeq ($(MICROPY_FORCE_32BIT),1) 94CC = clang -m32 95else 96CC = clang 97endif 98# Use clang syntax for map file 99LDFLAGS_ARCH = -Wl,-map,$@.map -Wl,-dead_strip 100else 101# Use gcc syntax for map file 102LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref -Wl,--gc-sections 103endif 104LDFLAGS += $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA) 105 106# Flags to link with pthread library 107LIBPTHREAD = -lpthread 108 109ifeq ($(MICROPY_FORCE_32BIT),1) 110# Note: you may need to install i386 versions of dependency packages, 111# starting with linux-libc-dev:i386 112ifeq ($(MICROPY_PY_FFI),1) 113ifeq ($(UNAME_S),Linux) 114CFLAGS_MOD += -I/usr/include/i686-linux-gnu 115endif 116endif 117endif 118 119ifeq ($(MICROPY_USE_READLINE),1) 120INC += -I$(TOP)/shared/readline 121CFLAGS_MOD += -DMICROPY_USE_READLINE=1 122SHARED_SRC_C_EXTRA += readline/readline.c 123endif 124ifeq ($(MICROPY_PY_TERMIOS),1) 125CFLAGS_MOD += -DMICROPY_PY_TERMIOS=1 126SRC_MOD += modtermios.c 127endif 128ifeq ($(MICROPY_PY_SOCKET),1) 129CFLAGS_MOD += -DMICROPY_PY_SOCKET=1 130SRC_MOD += modusocket.c 131endif 132ifeq ($(MICROPY_PY_THREAD),1) 133CFLAGS_MOD += -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=0 134LDFLAGS_MOD += $(LIBPTHREAD) 135endif 136 137# If the variant enables it, enable modbluetooth. 138ifeq ($(MICROPY_PY_BLUETOOTH),1) 139 140HAVE_LIBUSB := $(shell (which pkg-config > /dev/null && pkg-config --exists libusb-1.0) 2>/dev/null && echo '1') 141 142# Only one stack can be enabled. 143ifeq ($(MICROPY_BLUETOOTH_NIMBLE),1) 144ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1) 145$(error Cannot enable both NimBLE and BTstack at the same time) 146endif 147endif 148 149# Default to btstack, but a variant (or make command line) can set NimBLE 150# explicitly (which is always via H4 UART). 151ifneq ($(MICROPY_BLUETOOTH_NIMBLE),1) 152ifneq ($(MICROPY_BLUETOOTH_BTSTACK),1) 153MICROPY_BLUETOOTH_BTSTACK ?= 1 154endif 155endif 156 157CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH=1 158CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE=1 159 160ifeq ($(MICROPY_BLUETOOTH_BTSTACK),1) 161 162# Figure out which BTstack transport to use. 163ifeq ($(MICROPY_BLUETOOTH_BTSTACK_H4),1) 164ifeq ($(MICROPY_BLUETOOTH_BTSTACK_USB),1) 165$(error Cannot enable BTstack support for USB and H4 UART at the same time) 166endif 167else 168ifeq ($(HAVE_LIBUSB),1) 169# Default to btstack-over-usb. 170MICROPY_BLUETOOTH_BTSTACK_USB ?= 1 171else 172# Fallback to HCI controller via a H4 UART (e.g. Zephyr on nRF) over a /dev/tty serial port. 173MICROPY_BLUETOOTH_BTSTACK_H4 ?= 1 174endif 175endif 176 177# BTstack is enabled. 178GIT_SUBMODULES += lib/btstack 179include $(TOP)/extmod/btstack/btstack.mk 180SRC_BTSTACK += lib/btstack/platform/embedded/btstack_run_loop_embedded.c 181 182else 183 184# NimBLE is enabled. 185GIT_SUBMODULES += lib/mynewt-nimble 186CFLAGS_MOD += -DMICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS=1 187include $(TOP)/extmod/nimble/nimble.mk 188 189endif 190 191endif 192 193ifeq ($(MICROPY_PY_FFI),1) 194 195ifeq ($(MICROPY_STANDALONE),1) 196LIBFFI_CFLAGS_MOD := -I$(shell ls -1d $(BUILD)/lib/libffi/out/lib/libffi-*/include) 197 ifeq ($(MICROPY_FORCE_32BIT),1) 198 LIBFFI_LDFLAGS_MOD = $(BUILD)/lib/libffi/out/lib32/libffi.a 199 else 200 LIBFFI_LDFLAGS_MOD = $(BUILD)/lib/libffi/out/lib/libffi.a 201 endif 202else 203LIBFFI_CFLAGS_MOD := $(shell pkg-config --cflags libffi) 204LIBFFI_LDFLAGS_MOD := $(shell pkg-config --libs libffi) 205endif 206 207ifeq ($(UNAME_S),Linux) 208LIBFFI_LDFLAGS_MOD += -ldl 209endif 210 211CFLAGS_MOD += $(LIBFFI_CFLAGS_MOD) -DMICROPY_PY_FFI=1 212LDFLAGS_MOD += $(LIBFFI_LDFLAGS_MOD) 213SRC_MOD += modffi.c 214endif 215 216ifeq ($(MICROPY_PY_JNI),1) 217# Path for 64-bit OpenJDK, should be adjusted for other JDKs 218CFLAGS_MOD += -I/usr/lib/jvm/java-7-openjdk-amd64/include -DMICROPY_PY_JNI=1 219SRC_MOD += modjni.c 220endif 221 222# source files 223SRC_C += \ 224 main.c \ 225 gccollect.c \ 226 unix_mphal.c \ 227 mpthreadport.c \ 228 input.c \ 229 modmachine.c \ 230 modos.c \ 231 moduos_vfs.c \ 232 modtime.c \ 233 moduselect.c \ 234 alloc.c \ 235 fatfs_port.c \ 236 mpbthciport.c \ 237 mpbtstackport_common.c \ 238 mpbtstackport_h4.c \ 239 mpbtstackport_usb.c \ 240 mpnimbleport.c \ 241 $(SRC_MOD) \ 242 $(wildcard $(VARIANT_DIR)/*.c) 243 244SHARED_SRC_C += $(addprefix shared/,\ 245 runtime/gchelper_generic.c \ 246 timeutils/timeutils.c \ 247 $(SHARED_SRC_C_EXTRA) \ 248 ) 249 250SRC_CXX += \ 251 $(SRC_MOD_CXX) 252 253OBJ = $(PY_O) 254OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) 255OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) 256OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o)) 257OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o)) 258OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) 259 260# List of sources for qstr extraction 261SRC_QSTR += $(SRC_C) $(SRC_CXX) $(SHARED_SRC_C) $(EXTMOD_SRC_C) 262# Append any auto-generated sources that are needed by sources listed in 263# SRC_QSTR 264SRC_QSTR_AUTO_DEPS += 265 266ifneq ($(FROZEN_MANIFEST)$(FROZEN_MPY_DIR),) 267# To use frozen code create a manifest.py file with a description of files to 268# freeze, then invoke make with FROZEN_MANIFEST=manifest.py (be sure to build from scratch). 269CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool 270CFLAGS += -DMICROPY_MODULE_FROZEN_MPY 271CFLAGS += -DMPZ_DIG_SIZE=16 # force 16 bits to work on both 32 and 64 bit archs 272MPY_CROSS_FLAGS += -mcache-lookup-bc 273endif 274 275ifneq ($(FROZEN_MANIFEST)$(FROZEN_DIR),) 276CFLAGS += -DMICROPY_MODULE_FROZEN_STR 277endif 278 279HASCPP17 = $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 7) 280ifeq ($(HASCPP17), 1) 281 CXXFLAGS += -std=c++17 282else 283 CXXFLAGS += -std=c++11 284endif 285CXXFLAGS += $(filter-out -Wmissing-prototypes -Wold-style-definition -std=gnu99,$(CFLAGS) $(CXXFLAGS_MOD)) 286 287ifeq ($(MICROPY_FORCE_32BIT),1) 288RUN_TESTS_MPY_CROSS_FLAGS = --mpy-cross-flags='-mcache-lookup-bc -march=x86' 289else 290RUN_TESTS_MPY_CROSS_FLAGS = --mpy-cross-flags='-mcache-lookup-bc' 291endif 292 293ifeq ($(CROSS_COMPILE),arm-linux-gnueabi-) 294# Force disable error text compression when compiling for ARM as the compiler 295# cannot optimise out the giant strcmp list generated for MP_MATCH_COMPRESSED. 296# Checked on: 297# arm-linux-gnueabi-gcc (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0 298# arm-linux-gnueabi-gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 299# See https://github.com/micropython/micropython/pull/7659 for details. 300$(info Detected arm-linux-gnueabi-gcc. Disabling error message compression.) 301MICROPY_ROM_TEXT_COMPRESSION = 0 302endif 303 304include $(TOP)/py/mkrules.mk 305 306.PHONY: test test_full 307 308test: $(PROG) $(TOP)/tests/run-tests.py 309 $(eval DIRNAME=ports/$(notdir $(CURDIR))) 310 cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py 311 312test_full: $(PROG) $(TOP)/tests/run-tests.py 313 $(eval DIRNAME=ports/$(notdir $(CURDIR))) 314 cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py 315 cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py -d thread 316 cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py --emit native 317 cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) -d basics float micropython 318 cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) --emit native -d basics float micropython 319 cat $(TOP)/tests/basics/0prelim.py | ./$(PROG) | grep -q 'abc' 320 321test_gcov: test_full 322 gcov -o $(BUILD)/py $(TOP)/py/*.c 323 gcov -o $(BUILD)/extmod $(TOP)/extmod/*.c 324 325# Value of configure's --host= option (required for cross-compilation). 326# Deduce it from CROSS_COMPILE by default, but can be overridden. 327ifneq ($(CROSS_COMPILE),) 328CROSS_COMPILE_HOST = --host=$(patsubst %-,%,$(CROSS_COMPILE)) 329else 330CROSS_COMPILE_HOST = 331endif 332 333deplibs: libffi axtls 334 335libffi: $(BUILD)/lib/libffi/include/ffi.h 336 337$(TOP)/lib/libffi/configure: $(TOP)/lib/libffi/autogen.sh 338 cd $(TOP)/lib/libffi; ./autogen.sh 339 340# install-exec-recursive & install-data-am targets are used to avoid building 341# docs and depending on makeinfo 342$(BUILD)/lib/libffi/include/ffi.h: $(TOP)/lib/libffi/configure 343 mkdir -p $(BUILD)/lib/libffi; cd $(BUILD)/lib/libffi; \ 344 $(abspath $(TOP))/lib/libffi/configure $(CROSS_COMPILE_HOST) --prefix=$$PWD/out --disable-structs CC="$(CC)" CXX="$(CXX)" LD="$(LD)" CFLAGS="-Os -fomit-frame-pointer -fstrict-aliasing -ffast-math -fno-exceptions"; \ 345 $(MAKE) install-exec-recursive; $(MAKE) -C include install-data-am 346 347axtls: $(TOP)/lib/axtls/README 348 349$(TOP)/lib/axtls/README: 350 @echo "You cloned without --recursive, fetching submodules for you." 351 (cd $(TOP); git submodule update --init --recursive) 352 353PREFIX = /usr/local 354BINDIR = $(DESTDIR)$(PREFIX)/bin 355 356install: $(PROG) 357 install -d $(BINDIR) 358 install $(PROG) $(BINDIR)/$(PROG) 359 360uninstall: 361 -rm $(BINDIR)/$(PROG) 362