diff --git a/cmake/preload/toolchains/pico_arm_cortex_m0plus_clang.cmake b/cmake/preload/toolchains/pico_arm_cortex_m0plus_clang.cmake index 5ebde3e00..d445d3c73 100644 --- a/cmake/preload/toolchains/pico_arm_cortex_m0plus_clang.cmake +++ b/cmake/preload/toolchains/pico_arm_cortex_m0plus_clang.cmake @@ -1,8 +1,5 @@ set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus) -# these are all the directories under LLVM embedded toolchain for ARM (newlib or pibolibc) and under llvm_libc -set(PICO_CLANG_RUNTIMES armv6m_soft_nofp armv6m-unknown-none-eabi) - -set(PICO_COMMON_LANG_FLAGS "--target=armv6m-none-eabi -mfloat-abi=soft -march=armv6m") +set(PICO_COMMON_LANG_FLAGS "--target=arm-none-eabi -mcpu=cortex-m0plus -mfloat-abi=soft") include(${CMAKE_CURRENT_LIST_DIR}/util/pico_arm_clang_common.cmake) diff --git a/cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake b/cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake index da42da46e..16f30327e 100644 --- a/cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake +++ b/cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake @@ -1,8 +1,6 @@ set(CMAKE_SYSTEM_PROCESSOR cortex-m33) -# these are all the directories under LLVM embedded toolchain for ARM (newlib or pibolibc) and under llvm_libc -set(PICO_CLANG_RUNTIMES armv8m.main_soft_nofp armv8m.main_soft_nofp_unaligned armv8m.main-unknown-none-eabi) - -set(PICO_COMMON_LANG_FLAGS "-mcpu=cortex-m33 --target=armv8m.main-none-eabi -mfloat-abi=softfp -march=armv8m.main+fp+dsp") +set(PICO_COMMON_LANG_FLAGS "--target=arm-none-eabi -mfloat-abi=hard -march=armv8m.main+fp+dsp") set(PICO_DISASM_OBJDUMP_ARGS --mcpu=cortex-m33 --arch=armv8m.main+fp+dsp) + include(${CMAKE_CURRENT_LIST_DIR}/util/pico_arm_clang_common.cmake) diff --git a/cmake/preload/toolchains/util/pico_arm_clang_common.cmake b/cmake/preload/toolchains/util/pico_arm_clang_common.cmake index 5cb4e2df5..bd9ad0df9 100644 --- a/cmake/preload/toolchains/util/pico_arm_clang_common.cmake +++ b/cmake/preload/toolchains/util/pico_arm_clang_common.cmake @@ -11,7 +11,7 @@ pico_find_compiler(PICO_OBJCOPY llvm-objcopy) pico_find_compiler(PICO_OBJDUMP llvm-objdump) # Specify the cross compiler. -set(CMAKE_C_COMPILER ${PICO_COMPILER_CC} CACHE FILEPATH "C compiler") +set(CMAKE_C_COMPILER ${PICO_COMPILER_CC} CACHE FILEPATH "C compiler") set(CMAKE_CXX_COMPILER ${PICO_COMPILER_CXX} CACHE FILEPATH "C++ compiler") set(CMAKE_ASM_COMPILER ${PICO_COMPILER_ASM} CACHE FILEPATH "ASM compiler") @@ -43,55 +43,49 @@ endforeach() list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES PICO_CLIB) -foreach(PICO_CLANG_RUNTIME IN LISTS PICO_CLANG_RUNTIMES) - # LLVM embedded-toolchain for ARM style - find_path(PICO_COMPILER_SYSROOT NAMES include/stdio.h - HINTS - ${PICO_COMPILER_DIR}/../lib/clang-runtimes/arm-none-eabi/${PICO_CLANG_RUNTIME} - ${PICO_COMPILER_DIR}/../lib/clang-runtimes/${PICO_CLANG_RUNTIME} - ) - - if (PICO_COMPILER_SYSROOT) - if (NOT PICO_CLIB) - # this is a bit of a hack; to try to autodetect the C library used: - # `picolibc.h` seems to exist on the newer versions of LLVM embedded toolchain for ARM using picolibc whereas - # `newlib.h` appears in all versions, so isn't very useful - if (EXISTS "${PICO_COMPILER_SYSROOT}/include/picolibc.h") - message("Setting default C library to picolibc as LLVM appears to be using it") - set(PICO_CLIB "picolibc" CACHE INTERNAL "") - endif() - endif() - break() +set(_CLANG_RUNTIMES_DIR "${PICO_COMPILER_DIR}/../lib/clang-runtimes") +cmake_path(NORMAL_PATH _CLANG_RUNTIMES_DIR) +set(PICO_CLIB_ROOT "${_CLANG_RUNTIMES_DIR}") + +if(NOT PICO_CLIB OR PICO_CLIB STREQUAL "") + # newlib is primary if no clib specified + if(EXISTS "${_CLANG_RUNTIMES_DIR}/newlib") + set(PICO_CLIB "newlib") + else() + set(PICO_CLIB "picolibc") endif() - # llvm_libc style - find_path(PICO_COMPILER_SYSROOT NAMES stdio.h - HINTS - ${PICO_COMPILER_DIR}/../include/${PICO_CLANG_RUNTIME} - ) - if (PICO_COMPILER_SYSROOT) - if (NOT PICO_CLIB) - message("Setting default C library to llvm_libc as LLVM appears to be using it") - set(PICO_CLIB "llvm_libc" CACHE INTERNAL "") - endif() - break() + set(CACHE{PICO_CLIB} TYPE STRING FORCE VALUE ${PICO_CLIB}) +endif() + +if(PICO_CLIB STREQUAL "newlib") + if(EXISTS "${_CLANG_RUNTIMES_DIR}/newlib") + set(PICO_CLIB_ROOT "${_CLANG_RUNTIMES_DIR}/newlib") endif() -endforeach() +elseif(PICO_CLIB STREQUAL "llvm_libc") + if(EXISTS "${_CLANG_RUNTIMES_DIR}/llvmlibc") + set(PICO_CLIB_ROOT "${_CLANG_RUNTIMES_DIR}/llvmlibc") + endif() +elseif(PICO_CLIB STREQUAL "picolibc") + if(EXISTS "${_CLANG_RUNTIMES_DIR}/picolibc") + set(PICO_CLIB_ROOT "${_CLANG_RUNTIMES_DIR}/picolibc") + endif() +else() + message(FATAL_ERROR "PICO_CLIB must be one of newlib, picolib, llvm_libc or empty (but is '${PICO_CLIB}')") +endif() + +set(PICO_COMMON_LANG_FLAGS "${PICO_COMMON_LANG_FLAGS} --sysroot ${PICO_CLIB_ROOT}") # moving this here as a reminder from pico_standard_link; it was commented out theee, but if ever needed, # it belongs here as part of LINKER_FLAGS_INIT #target_link_options(pico_standard_link INTERFACE "LINKER:-fuse-ld=lld") if (PICO_CLIB STREQUAL "llvm_libc") - # TODO: Remove -nostdlib++ once we include libc++ in the toolchain. # TODO: Move -nostartfiles to the appropriate library. foreach(TYPE IN ITEMS EXE SHARED MODULE) - set(CMAKE_${TYPE}_LINKER_FLAGS_INIT "-nostdlib++ -nostartfiles") + set(CMAKE_${TYPE}_LINKER_FLAGS_INIT "-nostartfiles") endforeach() -else() - if (NOT PICO_COMPILER_SYSROOT) - message(FATAL_ERROR "Could not find an llvm runtime for '${PICO_CLANG_RUNTIME}'") - endif() - - set(PICO_COMMON_LANG_FLAGS "${PICO_COMMON_LANG_FLAGS} --sysroot ${PICO_COMPILER_SYSROOT}") endif() + +message(STATUS "Taking '${PICO_CLIB}' from '${PICO_CLIB_ROOT}'") + include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake) diff --git a/src/rp2_common/pico_clib_interface/BUILD.bazel b/src/rp2_common/pico_clib_interface/BUILD.bazel index 9bb05a99c..8ddc02de2 100644 --- a/src/rp2_common/pico_clib_interface/BUILD.bazel +++ b/src/rp2_common/pico_clib_interface/BUILD.bazel @@ -98,10 +98,16 @@ cc_library( target_compatible_with = compatible_with_rp2(), ) -# For now, picolibc doesn't need to provide any headers. -alias( +cc_library( name = "picolibc_interface", - actual = "//bazel:empty_cc_lib", + hdrs = [ + "include/picolibc/sys/cdefs.h", + ], + includes = ["include/picolibc"], + # It's hard to properly constrain compatibility since `auto` may select this, + # so just tag as manual. + tags = ["manual"], + target_compatible_with = compatible_with_rp2(), ) cc_library( diff --git a/src/rp2_common/pico_clib_interface/CMakeLists.txt b/src/rp2_common/pico_clib_interface/CMakeLists.txt index 84d3faf62..e080bd34d 100644 --- a/src/rp2_common/pico_clib_interface/CMakeLists.txt +++ b/src/rp2_common/pico_clib_interface/CMakeLists.txt @@ -21,6 +21,10 @@ if (NOT TARGET pico_clib_interface) # PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS=0 #) + target_include_directories(pico_picolibc_interface SYSTEM INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/include/picolibc + ) + # ---- llvm_libc ---- pico_add_library(pico_llvm_libc_interface) diff --git a/src/rp2_common/pico_clib_interface/include/llvm_libc/time.h b/src/rp2_common/pico_clib_interface/include/llvm_libc/time.h index bb37c7eff..df3d11d29 100644 --- a/src/rp2_common/pico_clib_interface/include/llvm_libc/time.h +++ b/src/rp2_common/pico_clib_interface/include/llvm_libc/time.h @@ -9,15 +9,15 @@ #include <__llvm-libc-common.h> +#include #include #include __BEGIN_C_DECLS struct tm* localtime_r(const time_t* timer, struct tm* buf); +time_t mktime(struct tm *); __END_C_DECLS -#include_next - #endif // _PICO_LLVM_LIBC_TIME_H diff --git a/src/rp2_common/pico_clib_interface/include/picolibc/sys/cdefs.h b/src/rp2_common/pico_clib_interface/include/picolibc/sys/cdefs.h new file mode 100644 index 000000000..5492e7864 --- /dev/null +++ b/src/rp2_common/pico_clib_interface/include/picolibc/sys/cdefs.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PICO_PICOLIBC_SYS_CDEFS_H +#define __PICO_PICOLIBC_SYS_CDEFS_H + +#if defined(__STDC__) || defined(__cplusplus) + +#define __CONCAT1(x,y) x ## y +#define __CONCAT(x,y) __CONCAT1(x,y) +#define __STRING(x) #x +#define __XSTRING(x) __STRING(x) + +#endif + +#define __unused __attribute__((__unused__)) +#define __used __attribute__((__used__)) +#define __packed __attribute__((__packed__)) +#define __aligned(x) __attribute__((__aligned__(x))) + +#define __always_inline __inline__ __attribute__((__always_inline__)) +#define __noinline __attribute__((__noinline__)) + +#define __printflike(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf__, fmtarg, firstvararg))) + +#include_next + +#endif 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 dfcab015e..c852bcb2e 100644 --- a/src/rp2_common/pico_clib_interface/llvm_libc_interface.c +++ b/src/rp2_common/pico_clib_interface/llvm_libc_interface.c @@ -7,11 +7,11 @@ #include #include #include -#include -#include - #include +#include "include/llvm_libc/time.h" +#include "include/llvm_libc/sys/time.h" + #include "pico/runtime_init.h" #include "pico/stdio.h" #include "pico/time.h" diff --git a/src/rp2_common/pico_clib_interface/picolibc_interface.c b/src/rp2_common/pico_clib_interface/picolibc_interface.c index 63d79135e..d73ef3f97 100644 --- a/src/rp2_common/pico_clib_interface/picolibc_interface.c +++ b/src/rp2_common/pico_clib_interface/picolibc_interface.c @@ -124,9 +124,19 @@ void runtime_init(void) { runtime_init_per_core_install_stack_guard(&__StackBottom); #endif - // piolibc __libc_init_array does __preint_array and __init_array - extern void __libc_init_array(void); - __libc_init_array(); + // todo maybe we want to do this in the future, but it does stuff like register_tm_clones + // which we didn't do in previous SDKs + //extern void __libc_init_array(void); + //__libc_init_array(); + + // ... so instead just do the __preinit_array + runtime_run_initializers(); + // ... and the __init_array + extern void (*__init_array_start)(void); + extern void (*__init_array_end)(void); + for (void (**p)(void) = &__init_array_start; p < &__init_array_end; ++p) { + (*p)(); + } } #if !PICO_RUNTIME_NO_INIT_PER_CORE_TLS_SETUP @@ -151,4 +161,4 @@ PICO_RUNTIME_INIT_FUNC_PER_CORE(runtime_init_pre_core_tls_setup, PICO_RUNTIME_IN // "ldr r0, =__tls_base\n" // "bx lr\n" // ); -//} \ No newline at end of file +//}