Skip to content
Open
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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_CLANG_RUNTIMES armv6m_soft_nofp armv6m_soft_nofp_size armv6m-unknown-none-eabi)

set(PICO_COMMON_LANG_FLAGS "--target=armv6m-none-eabi -mfloat-abi=soft -march=armv6m")

Expand Down
2 changes: 1 addition & 1 deletion cmake/preload/toolchains/pico_arm_cortex_m33_clang.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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_CLANG_RUNTIMES armv8m.main_soft_nofp armv8m.main_soft_nofp_unaligned armv8m.main_soft_nofp_unaligned_size 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_DISASM_OBJDUMP_ARGS --mcpu=cortex-m33 --arch=armv8m.main+fp+dsp)
Expand Down
47 changes: 37 additions & 10 deletions cmake/preload/toolchains/util/pico_arm_clang_common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,32 @@ endforeach()

list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES PICO_CLIB)

set(_CLANG_RUNTIMES_DIR "${PICO_COMPILER_DIR}/../lib/clang-runtimes")
set(_PICO_CLIB_PATH "${_CLANG_RUNTIMES_DIR}/arm-none-eabi")

if(NOT PICO_CLIB OR PICO_CLIB STREQUAL "" OR PICO_CLIB STREQUAL "newlib")
# newlib is 1st class choice
if(EXISTS "${_CLANG_RUNTIMES_DIR}/newlib/arm-none-eabi")
set(_PICO_CLIB_PATH "${_CLANG_RUNTIMES_DIR}/newlib/arm-none-eabi")
endif()
elseif(PICO_CLIB STREQUAL "llvm_libc")
if(EXISTS "${_CLANG_RUNTIMES_DIR}/llvmlibc/arm-none-eabi")
set(_PICO_CLIB_PATH "${_CLANG_RUNTIMES_DIR}/llvmlibc/arm-none-eabi")
endif()
elseif(PICO_CLIB STREQUAL "picolibc")
if(EXISTS "${_CLANG_RUNTIMES_DIR}/picolibc/arm-none-eabi")
set(_PICO_CLIB_PATH "${_CLANG_RUNTIMES_DIR}/picolibc/arm-none-eabi")
endif()
else()
message(FATAL_ERROR "PICO_CLIB must be one of newlib, picolib, llvm_libc or empty (but is '${PICO_CLIB}')")
endif()

foreach(PICO_CLANG_RUNTIME IN LISTS PICO_CLANG_RUNTIMES)
# LLVM embedded-toolchain for ARM style
find_path(PICO_COMPILER_SYSROOT NAMES include/stdio.h
find_path(PICO_COMPILER_SYSROOT NAMES lib/libc.a
HINTS
${PICO_COMPILER_DIR}/../lib/clang-runtimes/arm-none-eabi/${PICO_CLANG_RUNTIME}
${PICO_COMPILER_DIR}/../lib/clang-runtimes/${PICO_CLANG_RUNTIME}
${_PICO_CLIB_PATH}/${PICO_CLANG_RUNTIME}
${_CLANG_RUNTIMES_DIR}/${PICO_CLANG_RUNTIME}
)

if (PICO_COMPILER_SYSROOT)
Expand All @@ -66,7 +86,7 @@ foreach(PICO_CLANG_RUNTIME IN LISTS PICO_CLANG_RUNTIMES)
# llvm_libc style
find_path(PICO_COMPILER_SYSROOT NAMES stdio.h
HINTS
${PICO_COMPILER_DIR}/../include/${PICO_CLANG_RUNTIME}
${PICO_COMPILER_DIR}/../include/${PICO_CLANG_RUNTIME}
)
if (PICO_COMPILER_SYSROOT)
if (NOT PICO_CLIB)
Expand All @@ -76,6 +96,19 @@ foreach(PICO_CLANG_RUNTIME IN LISTS PICO_CLANG_RUNTIMES)
break()
endif()
endforeach()
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}")

# add some system includes due to structure of ATfE-21.1.1 header structure
# required for llvmlibc / newlib, NOT for picolibc
if(EXISTS "${PICO_COMPILER_SYSROOT}/../include/c++/v1")
set(PICO_COMMON_LANG_FLAGS "${PICO_COMMON_LANG_FLAGS} -isystem ${PICO_COMPILER_SYSROOT}/../include/c++/v1")
endif()
if(EXISTS "${PICO_COMPILER_SYSROOT}/../include")
set(PICO_COMMON_LANG_FLAGS "${PICO_COMMON_LANG_FLAGS} -isystem ${PICO_COMPILER_SYSROOT}/../include")
endif()

# 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
Expand All @@ -87,11 +120,5 @@ if (PICO_CLIB STREQUAL "llvm_libc")
foreach(TYPE IN ITEMS EXE SHARED MODULE)
set(CMAKE_${TYPE}_LINKER_FLAGS_INIT "-nostdlib++ -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()
include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake)
12 changes: 9 additions & 3 deletions src/rp2_common/pico_clib_interface/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
4 changes: 4 additions & 0 deletions src/rp2_common/pico_clib_interface/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
4 changes: 2 additions & 2 deletions src/rp2_common/pico_clib_interface/include/llvm_libc/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@

#include <__llvm-libc-common.h>

#include <llvm-libc-types/struct_timespec.h>
#include <llvm-libc-types/struct_tm.h>
#include <llvm-libc-types/time_t.h>

__BEGIN_C_DECLS

struct tm* localtime_r(const time_t* timer, struct tm* buf);
time_t mktime(struct tm *);

__END_C_DECLS

#include_next <time.h>

#endif // _PICO_LLVM_LIBC_TIME_H
32 changes: 32 additions & 0 deletions src/rp2_common/pico_clib_interface/include/picolibc/sys/cdefs.h
Original file line number Diff line number Diff line change
@@ -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 <sys/cdefs.h>

#endif
6 changes: 3 additions & 3 deletions src/rp2_common/pico_clib_interface/llvm_libc_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <sys/time.h>
#include <time.h>

#include <llvm-libc-types/ssize_t.h>

#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"
Expand Down
18 changes: 14 additions & 4 deletions src/rp2_common/pico_clib_interface/picolibc_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
// );
//}
//}