From fad4079778f46bc21dd19a674b31b4c3c7eb6a91 Mon Sep 17 00:00:00 2001 From: stijn Date: Thu, 8 Oct 2020 16:52:25 +0200 Subject: [PATCH] esp32,unix: Support building C++ code. Support building .cpp files and linking them into the micropython executable in a way similar to how it is done for .c files. The main incentive here is to enable user C modules to use C++ files (which are put in SRC_MOD_CXX by py.mk) since the core itself does not utilize C++. However, to verify build functionality a unix overage test is added. The esp32 port already has CXXFLAGS so just add the user modules' flags to it. For the unix port use a copy of the CFLAGS but strip the ones which are not usable for C++. --- .travis.yml | 2 +- ports/esp32/Makefile | 8 ++++++-- ports/unix/Makefile | 15 ++++++++++++++- ports/unix/coveragecpp.cpp | 23 +++++++++++++++++++++++ ports/unix/main.c | 2 ++ tests/unix/extra_coverage.py | 3 +++ tests/unix/extra_coverage.py.exp | 1 + 7 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 ports/unix/coveragecpp.cpp diff --git a/.travis.yml b/.travis.yml index c9fcc21336..3b399804e3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -165,7 +165,7 @@ jobs: - stage: test name: "unix coverage 32-bit build and tests" install: - - sudo apt-get install gcc-multilib libffi-dev:i386 + - sudo apt-get install gcc-multilib g++-multilib libffi-dev:i386 - sudo apt-get install python3-pip - sudo pip3 install setuptools - sudo pip3 install pyelftools diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index 94374eb1c4..756bc8f894 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -268,7 +268,7 @@ CFLAGS += -DMICROPY_ESP_IDF_4=1 endif # this is what ESPIDF uses for c++ compilation -CXXFLAGS = -std=gnu++11 $(CFLAGS_COMMON) $(INC) $(INC_ESPCOMP) +CXXFLAGS = -std=gnu++11 $(CFLAGS_COMMON) $(INC) $(INC_ESPCOMP) $(CXXFLAGS_MOD) LDFLAGS = -nostdlib -Map=$(@:.elf=.map) --cref LDFLAGS += --gc-sections -static -EL @@ -354,6 +354,9 @@ SRC_C = \ $(wildcard $(BOARD_DIR)/*.c) \ $(SRC_MOD) +SRC_CXX += \ + $(SRC_MOD_CXX) + EXTMOD_SRC_C += $(addprefix extmod/,\ modonewire.c \ ) @@ -376,6 +379,7 @@ DRIVERS_SRC_C = $(addprefix drivers/,\ OBJ_MP = OBJ_MP += $(PY_O) OBJ_MP += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ_MP += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) OBJ_MP += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o)) OBJ_MP += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) OBJ_MP += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o)) @@ -384,7 +388,7 @@ OBJ_MP += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o)) $(OBJ_MP): CFLAGS += -Wdouble-promotion -Wfloat-conversion # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(EXTMOD_SRC_C) $(LIB_SRC_C) $(DRIVERS_SRC_C) +SRC_QSTR += $(SRC_C) $(SRC_CXX) $(EXTMOD_SRC_C) $(LIB_SRC_C) $(DRIVERS_SRC_C) # Append any auto-generated sources that are needed by sources listed in SRC_QSTR SRC_QSTR_AUTO_DEPS += diff --git a/ports/unix/Makefile b/ports/unix/Makefile index 7380e5e412..3388d67a2d 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -248,13 +248,18 @@ LIB_SRC_C += $(addprefix lib/,\ utils/gchelper_generic.c \ ) +SRC_CXX += \ + coveragecpp.cpp \ + $(SRC_MOD_CXX) + OBJ = $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o)) # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(LIB_SRC_C) $(EXTMOD_SRC_C) +SRC_QSTR += $(SRC_C) $(SRC_CXX) $(LIB_SRC_C) $(EXTMOD_SRC_C) # Append any auto-generated sources that are needed by sources listed in # SRC_QSTR SRC_QSTR_AUTO_DEPS += @@ -272,6 +277,14 @@ ifneq ($(FROZEN_MANIFEST)$(FROZEN_DIR),) CFLAGS += -DMICROPY_MODULE_FROZEN_STR endif +HASCPP17 = $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 7) +ifeq ($(HASCPP17), 1) + CXXFLAGS += -std=c++17 +else + CXXFLAGS += -std=c++11 +endif +CXXFLAGS += $(filter-out -Wmissing-prototypes -Wold-style-definition -std=gnu99,$(CFLAGS) $(CXXFLAGS_MOD)) + ifeq ($(MICROPY_FORCE_32BIT),1) RUN_TESTS_MPY_CROSS_FLAGS = --mpy-cross-flags='-mcache-lookup-bc -march=x86' else diff --git a/ports/unix/coveragecpp.cpp b/ports/unix/coveragecpp.cpp new file mode 100644 index 0000000000..ea7418e1dd --- /dev/null +++ b/ports/unix/coveragecpp.cpp @@ -0,0 +1,23 @@ +extern "C" { +#include "py/obj.h" +} + +#if defined(MICROPY_UNIX_COVERAGE) + +// Just to test building of C++ code. +STATIC mp_obj_t extra_cpp_coverage_impl() { + return mp_const_none; +} + +extern "C" { +mp_obj_t extra_cpp_coverage(void); +mp_obj_t extra_cpp_coverage(void) { + return extra_cpp_coverage_impl(); +} + +// This is extern to avoid name mangling. +extern const mp_obj_fun_builtin_fixed_t extra_cpp_coverage_obj = {{&mp_type_fun_builtin_0}, {extra_cpp_coverage}}; + +} + +#endif diff --git a/ports/unix/main.c b/ports/unix/main.c index 0fe492a554..6f85cbf8d0 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -531,7 +531,9 @@ MP_NOINLINE int main_(int argc, char **argv) { #if defined(MICROPY_UNIX_COVERAGE) { MP_DECLARE_CONST_FUN_OBJ_0(extra_coverage_obj); + MP_DECLARE_CONST_FUN_OBJ_0(extra_cpp_coverage_obj); mp_store_global(QSTR_FROM_STR_STATIC("extra_coverage"), MP_OBJ_FROM_PTR(&extra_coverage_obj)); + mp_store_global(QSTR_FROM_STR_STATIC("extra_cpp_coverage"), MP_OBJ_FROM_PTR(&extra_cpp_coverage_obj)); } #endif diff --git a/tests/unix/extra_coverage.py b/tests/unix/extra_coverage.py index 36105f6bad..1c028506e3 100644 --- a/tests/unix/extra_coverage.py +++ b/tests/unix/extra_coverage.py @@ -46,6 +46,9 @@ stream.set_error(uerrno.EAGAIN) buf = uio.BufferedWriter(stream, 8) print(buf.write(bytearray(16))) +# function defined in C++ code +print("cpp", extra_cpp_coverage()) + # test basic import of frozen scripts import frzstr1 diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index 7d7b7dd9f9..514ff9437b 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -144,6 +144,7 @@ OSError 0 None None +cpp None frzstr1 frzstr1.py frzmpy1