summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstijn <stijn@ignitron.net>2020-10-08 16:52:25 +0200
committerDamien George <damien@micropython.org>2020-10-29 15:29:50 +1100
commitfad4079778f46bc21dd19a674b31b4c3c7eb6a91 (patch)
tree1a25658b8ad160b4e783806a1bbe3cd86cc65115
parent0153148fd26308e4ce921a4287ac4a26af15a9fe (diff)
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++.
-rw-r--r--.travis.yml2
-rw-r--r--ports/esp32/Makefile8
-rw-r--r--ports/unix/Makefile15
-rw-r--r--ports/unix/coveragecpp.cpp23
-rw-r--r--ports/unix/main.c2
-rw-r--r--tests/unix/extra_coverage.py3
-rw-r--r--tests/unix/extra_coverage.py.exp1
7 files changed, 50 insertions, 4 deletions
diff --git a/.travis.yml b/.travis.yml
index c9fcc2133..3b399804e 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 94374eb1c..756bc8f89 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 7380e5e41..3388d67a2 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 000000000..ea7418e1d
--- /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 0fe492a55..6f85cbf8d 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 36105f6ba..1c028506e 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 7d7b7dd9f..514ff9437 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