Skip to content

Commit

Permalink
[c++] Add option to use C++ Exceptions and RTTI
Browse files Browse the repository at this point in the history
  • Loading branch information
salkinium committed Mar 11, 2020
1 parent 811670e commit f00e789
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 10 deletions.
30 changes: 30 additions & 0 deletions ext/gcc/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ def prepare(module, options):
name="use_modm_assert", default=True,
description="Assert on exception in stdlib. Set to False to save flash."))

elif is_cortex_m:
module.add_option(
BooleanOption(
name="exceptions", default=False,
description=descr_exceptions))
module.add_option(
BooleanOption(
name="rtti", default=False,
description=descr_rtti))

module.depends(":architecture:assert",
":architecture:memory")

Expand All @@ -62,3 +72,23 @@ def build(env):
env.copy("libcabi_cortex.cpp", "libcabi.cpp")
env.copy("cxxabi_cortex.cpp", "cxxabi.cpp")
env.copy("newdelete_cortex.cpp", "newdelete.cpp")

# ============================ Option Descriptions ============================

descr_exceptions = """# C++ Exceptions
Enables the full use of C++ exception handling.
!!! warning "Check your code size"
The inclusion of the stack unwind tables will increase your code size quite
a bit. Check whether your target has enough code memory this!
"""

descr_rtti = """# C++ Runtime Type Information
Enables the full use of C++ runtime type information.
!!! warning "Check your code size"
The inclusion of the RTTI tables will increase your code size quite
a bit. Check whether your target has enough code memory this!
"""
2 changes: 1 addition & 1 deletion src/modm/platform/core/cortex/linker.macros
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ TOTAL_STACK_SIZE = MAIN_STACK_SIZE + PROCESS_STACK_SIZE;
%% endif
} >{{memory}}

%% if 0
%% if with_cpp_exceptions
.ARM.extab : ALIGN(4)
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
Expand Down
2 changes: 2 additions & 0 deletions src/modm/platform/core/cortex/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ def common_linkerscript(env):
env.collector_values(":platform:cortex-m:linkerscript.table_extern.copy")]),
"linkerscript_extern_heap": "\n".join([m.strip() for m in
env.collector_values(":platform:cortex-m:linkerscript.table_extern.heap")]),

"with_cpp_exceptions": env.get(":stdc++:exceptions", False),
}
properties.update(common_memories(env))
return properties
Expand Down
50 changes: 42 additions & 8 deletions tools/build_script_generator/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import os, re
import itertools
from collections import defaultdict
from enum import IntFlag

common_build_flags = {
"ccflags": ("Compiler flags for both C and C++ sources",
Expand Down Expand Up @@ -181,8 +182,23 @@ def common_collect_flags_for_scope(env, scope_filter=None):
return flags


def common_compiler_flags(compiler, target):
class CompilerFeature(IntFlag):
CPP_EXCEPTIONS = 1
CPP_RTTI = 2

def common_compiler_flags(compiler, target, features=None):
"""
Returns the compile flags for a given compiler, target and set of features
in the form: `flags[name(.profile)] = list(compiler flags)`.
:param compiler: Currently supports only "GCC"
:param target: the target identifier
:param features: CompilerFeatures IntFlags
:returns: compiler flags dictionary
"""
if features is None: features = CompilerFeature(0);
flags = defaultdict(list)

# flags for C **and** C++
flags["ccflags"] = [
"-W",
Expand Down Expand Up @@ -250,6 +266,26 @@ def common_compiler_flags(compiler, target):
"-std=c++17",
# "-pedantic",
]
# C++ exceptions?
if features & CompilerFeature.CPP_EXCEPTIONS:
flags["cxxflags"] += [
"-fexceptions",
"-funwind-tables",
]
else:
flags["cxxflags"] += [
"-fno-exceptions",
"-fno-unwind-tables",
]
# C++ RTTI?
if features & CompilerFeature.CPP_RTTI:
flags["cxxflags"] += [
"-frtti"
]
else:
flags["cxxflags"] += [
"-fno-rtti"
]
# flags only for Assembly
flags["asflags"] = [
"-g3",
Expand Down Expand Up @@ -300,9 +336,6 @@ def common_compiler_flags(compiler, target):
"-Wdouble-promotion",
]
flags["cxxflags"] += [
"-fno-exceptions",
"-fno-unwind-tables",
"-fno-rtti",
"-fno-threadsafe-statics",
"-fuse-cxa-atexit",
]
Expand All @@ -312,12 +345,16 @@ def common_compiler_flags(compiler, target):
"-Wl,-wrap,_free_r",
"-Wl,-wrap,_malloc_r",
"-Wl,-wrap,_realloc_r",
"--specs=nano.specs",
"--specs=nosys.specs",
"-nostartfiles",
"-L{linkdir}",
"-Tlinkerscript.ld",
]
# Newlib Nano does not support C++ exceptions at all
if not (features & CompilerFeature.CPP_EXCEPTIONS):
flags["linkflags"] += [
"--specs=nano.specs",
]

elif core.startswith("avr"):
# avr-gcc only accepts certain device strings for its -mmcu flag
Expand All @@ -330,9 +367,6 @@ def common_compiler_flags(compiler, target):
"-mmcu={}".format(mmcu),
]
flags["cxxflags"] += [
"-fno-exceptions",
"-fno-unwind-tables",
"-fno-rtti",
"-fno-threadsafe-statics",
]
flags["linkflags"] += [
Expand Down
11 changes: 10 additions & 1 deletion tools/build_script_generator/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,17 @@ def build(env):
if env.has_collector(":build:path.openocd"):
env.collect(":build:path.openocd", "modm/openocd")

# Assemble require compile features
if env[":target"].identifier.platform == "hosted":
compiler_features = CompilerFeature.CPP_EXCEPTIONS | CompilerFeature.CPP_RTTI
else:
compiler_features = CompilerFeature(0)
if env.get(":stdc++:exceptions", False):
compiler_features |= CompilerFeature.CPP_EXCEPTIONS
if env.get(":stdc++:rtti", False):
compiler_features |= CompilerFeature.CPP_RTTI
# Add compiler flags to metadata
for flag, values in common_compiler_flags("gcc", env[":target"]).items():
for flag, values in common_compiler_flags("gcc", env[":target"], compiler_features).items():
env.collect(flag, *values)

def post_build(env):
Expand Down

0 comments on commit f00e789

Please sign in to comment.