Browse Source

Build: Improve C++ support

Can choose the C++ standard (C++98/11/14/17/2a)
Can link with standard C++ library (libstdc++)
Add support of C++ exceptions
Add support of C++ RTTI
Add C++ options to subsys/cpp/Kconfig
Implements new and delete using k_malloc and k_free
if CONFIG_HEAP_MEM_POOL_SIZE is defined

Signed-off-by: Benoit Leforestier <benoit.leforestier@gmail.com>
pull/10905/head
Benoit Leforestier 7 years ago committed by Anas Nashif
parent
commit
26e0f9a9e1
  1. 44
      CMakeLists.txt
  2. 55
      include/kernel.h
  3. 6
      misc/Kconfig
  4. 2
      subsys/Kconfig
  5. 1
      subsys/cpp/CMakeLists.txt
  6. 70
      subsys/cpp/Kconfig
  7. 118
      subsys/cpp/cpp_new.cpp

44
CMakeLists.txt

@ -105,6 +105,28 @@ else()
assert(0 "Unreachable code. Expected optimization level to have been chosen. See misc/Kconfig.") assert(0 "Unreachable code. Expected optimization level to have been chosen. See misc/Kconfig.")
endif() endif()
# Dialects of C++, corresponding to the multiple published ISO standards.
# Which standard it implements can be selected using the -std= command-line option.
set_ifndef(DIALECT_STD_CPP98 "c++98")
set_ifndef(DIALECT_STD_CPP11 "c++11")
set_ifndef(DIALECT_STD_CPP14 "c++14")
set_ifndef(DIALECT_STD_CPP17 "c++17")
set_ifndef(DIALECT_STD_CPP2A "c++2a")
if(CONFIG_STD_CPP98)
set(STD_CPP_DIALECT ${DIALECT_STD_CPP98})
elseif(CONFIG_STD_CPP11)
set(STD_CPP_DIALECT ${DIALECT_STD_CPP11}) # Default
elseif(CONFIG_STD_CPP14)
set(STD_CPP_DIALECT ${DIALECT_STD_CPP14})
elseif(CONFIG_STD_CPP17)
set(STD_CPP_DIALECT ${DIALECT_STD_CPP17})
elseif(CONFIG_STD_CPP2A)
set(STD_CPP_DIALECT ${DIALECT_STD_CPP2A})
else()
assert(0 "Unreachable code. Expected C++ standard to have been chosen. See misc/Kconfig.")
endif()
zephyr_compile_options( zephyr_compile_options(
${OPTIMIZATION_FLAG} # Usually -Os ${OPTIMIZATION_FLAG} # Usually -Os
-g # TODO: build configuration enough? -g # TODO: build configuration enough?
@ -120,17 +142,27 @@ zephyr_compile_options(
) )
zephyr_compile_options( zephyr_compile_options(
$<$<COMPILE_LANGUAGE:CXX>:-std=c++11> $<$<COMPILE_LANGUAGE:CXX>:-std=${STD_CPP_DIALECT}>
$<$<COMPILE_LANGUAGE:CXX>:-fcheck-new> $<$<COMPILE_LANGUAGE:CXX>:-fcheck-new>
$<$<COMPILE_LANGUAGE:CXX>:-ffunction-sections> $<$<COMPILE_LANGUAGE:CXX>:-ffunction-sections>
$<$<COMPILE_LANGUAGE:CXX>:-fdata-sections> $<$<COMPILE_LANGUAGE:CXX>:-fdata-sections>
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
$<$<COMPILE_LANGUAGE:ASM>:-xassembler-with-cpp> $<$<COMPILE_LANGUAGE:ASM>:-xassembler-with-cpp>
$<$<COMPILE_LANGUAGE:ASM>:-D_ASMLANGUAGE> $<$<COMPILE_LANGUAGE:ASM>:-D_ASMLANGUAGE>
) )
if(NOT CONFIG_RTTI)
zephyr_compile_options(
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>
)
endif()
if(NOT CONFIG_EXCEPTIONS)
zephyr_compile_options(
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
)
endif()
if(NOT CONFIG_NATIVE_APPLICATION) if(NOT CONFIG_NATIVE_APPLICATION)
zephyr_ld_options( zephyr_ld_options(
-nostartfiles -nostartfiles
@ -141,6 +173,12 @@ zephyr_ld_options(
) )
endif() endif()
if(CONFIG_LIB_CPLUSPLUS)
zephyr_ld_options(
-lstdc++
)
endif()
# ========================================================================== # ==========================================================================
# #
# cmake -DW=... settings # cmake -DW=... settings

55
include/kernel.h

@ -4846,61 +4846,6 @@ extern void _arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz,
} }
#endif #endif
#if defined(CONFIG_CPLUSPLUS) && defined(__cplusplus)
/*
* Define new and delete operators.
* At this moment, the operators do nothing since objects are supposed
* to be statically allocated.
*/
inline void operator delete(void *ptr)
{
(void)ptr;
}
inline void operator delete[](void *ptr)
{
(void)ptr;
}
inline void *operator new(size_t size)
{
(void)size;
return NULL;
}
inline void *operator new[](size_t size)
{
(void)size;
return NULL;
}
/* Placement versions of operator new and delete */
inline void operator delete(void *ptr1, void *ptr2)
{
(void)ptr1;
(void)ptr2;
}
inline void operator delete[](void *ptr1, void *ptr2)
{
(void)ptr1;
(void)ptr2;
}
inline void *operator new(size_t size, void *ptr)
{
(void)size;
return ptr;
}
inline void *operator new[](size_t size, void *ptr)
{
(void)size;
return ptr;
}
#endif /* defined(CONFIG_CPLUSPLUS) && defined(__cplusplus) */
#include <tracing.h> #include <tracing.h>
#include <syscalls/kernel.h> #include <syscalls/kernel.h>

6
misc/Kconfig

@ -111,6 +111,7 @@ config CHECK_LINK_MAP
help help
Run a linker address generation validity checker at the end of the Run a linker address generation validity checker at the end of the
build. build.
endmenu endmenu
menu "Compiler Options" menu "Compiler Options"
@ -175,11 +176,6 @@ config COMPILER_OPT
and can be used to change compiler optimization, warning and error and can be used to change compiler optimization, warning and error
messages, and so on. messages, and so on.
config CPLUSPLUS
bool "Enable C++ support for the application"
help
This option enables the use of applications built with C++.
endmenu endmenu
menu "Build Options" menu "Build Options"

2
subsys/Kconfig

@ -9,6 +9,8 @@ source "subsys/bluetooth/Kconfig"
source "subsys/console/Kconfig" source "subsys/console/Kconfig"
source "subsys/cpp/Kconfig"
source "subsys/debug/Kconfig" source "subsys/debug/Kconfig"
source "subsys/disk/Kconfig" source "subsys/disk/Kconfig"

1
subsys/cpp/CMakeLists.txt

@ -4,4 +4,5 @@ zephyr_sources_ifdef(CONFIG_CPLUSPLUS
cpp_init_array.c cpp_init_array.c
cpp_ctors.c cpp_ctors.c
cpp_dtors.c cpp_dtors.c
cpp_new.cpp
) )

70
subsys/cpp/Kconfig

@ -0,0 +1,70 @@
# Kconfig - C++ configuration options
#
# Copyright (c) 2018 B. Leforestier
#
# SPDX-License-Identifier: Apache-2.0
#
menu "C++ Options"
config CPLUSPLUS
bool "Enable C++ support for the application"
help
This option enables the use of applications built with C++.
choice
prompt "C++ Standard"
default STD_CPP11
help
C++ Standards.
config STD_CPP98
bool "C++ 98"
help
1998 C++ standard as modified by the 2003 technical corrigendum
and some later defect reports.
config STD_CPP11
bool "C++ 11"
help
2011 C++ standard, previously known as C++0x.
config STD_CPP14
bool "C++ 14"
help
2014 C++ standard.
config STD_CPP17
bool "C++ 17"
help
2017 C++ standard, previously known as C++0x.
config STD_CPP2A
bool "C++ 2a"
help
Next revision of the C++ standard, which is expected to be published in 2020.
endchoice
config LIB_CPLUSPLUS
depends on CPLUSPLUS
bool "Link with STD C++ library"
help
Link with STD C++ Library.
config EXCEPTIONS
depends on CPLUSPLUS
select LIB_CPLUSPLUS
bool "Enable C++ exceptions support"
help
This option enables support of C++ exceptions.
config RTTI
depends on CPLUSPLUS
select LIB_CPLUSPLUS
bool "Enable C++ RTTI support"
help
This option enables support of C++ RTTI.
endmenu

118
subsys/cpp/cpp_new.cpp

@ -0,0 +1,118 @@
/*
* Copyright (c) 2018
*
* SPDX-License-Identifier: Apache-2.0
*/
#if defined(CONFIG_LIB_CPLUSPLUS)
#include <new>
#endif // CONFIG_LIB_CPLUSPLUS
#include <kernel.h>
void* operator new(size_t size)
{
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
void* ptr = k_malloc(size);
#if defined(__cpp_exceptions) && defined(CONFIG_LIB_CPLUSPLUS)
if (!ptr)
throw std::bad_alloc();
#endif
return ptr;
#else
ARG_UNUSED(size);
return NULL;
#endif
}
void* operator new[](size_t size)
{
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
void* ptr = k_malloc(size);
#if defined(__cpp_exceptions) && defined(CONFIG_LIB_CPLUSPLUS)
if (!ptr)
throw std::bad_alloc();
#endif
return ptr;
#else
ARG_UNUSED(size);
return NULL;
#endif
}
void operator delete(void* ptr) noexcept
{
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
k_free(ptr);
#else
ARG_UNUSED(ptr);
#endif
}
void operator delete[](void* ptr) noexcept
{
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
k_free(ptr);
#else
ARG_UNUSED(ptr);
#endif
}
#if defined(CONFIG_LIB_CPLUSPLUS)
void* operator new(size_t size, const std::nothrow_t&) noexcept
{
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
return k_malloc(size);
#else
ARG_UNUSED(size);
return NULL;
#endif
}
void* operator new[](size_t size, const std::nothrow_t&) noexcept
{
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
return k_malloc(size);
#else
ARG_UNUSED(size);
return NULL;
#endif
}
void operator delete(void* ptr, const std::nothrow_t&) noexcept
{
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
k_free(ptr);
#else
ARG_UNUSED(ptr);
#endif
}
void operator delete[](void* ptr, const std::nothrow_t&) noexcept
{
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
k_free(ptr);
#else
ARG_UNUSED(ptr);
#endif
}
#endif // CONFIG_LIB_CPLUSPLUS
#if (__cplusplus > 201103L)
void operator delete(void* ptr, size_t) noexcept
{
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
k_free(ptr);
#else
ARG_UNUSED(ptr);
#endif
}
void operator delete[](void* ptr, size_t) noexcept
{
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
k_free(ptr);
#else
ARG_UNUSED(ptr);
#endif
}
#endif // __cplusplus > 201103L
Loading…
Cancel
Save