diff --git a/cmake/preload/toolchains/util/pico_arm_gcc_common.cmake b/cmake/preload/toolchains/util/pico_arm_gcc_common.cmake index 40ac81998..3c0a9045f 100644 --- a/cmake/preload/toolchains/util/pico_arm_gcc_common.cmake +++ b/cmake/preload/toolchains/util/pico_arm_gcc_common.cmake @@ -4,6 +4,9 @@ # wrongly emit .fpu softvfp regardless of any other options! go figure!!! if (PICO_HARD_FLOAT_ABI) set(PICO_COMMON_LANG_FLAGS "${PICO_COMMON_LANG_FLAGS} -mfloat-abi=hard") +elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL cortex-m0plus) + # older GCC dont accept softfp for M0+ and end up picking wrong libraries in multilib + set(PICO_COMMON_LANG_FLAGS "${PICO_COMMON_LANG_FLAGS} -mfloat-abi=soft") else() set(PICO_COMMON_LANG_FLAGS "${PICO_COMMON_LANG_FLAGS} -mfloat-abi=softfp") endif() diff --git a/src/BUILD.bazel b/src/BUILD.bazel index a397b486507..f2315a150 100644 --- a/src/BUILD.bazel +++ b/src/BUILD.bazel @@ -14,6 +14,7 @@ alias( "//src/common/hardware_claim:__pkg__", "//src/common/pico_base_headers:__pkg__", "//src/common/pico_binary_info:__pkg__", + "//src/rp2_common/pico_cxx_options:__pkg__", # These libraries sometimes need the host version even though they live # in rp2_common. "//src/rp2_common/boot_bootrom_headers:__pkg__", diff --git a/src/common/pico_base_headers/BUILD.bazel b/src/common/pico_base_headers/BUILD.bazel index ad46a5f67..235f7a640 100644 --- a/src/common/pico_base_headers/BUILD.bazel +++ b/src/common/pico_base_headers/BUILD.bazel @@ -125,6 +125,7 @@ cc_library( "//src/rp2_common/hardware_watchdog:__pkg__", "//src/rp2_common/hardware_xosc:__pkg__", "//src/rp2_common/pico_crt0:__pkg__", + "//src/rp2_common/pico_cxx_options:__pkg__", "//src/rp2_common/pico_platform_common:__pkg__", "//src/rp2_common/pico_printf:__pkg__", "//src/rp2_common/pico_runtime:__pkg__", diff --git a/src/rp2_common/pico_clib_interface/BUILD.bazel b/src/rp2_common/pico_clib_interface/BUILD.bazel index de77a9bee..973b683dd 100644 --- a/src/rp2_common/pico_clib_interface/BUILD.bazel +++ b/src/rp2_common/pico_clib_interface/BUILD.bazel @@ -63,11 +63,16 @@ cc_library( cc_library( name = "llvm_libc_interface_link", - srcs = ["llvm_libc_interface.c"], + srcs = [ + "cxa_guard.c", + "llvm_libc_interface.c", + "llvm_libc_interface_cpp.cpp", + ], implementation_deps = [ ":llvm_libc_interface", "//src/rp2_common/pico_atomic", "//src/rp2_common/pico_bootrom", + "//src/rp2_common/pico_cxx_options", "//src/rp2_common/pico_runtime_init", "//src/rp2_common/pico_stdio:pico_stdio_headers", ], @@ -85,10 +90,15 @@ alias( cc_library( name = "newlib_interface_link", - srcs = ["newlib_interface.c"], + srcs = [ + "cxa_guard.c", + "newlib_interface.c", + ], implementation_deps = [ "//src/common/pico_time", + "//src/rp2_common/pico_atomic", "//src/rp2_common/pico_bootrom", + "//src/rp2_common/pico_cxx_options", "//src/rp2_common/pico_printf", "//src/rp2_common/pico_runtime_init", "//src/rp2_common/pico_stdio:pico_stdio_headers", @@ -107,10 +117,15 @@ alias( cc_library( name = "picolibc_interface_link", - srcs = ["picolibc_interface.c"], + srcs = [ + "cxa_guard.c", + "picolibc_interface.c", + ], implementation_deps = [ "//src/common/pico_time", + "//src/rp2_common/pico_atomic", "//src/rp2_common/pico_bootrom", + "//src/rp2_common/pico_cxx_options", "//src/rp2_common/pico_printf", "//src/rp2_common/pico_runtime_init", "//src/rp2_common/pico_stdio:pico_stdio_headers", diff --git a/src/rp2_common/pico_clib_interface/CMakeLists.txt b/src/rp2_common/pico_clib_interface/CMakeLists.txt index 5fae421e7..09130bd08 100644 --- a/src/rp2_common/pico_clib_interface/CMakeLists.txt +++ b/src/rp2_common/pico_clib_interface/CMakeLists.txt @@ -6,7 +6,9 @@ if (NOT TARGET pico_clib_interface) target_sources(pico_newlib_interface INTERFACE ${CMAKE_CURRENT_LIST_DIR}/newlib_interface.c + ${CMAKE_CURRENT_LIST_DIR}/cxa_guard.c ) + pico_mirrored_target_link_libraries(pico_newlib_interface INTERFACE pico_stdio pico_atomic pico_cxx_options) # ---- picolibc ---- @@ -14,8 +16,10 @@ if (NOT TARGET pico_clib_interface) target_sources(pico_picolibc_interface INTERFACE ${CMAKE_CURRENT_LIST_DIR}/picolibc_interface.c + ${CMAKE_CURRENT_LIST_DIR}/cxa_guard.c ) + pico_mirrored_target_link_libraries(pico_picolibc_interface INTERFACE pico_stdio pico_atomic pico_cxx_options) # replacing the functions is fine it seems #target_compile_definitions(pico_picolibc_interface INTERFACE # PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS=0 @@ -26,13 +30,14 @@ if (NOT TARGET pico_clib_interface) target_sources(pico_llvm_libc_interface INTERFACE ${CMAKE_CURRENT_LIST_DIR}/llvm_libc_interface.c + ${CMAKE_CURRENT_LIST_DIR}/llvm_libc_interface_cpp.cpp + ${CMAKE_CURRENT_LIST_DIR}/cxa_guard.c ) target_include_directories(pico_llvm_libc_interface SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include/llvm_libc ) - target_link_libraries(pico_llvm_libc_interface INTERFACE pico_atomic) - pico_mirrored_target_link_libraries(pico_llvm_libc_interface INTERFACE pico_stdio) + pico_mirrored_target_link_libraries(pico_llvm_libc_interface INTERFACE pico_stdio pico_atomic pico_cxx_options) if (NOT PICO_CLIB) # PICO_CMAKE_CONFIG: PICO_CLIB, The C library to use e.g. newlib/picolibc/llvm_libc, type=string, default=based on PICO_COMPILER, group=build, docref=cmake-toolchain-config diff --git a/src/rp2_common/pico_clib_interface/cxa_guard.c b/src/rp2_common/pico_clib_interface/cxa_guard.c new file mode 100644 index 000000000..b4012945b --- /dev/null +++ b/src/rp2_common/pico_clib_interface/cxa_guard.c @@ -0,0 +1,92 @@ +/* +* Copyright (c) 2026 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "pico/cxx_options.h" + +#define CXA_GUARD_UNINITIALIZED 0 +#define CXA_GUARD_INITIALIZED 1 +#define CXA_GUARD_INITIALIZING 2 + +#if PICO_CXX_THREAD_SAFE_STATIC_INIT +#include +#include + +// newer LLVM complains on RP2040 because there are no atomics (it doesn't know we have pico_atomic) +Clang_Pragma("clang diagnostic push") +Clang_Pragma("clang diagnostic ignored \"-Watomic-alignment\"") + +int __cxa_guard_acquire(int32_t *guard_object) { + // Cast the raw pointer to a standard C11 atomic pointer type + _Atomic int32_t *atomic_guard = (_Atomic int32_t *)guard_object; + + while (true) { + // read current state + int32_t current = atomic_load_explicit(atomic_guard, memory_order_acquire); + + // bit 0 set -> Initialization is complete, skip constructor + if (current & CXA_GUARD_INITIALIZED) { + return 0; + } + + // bit 1 set -> another thread/core is initializing it, so sleep + if (current & CXA_GUARD_INITIALIZING) { + __wfe(); + continue; + } + + // attempt to atomically claim the lock by moving state from CXA_GUARD_UNINITIALIZED to CXA_GUARD_INITIALIZING. + int32_t expected = CXA_GUARD_UNINITIALIZED; + if (atomic_compare_exchange_weak_explicit(atomic_guard, &expected, CXA_GUARD_INITIALIZING, + memory_order_release, + memory_order_relaxed)) { + return 1; // Success! This core must execute the constructor + } + } +} + +void __cxa_guard_release(int32_t *guard_object) { + _Atomic int32_t *atomic_guard = (_Atomic int32_t *)guard_object; + + // set Bit 0 (done) and clear Bit 1 (unlocked) + atomic_store_explicit(atomic_guard, CXA_GUARD_INITIALIZED, memory_order_release); + + // wake up any waiters + __sev(); +} + +void __cxa_guard_abort(int32_t *guard_object) { + _Atomic int32_t *atomic_guard = (_Atomic int32_t *)guard_object; + + // reset back to uninitialized state + atomic_store_explicit(atomic_guard, CXA_GUARD_UNINITIALIZED, memory_order_release); + + // wake up any waiters + __sev(); +} + +Clang_Pragma("clang diagnostic pop") +#else + +int __cxa_guard_acquire(volatile int32_t *guard_object) { + int32_t guard_val = *guard_object; + if (guard_val == CXA_GUARD_INITIALIZED) { + return 0; + } + if (guard_val & CXA_GUARD_INITIALIZING) { + panic("recursive CXX initializer"); + } + *guard_object = CXA_GUARD_INITIALIZING; + return 1; +} + +void __cxa_guard_release(volatile int32_t *guard_object) { + *guard_object = CXA_GUARD_INITIALIZED; +} + +void __cxa_guard_abort(volatile int32_t *guard_object) { + *guard_object = CXA_GUARD_UNINITIALIZED; +} +#endif \ No newline at end of file diff --git a/src/rp2_common/pico_clib_interface/llvm_libc_interface.c b/src/rp2_common/pico_clib_interface/llvm_libc_interface.c index 7c1157304..5f772f2e7 100644 --- a/src/rp2_common/pico_clib_interface/llvm_libc_interface.c +++ b/src/rp2_common/pico_clib_interface/llvm_libc_interface.c @@ -9,7 +9,6 @@ #include #include #include - #include #include "pico/runtime_init.h" @@ -79,7 +78,12 @@ bool __llvm_libc_timespec_get_utc(struct timespec *ts) { return true; } -void __cxa_finalize(__unused void *dso) {} +__weak void __cxa_finalize(__unused void *dso) {} + +__weak int atexit(void (*function)(void)) { + (void)function; + return 0; +} void __attribute__((noreturn)) __llvm_libc_exit(__unused int status) { #if PICO_ENTER_USB_BOOT_ON_EXIT @@ -120,5 +124,4 @@ void runtime_init(void) { for (void (**p)(void) = &__init_array_start; p < &__init_array_end; ++p) { (*p)(); } -} - +} \ No newline at end of file diff --git a/src/rp2_common/pico_clib_interface/llvm_libc_interface_cpp.cpp b/src/rp2_common/pico_clib_interface/llvm_libc_interface_cpp.cpp new file mode 100644 index 000000000..928c1fe62 --- /dev/null +++ b/src/rp2_common/pico_clib_interface/llvm_libc_interface_cpp.cpp @@ -0,0 +1,13 @@ +#include +#include + +#include "pico.h" + +namespace std { + inline namespace __2 { + [[__noreturn__]] _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT( + __printf__, 1, 2) void __libcpp_verbose_abort(const char* __format, ...) _NOEXCEPT { + panic("c++ abort: %s", __format); + } + } +} diff --git a/src/rp2_common/pico_clib_interface/newlib_interface.c b/src/rp2_common/pico_clib_interface/newlib_interface.c index 944045052..0c1fbd7d6 100644 --- a/src/rp2_common/pico_clib_interface/newlib_interface.c +++ b/src/rp2_common/pico_clib_interface/newlib_interface.c @@ -47,6 +47,9 @@ void __attribute__((noreturn)) __weak _exit(__unused int status) { #endif } +void __weak _fini(void) { +} + __weak void *_sbrk(int incr) { extern char end; /* Set by linker. */ static char *heap_end; diff --git a/src/rp2_common/pico_clib_interface/picolibc_interface.c b/src/rp2_common/pico_clib_interface/picolibc_interface.c index afc6434ff..25dc87ae7 100644 --- a/src/rp2_common/pico_clib_interface/picolibc_interface.c +++ b/src/rp2_common/pico_clib_interface/picolibc_interface.c @@ -85,6 +85,15 @@ void __attribute__((noreturn)) __weak _exit(__unused int status) { #endif } +int __weak getpid(void) { + return 0; +} + +int __weak kill(__unused int pid, __unused int sig) { + __breakpoint(); + return -1; +} + static int64_t epoch_time_us_since_boot; __weak int gettimeofday (struct timeval *__restrict tv, __unused void *__restrict tz) { diff --git a/src/rp2_common/pico_cxx_options/BUILD.bazel b/src/rp2_common/pico_cxx_options/BUILD.bazel index 61ef0c3a4..87c177b4b 100644 --- a/src/rp2_common/pico_cxx_options/BUILD.bazel +++ b/src/rp2_common/pico_cxx_options/BUILD.bazel @@ -14,9 +14,14 @@ pico_sdk_define( cc_library( name = "pico_cxx_options", srcs = ["new_delete.cpp"], + hdrs = [ + "include/pico/cxx_options.h", + ], + includes = ["include"], target_compatible_with = compatible_with_rp2(), deps = [ ":PICO_CXX_ENABLE_EXCEPTIONS", - "//src/rp2_common:pico_platform", + "//src:pico_platform_internal", + "//src/common/pico_base_headers", ], ) diff --git a/src/rp2_common/pico_cxx_options/CMakeLists.txt b/src/rp2_common/pico_cxx_options/CMakeLists.txt index 500fceb57..ad111092c 100644 --- a/src/rp2_common/pico_cxx_options/CMakeLists.txt +++ b/src/rp2_common/pico_cxx_options/CMakeLists.txt @@ -4,6 +4,7 @@ if (NOT TARGET pico_cxx_options) target_sources(pico_cxx_options INTERFACE ${CMAKE_CURRENT_LIST_DIR}/new_delete.cpp ) + target_include_directories(pico_cxx_options SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) # PICO_CMAKE_CONFIG: PICO_CXX_ENABLE_EXCEPTIONS, Enable CXX exception handling, type=bool, default=0, group=pico_cxx_options # PICO_BUILD_DEFINE: PICO_CXX_ENABLE_EXCEPTIONS, value of CMake var PICO_CXX_ENABLE_EXCEPTIONS, type=string, default=0, group=pico_cxx_options diff --git a/src/rp2_common/pico_cxx_options/include/pico/cxx_options.h b/src/rp2_common/pico_cxx_options/include/pico/cxx_options.h new file mode 100644 index 000000000..41f4ce094 --- /dev/null +++ b/src/rp2_common/pico_cxx_options/include/pico/cxx_options.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _PICO_CXX_OPTIONS_H +#define _PICO_CXX_OPTIONS_H + +#include "pico.h" + +// PICO_CONFIG: PICO_CXX_DISABLE_ALLOCATION_OVERRIDES, Disable SDK overrides of C++ new/delete operators, type=bool, default=0, advanced=true, group=pico_cxx_options + +// PICO_CONFIG: PICO_CXX_THREAD_SAFE_STATIC_INIT, Enable thread/IRQ safe locks for C++ static initializers, type=bool, default=1 when using pico_multicore, advanced=true, group=pico_cxx_options +#ifndef PICO_CXX_THREAD_SAFE_STATIC_INIT +#define PICO_CXX_THREAD_SAFE_STATIC_INIT LIB_PICO_MULTICORE +#endif + +#endif + + diff --git a/src/rp2_common/pico_cxx_options/new_delete.cpp b/src/rp2_common/pico_cxx_options/new_delete.cpp index abf54f3a6..95872feff 100644 --- a/src/rp2_common/pico_cxx_options/new_delete.cpp +++ b/src/rp2_common/pico_cxx_options/new_delete.cpp @@ -3,12 +3,13 @@ * * SPDX-License-Identifier: BSD-3-Clause */ +#include "pico/cxx_options.h" #if !PICO_CXX_ENABLE_EXCEPTIONS // Override the standard allocators to use regular malloc/free #if !PICO_CXX_DISABLE_ALLOCATION_OVERRIDES // Let user override -#include // weird looking but it is required if dropping picolibc on top of GCC+newlib (reent issue) +#include // weird looking, but it is required if dropping picolibc on top of GCC+newlib (reent issue) #include #include "pico.h" @@ -20,7 +21,7 @@ void *operator new[](std::size_t n) { return std::malloc(n); } -void operator delete(void *p) { std::free(p); } +void operator delete(void *p) noexcept { std::free(p); } void operator delete[](void *p) noexcept { std::free(p); } diff --git a/src/rp2_common/pico_standard_link/CMakeLists.txt b/src/rp2_common/pico_standard_link/CMakeLists.txt index 432dc1546..ee8b7e870 100644 --- a/src/rp2_common/pico_standard_link/CMakeLists.txt +++ b/src/rp2_common/pico_standard_link/CMakeLists.txt @@ -208,7 +208,7 @@ if (NOT TARGET pico_standard_link) # \brief\ Place time-critical code for the target into # # Configures the target to run functions marked __time_critical_func() from rather than - # normal SRAM, useful if has dedicated AHB ports which are otherwise unused. For example, + # normal SRAM, useful if has dedicated AHB ports which are otherwise unused. For example, # xip_ram could be used in no_flash and copy_to_ram binaries, as the XIP AHB ports are unused. # This sets PICO_TIME_CRITICAL_PLACEMENT=__in_, and any necessary defines required to use # (e.g. PICO_USE_XIP_CACHE_AS_RAM=1 for xip_ram). @@ -229,7 +229,7 @@ if (NOT TARGET pico_standard_link) # \brief\ Place time-critical code for the target into # # Configures the target to place data (and code) marked __not_in_flash() in rather than - # normal SRAM, useful if has dedicated AHB ports which are otherwise unused. For example, + # normal SRAM, useful if has dedicated AHB ports which are otherwise unused. For example, # xip_ram could be used in no_flash and copy_to_ram binaries, as the XIP AHB ports are unused. # This sets PICO_NOT_IN_FLASH_PLACEMENT=__in_, and any necessary defines required to use # (e.g. PICO_USE_XIP_CACHE_AS_RAM=1 for xip_ram). @@ -363,9 +363,10 @@ if (NOT TARGET pico_standard_link) target_compile_definitions(pico_standard_link INTERFACE PICO_DEOPTIMIZED_DEBUG=1) endif() - # this (arguably wrong) code is restored for 1.5.1 as setting -nostartfiles on many C++ binaries causes link errors. see issue #1368 - # -nostartfiles will be added if PICO_NO_FLASH would be defined to 1 - target_link_options(pico_standard_link INTERFACE $<$,${NO_FLASH_BINARY_TYPES}>,1,$,$>>>:-nostartfiles>) + if (PICO_C_COMPILER_IS_GNU) + target_link_options(pico_standard_link INTERFACE -nostartfiles) + endif() + # boot_stage2 will be linked if PICO_NO_FLASH would be defined to 0; note if boot_stage2 headers not present, then boot_stage2 is omitted from build anyway if (TARGET boot_stage2_headers) target_link_libraries(pico_standard_link INTERFACE $<$,${NO_FLASH_BINARY_TYPES}>,1,$,$>>>>:$>,$,bs2_default>_library>) diff --git a/src/rp2_common/pico_standard_link/script_include/section_copy_to_ram_data.incl b/src/rp2_common/pico_standard_link/script_include/section_copy_to_ram_data.incl index 646523756..a47340064 100644 --- a/src/rp2_common/pico_standard_link/script_include/section_copy_to_ram_data.incl +++ b/src/rp2_common/pico_standard_link/script_include/section_copy_to_ram_data.incl @@ -11,6 +11,7 @@ __tls_base, __tls_end __tbss_end __global_pointer$ + __dso_handle */ SECTIONS @@ -65,6 +66,7 @@ SECTIONS *(SORT(.fini_array.*)) *(.fini_array) PROVIDE_HIDDEN (__fini_array_end = .); + PROVIDE(__dso_handle = 0); *(.jcr) . = ALIGN(4); diff --git a/src/rp2_common/pico_standard_link/script_include/section_default_text.incl b/src/rp2_common/pico_standard_link/script_include/section_default_text.incl index 52f42fe2e..124aaaa74 100644 --- a/src/rp2_common/pico_standard_link/script_include/section_default_text.incl +++ b/src/rp2_common/pico_standard_link/script_include/section_default_text.incl @@ -6,6 +6,7 @@ __init_array_start, __init_array_end __bothinit_array_start, __bothinit_array_end __fini_array_start, __fini_array_end + __dso_handle */ SECTIONS @@ -72,6 +73,7 @@ SECTIONS *(SORT(.fini_array.*)) *(.fini_array) PROVIDE_HIDDEN (__fini_array_end = .); + PROVIDE(__dso_handle = 0); *(.eh_frame*) . = ALIGN(4); diff --git a/src/rp2_common/pico_standard_link/script_include/section_no_flash_data.incl b/src/rp2_common/pico_standard_link/script_include/section_no_flash_data.incl index d162a45b1..440c9fb95 100644 --- a/src/rp2_common/pico_standard_link/script_include/section_no_flash_data.incl +++ b/src/rp2_common/pico_standard_link/script_include/section_no_flash_data.incl @@ -11,6 +11,7 @@ __tls_base, __tls_end __tbss_end __global_pointer$ + __dso_handle */ SECTIONS @@ -60,6 +61,7 @@ SECTIONS *(SORT(.fini_array.*)) *(.fini_array) PROVIDE_HIDDEN (__fini_array_end = .); + PROVIDE(__dso_handle = 0); *(.jcr) . = ALIGN(4); diff --git a/test/kitchen_sink/BUILD.bazel b/test/kitchen_sink/BUILD.bazel index 189eef3be..0bf0ba845 100644 --- a/test/kitchen_sink/BUILD.bazel +++ b/test/kitchen_sink/BUILD.bazel @@ -107,6 +107,14 @@ cc_binary( name = "kitchen_sink_cpp", testonly = True, srcs = ["kitchen_sink_cpp.cpp"], + # todo - seems like the bazel clang build omits important library(s) containing new/delete (or we end + # up not providing them via new_delete.cpp for some reason). + # I'm leaving as a todo for now as building with llvm-libc and clang outside of bazel work fine + # (note DISABLE_VECTOR_TEST avoids use of std::vector in kitchen_sink_test_cpp) + defines = select({ + "//bazel/constraint:pico_toolchain_clang_enabled": ["DISABLE_VECTOR_TEST=1"], + "//conditions:default": [], + }), deps = [":kitchen_sink_common"], ) @@ -126,6 +134,22 @@ cc_binary( deps = [":kitchen_sink_common"], ) +cc_binary( + name = "kitchen_sink_cpp_no_flash_actual", + testonly = True, + srcs = ["kitchen_sink_cpp.cpp"], + # todo - seems like the bazel clang build omits important library(s) containing new/delete (or we end + # up not providing them via new_delete.cpp for some reason). + # I'm leaving as a todo for now as building with llvm-libc and clang outside of bazel work fine + # (note DISABLE_VECTOR_TEST avoids use of std::vector in kitchen_sink_test_cpp) + defines = select({ + "//bazel/constraint:pico_toolchain_clang_enabled": ["DISABLE_VECTOR_TEST=1"], + "//conditions:default": [], + }), + tags = ["manual"], # Built via kitchen_sink_cpp_no_flash + deps = [":kitchen_sink_common"], +) + cc_binary( name = "kitchen_sink_blocked_ram_actual", testonly = True, @@ -150,6 +174,14 @@ pico_set_binary_type( target_compatible_with = compatible_with_rp2(), ) +pico_set_binary_type( + name = "kitchen_sink_cpp_no_flash", + testonly = True, + src = ":kitchen_sink_cpp_no_flash_actual", + binary_type = "no_flash", + target_compatible_with = compatible_with_rp2(), +) + pico_set_binary_type( name = "kitchen_sink_blocked_ram", testonly = True, diff --git a/test/kitchen_sink/CMakeLists.txt b/test/kitchen_sink/CMakeLists.txt index d9616304c..925cab732 100644 --- a/test/kitchen_sink/CMakeLists.txt +++ b/test/kitchen_sink/CMakeLists.txt @@ -170,70 +170,6 @@ pico_set_program_name(kitchen_sink "Wombat tentacles") pico_add_extra_outputs(kitchen_sink) target_compile_definitions(kitchen_sink PRIVATE KITCHEN_SINK_ID="regular binary") -if (NOT PICO_RP2040) - add_executable(kitchen_sink_psram_fixed ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) - target_link_libraries(kitchen_sink_psram_fixed kitchen_sink_libs kitchen_sink_options) - target_compile_definitions(kitchen_sink_psram_fixed PRIVATE FIXED_PSRAM_SIZE=1) - if (NOT DEFINED PICO_PSRAM_SIZE_BYTES) - # Override the PSRAM size for boards that usually don't have PSRAM to allow - # variables in PSRAM, and auto-detect at runtime if PSRAM is present. - target_compile_definitions(kitchen_sink_psram_fixed PRIVATE PICO_AUTO_DETECT_PSRAM=1) - pico_override_psram_size(kitchen_sink_psram_fixed "(1 * 1024 * 1024)") - endif() - pico_add_extra_outputs(kitchen_sink_psram_fixed) - target_compile_definitions(kitchen_sink_psram_fixed PRIVATE KITCHEN_SINK_ID="psram fixed size binary") - set_target_properties(kitchen_sink_psram_fixed PROPERTIES PICO_TEST_FAILURE_STRING "ERROR:") - - add_executable(kitchen_sink_psram_tiny ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) - target_link_libraries(kitchen_sink_psram_tiny kitchen_sink_libs kitchen_sink_options) - target_compile_definitions(kitchen_sink_psram_tiny PRIVATE FIXED_PSRAM_SIZE=1 TINY_PSRAM=1) - # Override the PSRAM size to allow variables in PSRAM - target_compile_definitions(kitchen_sink_psram_tiny PRIVATE PICO_AUTO_DETECT_PSRAM=1) - pico_override_psram_size(kitchen_sink_psram_tiny "(1 * 1024 * 1024)") - pico_add_extra_outputs(kitchen_sink_psram_tiny) - target_compile_definitions(kitchen_sink_psram_tiny PRIVATE KITCHEN_SINK_ID="psram tiny size binary") - # Expected to bus fault, so printing PASSED is a failure - set_target_properties(kitchen_sink_psram_tiny PROPERTIES PICO_TEST_SUCCESS_STRING "psram tiny size binary") - set_target_properties(kitchen_sink_psram_tiny PROPERTIES PICO_TEST_FAILURE_STRING "PASSED") - - add_executable(kitchen_sink_psram_small ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) - target_link_libraries(kitchen_sink_psram_small kitchen_sink_libs kitchen_sink_options) - target_compile_definitions(kitchen_sink_psram_small PRIVATE FIXED_PSRAM_SIZE=1 SMALL_PSRAM=1) - # Override the PSRAM size to allow variables in PSRAM - target_compile_definitions(kitchen_sink_psram_small PRIVATE PICO_AUTO_DETECT_PSRAM=1) - pico_override_psram_size(kitchen_sink_psram_small "(1 * 1024 * 1024)") - pico_add_extra_outputs(kitchen_sink_psram_small) - target_compile_definitions(kitchen_sink_psram_small PRIVATE KITCHEN_SINK_ID="psram small size binary") - set_target_properties(kitchen_sink_psram_small PROPERTIES PICO_TEST_FAILURE_STRING "ERROR:") - - add_executable(kitchen_sink_psram_detect ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) - target_link_libraries(kitchen_sink_psram_detect kitchen_sink_libs kitchen_sink_options) - target_compile_definitions(kitchen_sink_psram_detect PRIVATE PICO_AUTO_DETECT_PSRAM=1) - pico_add_extra_outputs(kitchen_sink_psram_detect) - target_compile_definitions(kitchen_sink_psram_detect PRIVATE KITCHEN_SINK_ID="psram detect size binary") - set_target_properties(kitchen_sink_psram_detect PROPERTIES PICO_TEST_FAILURE_STRING "ERROR:") - - add_executable(kitchen_sink_no_flash_psram_detect ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) - target_link_libraries(kitchen_sink_no_flash_psram_detect kitchen_sink_libs kitchen_sink_options) - target_compile_definitions(kitchen_sink_no_flash_psram_detect PRIVATE PICO_AUTO_DETECT_PSRAM=1) - pico_set_binary_type(kitchen_sink_no_flash_psram_detect no_flash) - pico_add_extra_outputs(kitchen_sink_no_flash_psram_detect) - target_compile_definitions(kitchen_sink_no_flash_psram_detect PRIVATE KITCHEN_SINK_ID="psram detect size no_flash binary") - set_target_properties(kitchen_sink_no_flash_psram_detect PROPERTIES PICO_TEST_FAILURE_STRING "ERROR:") - - add_executable(kitchen_sink_psram_flash_fixed ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) - target_link_libraries(kitchen_sink_psram_flash_fixed kitchen_sink_libs kitchen_sink_options) - target_compile_definitions(kitchen_sink_psram_flash_fixed PRIVATE FIXED_PSRAM_SIZE=1) - # Override the FLASH and PSRAM size to check overriding works - # variables in PSRAM, and auto-detect at runtime if PSRAM is present. - target_compile_definitions(kitchen_sink_psram_flash_fixed PRIVATE PICO_AUTO_DETECT_PSRAM=1) - pico_override_flash_size(kitchen_sink_psram_flash_fixed "(1 * 1024 * 1024)") - pico_override_psram_size(kitchen_sink_psram_flash_fixed "(1 * 1024 * 1024)") - pico_add_extra_outputs(kitchen_sink_psram_flash_fixed) - target_compile_definitions(kitchen_sink_psram_flash_fixed PRIVATE KITCHEN_SINK_ID="psram and flash fixed size binary") - set_target_properties(kitchen_sink_psram_flash_fixed PROPERTIES PICO_TEST_FAILURE_STRING "ERROR:") -endif() - if (TARGET hardware_pio) pico_generate_pio_header(kitchen_sink ${CMAKE_CURRENT_LIST_DIR}/trivial.pio) endif() @@ -332,6 +268,70 @@ if (NOT KITCHEN_SINK_NO_BINARY_TYPE_VARIANTS) pico_add_extra_outputs(kitchen_sink_simple_overlay) target_compile_definitions(kitchen_sink_simple_overlay PRIVATE KITCHEN_SINK_ID="simple overlay binary" EXTRA_DATA_SECTION=2) endif() + + if (NOT PICO_RP2040) + add_executable(kitchen_sink_psram_fixed ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) + target_link_libraries(kitchen_sink_psram_fixed kitchen_sink_libs kitchen_sink_options) + target_compile_definitions(kitchen_sink_psram_fixed PRIVATE FIXED_PSRAM_SIZE=1) + if (NOT DEFINED PICO_PSRAM_SIZE_BYTES) + # Override the PSRAM size for boards that usually don't have PSRAM to allow + # variables in PSRAM, and auto-detect at runtime if PSRAM is present. + target_compile_definitions(kitchen_sink_psram_fixed PRIVATE PICO_AUTO_DETECT_PSRAM=1) + pico_override_psram_size(kitchen_sink_psram_fixed "(1 * 1024 * 1024)") + endif() + pico_add_extra_outputs(kitchen_sink_psram_fixed) + target_compile_definitions(kitchen_sink_psram_fixed PRIVATE KITCHEN_SINK_ID="psram fixed size binary") + set_target_properties(kitchen_sink_psram_fixed PROPERTIES PICO_TEST_FAILURE_STRING "ERROR:") + + add_executable(kitchen_sink_psram_tiny ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) + target_link_libraries(kitchen_sink_psram_tiny kitchen_sink_libs kitchen_sink_options) + target_compile_definitions(kitchen_sink_psram_tiny PRIVATE FIXED_PSRAM_SIZE=1 TINY_PSRAM=1) + # Override the PSRAM size to allow variables in PSRAM + target_compile_definitions(kitchen_sink_psram_tiny PRIVATE PICO_AUTO_DETECT_PSRAM=1) + pico_override_psram_size(kitchen_sink_psram_tiny "(1 * 1024 * 1024)") + pico_add_extra_outputs(kitchen_sink_psram_tiny) + target_compile_definitions(kitchen_sink_psram_tiny PRIVATE KITCHEN_SINK_ID="psram tiny size binary") + # Expected to bus fault, so printing PASSED is a failure + set_target_properties(kitchen_sink_psram_tiny PROPERTIES PICO_TEST_SUCCESS_STRING "psram tiny size binary") + set_target_properties(kitchen_sink_psram_tiny PROPERTIES PICO_TEST_FAILURE_STRING "PASSED") + + add_executable(kitchen_sink_psram_small ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) + target_link_libraries(kitchen_sink_psram_small kitchen_sink_libs kitchen_sink_options) + target_compile_definitions(kitchen_sink_psram_small PRIVATE FIXED_PSRAM_SIZE=1 SMALL_PSRAM=1) + # Override the PSRAM size to allow variables in PSRAM + target_compile_definitions(kitchen_sink_psram_small PRIVATE PICO_AUTO_DETECT_PSRAM=1) + pico_override_psram_size(kitchen_sink_psram_small "(1 * 1024 * 1024)") + pico_add_extra_outputs(kitchen_sink_psram_small) + target_compile_definitions(kitchen_sink_psram_small PRIVATE KITCHEN_SINK_ID="psram small size binary") + set_target_properties(kitchen_sink_psram_small PROPERTIES PICO_TEST_FAILURE_STRING "ERROR:") + + add_executable(kitchen_sink_psram_detect ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) + target_link_libraries(kitchen_sink_psram_detect kitchen_sink_libs kitchen_sink_options) + target_compile_definitions(kitchen_sink_psram_detect PRIVATE PICO_AUTO_DETECT_PSRAM=1) + pico_add_extra_outputs(kitchen_sink_psram_detect) + target_compile_definitions(kitchen_sink_psram_detect PRIVATE KITCHEN_SINK_ID="psram detect size binary") + set_target_properties(kitchen_sink_psram_detect PROPERTIES PICO_TEST_FAILURE_STRING "ERROR:") + + add_executable(kitchen_sink_no_flash_psram_detect ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) + target_link_libraries(kitchen_sink_no_flash_psram_detect kitchen_sink_libs kitchen_sink_options) + target_compile_definitions(kitchen_sink_no_flash_psram_detect PRIVATE PICO_AUTO_DETECT_PSRAM=1) + pico_set_binary_type(kitchen_sink_no_flash_psram_detect no_flash) + pico_add_extra_outputs(kitchen_sink_no_flash_psram_detect) + target_compile_definitions(kitchen_sink_no_flash_psram_detect PRIVATE KITCHEN_SINK_ID="psram detect size no_flash binary") + set_target_properties(kitchen_sink_no_flash_psram_detect PROPERTIES PICO_TEST_FAILURE_STRING "ERROR:") + + add_executable(kitchen_sink_psram_flash_fixed ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) + target_link_libraries(kitchen_sink_psram_flash_fixed kitchen_sink_libs kitchen_sink_options) + target_compile_definitions(kitchen_sink_psram_flash_fixed PRIVATE FIXED_PSRAM_SIZE=1) + # Override the FLASH and PSRAM size to check overriding works + # variables in PSRAM, and auto-detect at runtime if PSRAM is present. + target_compile_definitions(kitchen_sink_psram_flash_fixed PRIVATE PICO_AUTO_DETECT_PSRAM=1) + pico_override_flash_size(kitchen_sink_psram_flash_fixed "(1 * 1024 * 1024)") + pico_override_psram_size(kitchen_sink_psram_flash_fixed "(1 * 1024 * 1024)") + pico_add_extra_outputs(kitchen_sink_psram_flash_fixed) + target_compile_definitions(kitchen_sink_psram_flash_fixed PRIVATE KITCHEN_SINK_ID="psram and flash fixed size binary") + set_target_properties(kitchen_sink_psram_flash_fixed PROPERTIES PICO_TEST_FAILURE_STRING "ERROR:") + endif() endif() add_executable(kitchen_sink_cpp ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink_cpp.cpp) @@ -339,6 +339,14 @@ target_link_libraries(kitchen_sink_cpp kitchen_sink_libs kitchen_sink_options) pico_set_program_name(kitchen_sink_cpp "Wombat tentacles CPP") pico_add_extra_outputs(kitchen_sink_cpp) +if (NOT KITCHEN_SINK_NO_BINARY_TYPE_VARIANTS) + add_executable(kitchen_sink_cpp_no_flash ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink_cpp.cpp) + pico_set_binary_type(kitchen_sink_cpp_no_flash no_flash) + target_link_libraries(kitchen_sink_cpp_no_flash kitchen_sink_libs kitchen_sink_options) + pico_add_extra_outputs(kitchen_sink_cpp_no_flash) + target_compile_definitions(kitchen_sink_cpp_no_flash PRIVATE KITCHEN_SINK_ID="no-flash binary") +endif() + if (TARGET pico_cyw43_arch) # for lwipopts.h add_executable(kitchen_sink_lwip_poll ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) diff --git a/test/kitchen_sink/kitchen_sink.c b/test/kitchen_sink/kitchen_sink.c index a151a0b5e..0d8e70591 100644 --- a/test/kitchen_sink/kitchen_sink.c +++ b/test/kitchen_sink/kitchen_sink.c @@ -314,6 +314,11 @@ int main(void) { } #endif +#ifdef EXTRA_FUNC + extern void EXTRA_FUNC(void); + EXTRA_FUNC(); +#endif + #ifndef __riscv exception_set_exclusive_handler(SVCALL_EXCEPTION, svc_call); // this should compile as we are Cortex-M diff --git a/test/kitchen_sink/kitchen_sink_cpp.cpp b/test/kitchen_sink/kitchen_sink_cpp.cpp index 1b4fe5ab6..650d36a36 100644 --- a/test/kitchen_sink/kitchen_sink_cpp.cpp +++ b/test/kitchen_sink/kitchen_sink_cpp.cpp @@ -1 +1,23 @@ -#include "kitchen_sink.c" \ No newline at end of file +#if DISABLE_VECTOR_TEST +#include "kitchen_sink.c" +#else +#include + +#define EXTRA_FUNC test_vector +#include "kitchen_sink.c" + +std::vector sv({"foo", "bar", "humbug"}); + +void test_vector() { + static std::vector vec; + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + for (const auto &x : sv) { + puts(x); + } + for (const auto &x : vec) { + printf("Number %d\n", x); + } +} +#endif diff --git a/tools/bazel_build.py b/tools/bazel_build.py index 8acffca8f..003030d22 100755 --- a/tools/bazel_build.py +++ b/tools/bazel_build.py @@ -39,6 +39,7 @@ "//test/kitchen_sink:kitchen_sink_cpp", "//test/kitchen_sink:kitchen_sink_copy_to_ram", "//test/kitchen_sink:kitchen_sink_no_flash", + "//test/kitchen_sink:kitchen_sink_cpp_no_flash", "//test/kitchen_sink:kitchen_sink_blocked_ram", "//test/kitchen_sink:kitchen_sink_lwip_poll", "//test/kitchen_sink:kitchen_sink_lwip_background",