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++.
This commit is contained in:
stijn 2020-10-08 16:52:25 +02:00 committed by Damien George
parent 0153148fd2
commit fad4079778
7 changed files with 50 additions and 4 deletions

View File

@ -165,7 +165,7 @@ jobs:
- stage: test - stage: test
name: "unix coverage 32-bit build and tests" name: "unix coverage 32-bit build and tests"
install: 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 apt-get install python3-pip
- sudo pip3 install setuptools - sudo pip3 install setuptools
- sudo pip3 install pyelftools - sudo pip3 install pyelftools

View File

@ -268,7 +268,7 @@ CFLAGS += -DMICROPY_ESP_IDF_4=1
endif endif
# this is what ESPIDF uses for c++ compilation # 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 = -nostdlib -Map=$(@:.elf=.map) --cref
LDFLAGS += --gc-sections -static -EL LDFLAGS += --gc-sections -static -EL
@ -354,6 +354,9 @@ SRC_C = \
$(wildcard $(BOARD_DIR)/*.c) \ $(wildcard $(BOARD_DIR)/*.c) \
$(SRC_MOD) $(SRC_MOD)
SRC_CXX += \
$(SRC_MOD_CXX)
EXTMOD_SRC_C += $(addprefix extmod/,\ EXTMOD_SRC_C += $(addprefix extmod/,\
modonewire.c \ modonewire.c \
) )
@ -376,6 +379,7 @@ DRIVERS_SRC_C = $(addprefix drivers/,\
OBJ_MP = OBJ_MP =
OBJ_MP += $(PY_O) OBJ_MP += $(PY_O)
OBJ_MP += $(addprefix $(BUILD)/, $(SRC_C:.c=.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)/, $(EXTMOD_SRC_C:.c=.o))
OBJ_MP += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) OBJ_MP += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o))
OBJ_MP += $(addprefix $(BUILD)/, $(DRIVERS_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 $(OBJ_MP): CFLAGS += -Wdouble-promotion -Wfloat-conversion
# List of sources for qstr extraction # 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 # Append any auto-generated sources that are needed by sources listed in SRC_QSTR
SRC_QSTR_AUTO_DEPS += SRC_QSTR_AUTO_DEPS +=

View File

@ -248,13 +248,18 @@ LIB_SRC_C += $(addprefix lib/,\
utils/gchelper_generic.c \ utils/gchelper_generic.c \
) )
SRC_CXX += \
coveragecpp.cpp \
$(SRC_MOD_CXX)
OBJ = $(PY_O) OBJ = $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.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)/, $(LIB_SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o))
# List of sources for qstr extraction # 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 # Append any auto-generated sources that are needed by sources listed in
# SRC_QSTR # SRC_QSTR
SRC_QSTR_AUTO_DEPS += SRC_QSTR_AUTO_DEPS +=
@ -272,6 +277,14 @@ ifneq ($(FROZEN_MANIFEST)$(FROZEN_DIR),)
CFLAGS += -DMICROPY_MODULE_FROZEN_STR CFLAGS += -DMICROPY_MODULE_FROZEN_STR
endif 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) ifeq ($(MICROPY_FORCE_32BIT),1)
RUN_TESTS_MPY_CROSS_FLAGS = --mpy-cross-flags='-mcache-lookup-bc -march=x86' RUN_TESTS_MPY_CROSS_FLAGS = --mpy-cross-flags='-mcache-lookup-bc -march=x86'
else else

View File

@ -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

View File

@ -531,7 +531,9 @@ MP_NOINLINE int main_(int argc, char **argv) {
#if defined(MICROPY_UNIX_COVERAGE) #if defined(MICROPY_UNIX_COVERAGE)
{ {
MP_DECLARE_CONST_FUN_OBJ_0(extra_coverage_obj); 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_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 #endif

View File

@ -46,6 +46,9 @@ stream.set_error(uerrno.EAGAIN)
buf = uio.BufferedWriter(stream, 8) buf = uio.BufferedWriter(stream, 8)
print(buf.write(bytearray(16))) print(buf.write(bytearray(16)))
# function defined in C++ code
print("cpp", extra_cpp_coverage())
# test basic import of frozen scripts # test basic import of frozen scripts
import frzstr1 import frzstr1

View File

@ -144,6 +144,7 @@ OSError
0 0
None None
None None
cpp None
frzstr1 frzstr1
frzstr1.py frzstr1.py
frzmpy1 frzmpy1