Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add newlib-nano as multilib #60

Open
wants to merge 3 commits into
base: arm-software
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions arm-software/embedded/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ set(LLVM_TOOLCHAIN_C_LIBRARY
"Which C library to use."
)
set_property(CACHE LLVM_TOOLCHAIN_C_LIBRARY
PROPERTY STRINGS picolibc newlib llvmlibc)
PROPERTY STRINGS picolibc newlib newlib-nano llvmlibc)

option(
SHORT_BUILD_PATHS
Expand Down Expand Up @@ -286,7 +286,7 @@ include(ProcessorCount)
if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL picolibc)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/fetch_picolibc.cmake)
endif()
if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL newlib)
if(LLVM_TOOLCHAIN_C_LIBRARY MATCHES "^newlib")
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/fetch_newlib.cmake)
endif()

Expand All @@ -309,18 +309,18 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
endif()
##################################################################################################

if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL newlib)
if(LLVM_TOOLCHAIN_C_LIBRARY MATCHES "^newlib")
install(
FILES
${CMAKE_CURRENT_SOURCE_DIR}/newlib.cfg
${CMAKE_CURRENT_SOURCE_DIR}/${LLVM_TOOLCHAIN_C_LIBRARY}.cfg
DESTINATION bin
COMPONENT llvm-toolchain-newlib-configs
COMPONENT llvm-toolchain-${LLVM_TOOLCHAIN_C_LIBRARY}-configs
)
install(
DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}/newlib-samples/
DESTINATION samples
COMPONENT llvm-toolchain-newlib-configs
COMPONENT llvm-toolchain-${LLVM_TOOLCHAIN_C_LIBRARY}-configs
)
endif()

Expand Down Expand Up @@ -731,7 +731,7 @@ if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL picolibc)
${picolibc_SOURCE_DIR}/COPYING.picolibc COPYING.picolibc
)
endif()
if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL newlib)
if(LLVM_TOOLCHAIN_C_LIBRARY MATCHES "^newlib")
list(APPEND third_party_license_files
${newlib_SOURCE_DIR}/COPYING.NEWLIB COPYING.NEWLIB
${newlib_SOURCE_DIR}/COPYING.LIBGLOSS COPYING.LIBGLOSS
Expand Down
4 changes: 2 additions & 2 deletions arm-software/embedded/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ bare-metal LLVM based toolchain targeting Arm based on:
* libc++abi
* libc++
* compiler-rt
* picolibc, or optionally newlib or LLVM's libc
* picolibc, or optionally newlib(-nano) or LLVM's libc

## Goal

Expand Down Expand Up @@ -191,7 +191,7 @@ relying on the Arm GNU Toolchain.
> *Note:* `picolibc` provides excellent
> [support for Arm GNU Toolchain](https://github.com/picolibc/picolibc/blob/main/doc/using.md),
> so projects that require using both Arm GNU Toolchain and Arm Toolchain for Embedded
> can choose either `picolibc` or `newlib`.
> can choose either `picolibc` or `newlib`/`newlib-nano`.

## Building from source

Expand Down
4 changes: 2 additions & 2 deletions arm-software/embedded/arm-multilib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ set(llvmproject_src_dir ${TOOLCHAIN_SOURCE_DIR}/../..)
set(MULTILIB_JSON "" CACHE STRING "JSON file to load library definitions from.")
set(ENABLE_VARIANTS "all" CACHE STRING "Semicolon separated list of variants to build, or \"all\". Must match entries in the json.")
set(C_LIBRARY "picolibc" CACHE STRING "Which C library to use.")
set_property(CACHE C_LIBRARY PROPERTY STRINGS picolibc newlib llvmlibc)
set_property(CACHE C_LIBRARY PROPERTY STRINGS picolibc newlib newlib-nano llvmlibc)
set(PROJECT_PREFIX "${CMAKE_BINARY_DIR}/lib-builds" CACHE STRING "Directory to build subprojects in.")
option(
NUMERICAL_BUILD_NAMES
Expand Down Expand Up @@ -95,7 +95,7 @@ include(ExternalProject)
if(C_LIBRARY STREQUAL picolibc)
include(${TOOLCHAIN_SOURCE_DIR}/cmake/fetch_picolibc.cmake)
list(APPEND passthrough_dirs "-DFETCHCONTENT_SOURCE_DIR_PICOLIBC=${FETCHCONTENT_SOURCE_DIR_PICOLIBC}")
elseif(C_LIBRARY STREQUAL newlib)
elseif(C_LIBRARY MATCHES "^newlib")
include(${TOOLCHAIN_SOURCE_DIR}/cmake/fetch_newlib.cmake)
list(APPEND passthrough_dirs "-DFETCHCONTENT_SOURCE_DIR_NEWLIB=${FETCHCONTENT_SOURCE_DIR_NEWLIB}")
endif()
Expand Down
66 changes: 50 additions & 16 deletions arm-software/embedded/arm-runtimes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ set(llvmproject_src_dir ${TOOLCHAIN_SOURCE_DIR}/../..)
# CMake arguments are loaded from the JSON file depending on which C
# library is used, so this must be set before the JSON is processed.
set(C_LIBRARY "picolibc" CACHE STRING "Which C library to use.")
set_property(CACHE C_LIBRARY PROPERTY STRINGS picolibc newlib llvmlibc)
set_property(CACHE C_LIBRARY PROPERTY STRINGS picolibc newlib newlib-nano llvmlibc)

set(VARIANT_JSON "" CACHE STRING "JSON file to load args from.")
if(VARIANT_JSON)
Expand All @@ -37,7 +37,12 @@ if(VARIANT_JSON)
set(${json_param}_def ${json_val})
endforeach()
# Load arguments specific to the chosen library, overwriting any existing values.
string(JSON json_args GET ${variant_json_read} "args" ${C_LIBRARY})
if(C_LIBRARY MATCHES "^newlib")
# Treat newlib variants as newlib for library compatibility
string(JSON json_args GET ${variant_json_read} "args" "newlib")
else()
string(JSON json_args GET ${variant_json_read} "args" ${C_LIBRARY})
endif()
string(JSON json_args_len LENGTH ${json_args})
math(EXPR json_args_len_dec "${json_args_len} - 1")
foreach(json_idx RANGE ${json_args_len_dec})
Expand Down Expand Up @@ -85,7 +90,7 @@ set(PICOLIBC_BUILD_TYPE ${PICOLIBC_BUILD_TYPE_def} CACHE STRING "Picolibc config
set_property(CACHE PICOLIBC_BUILD_TYPE PROPERTY STRINGS minsize release)

set(ENABLE_CXX_LIBS ${ENABLE_CXX_LIBS_def} CACHE BOOL "Build CXX libs")
set(ENABLE_LIBC_TESTS ${ENABLE_LIBC_TESTS_def} CACHE BOOL "Enable libc tests (picolibc, newlib or llvm-libc).")
set(ENABLE_LIBC_TESTS ${ENABLE_LIBC_TESTS_def} CACHE BOOL "Enable libc tests (picolibc, newlib, newlib-nano or llvm-libc).")
set(ENABLE_COMPILER_RT_TESTS ${ENABLE_COMPILER_RT_TESTS_def} CACHE BOOL "Enable compiler-rt tests.")
set(ENABLE_LIBCXX_TESTS ${ENABLE_LIBCXX_TESTS_def} CACHE BOOL "Enable libcxx tests.")
set(LLVM_BINARY_DIR "" CACHE PATH "Path to LLVM toolchain root to build libraries with")
Expand Down Expand Up @@ -459,11 +464,44 @@ endif()
# newlib
###############################################################################

if(C_LIBRARY STREQUAL newlib)
if(C_LIBRARY MATCHES "^newlib")
if(ENABLE_LIBC_TESTS)
message(FATAL_ERROR "Tests cannot yet be enabled using newlib libc.")
endif()

if(C_LIBRARY STREQUAL newlib-nano)
# Taken from https://gitlab.arm.com/tooling/gnu-devtools-for-arm/-/blob/main/build-baremetal-toolchain.sh#L582
set(newlib_flags
--disable-newlib-supplied-syscalls
--disable-nls
--enable-lite-exit
--disable-multilib
--enable-newlib-retargetable-locking
--enable-newlib-nano-malloc
--disable-newlib-unbuf-stream-opt
--enable-newlib-reent-small
--disable-newlib-fseek-optimization
--enable-newlib-nano-formatted-io
--disable-newlib-fvwrite-in-streamio
--disable-newlib-wide-orient
--enable-lite-exit
--enable-newlib-global-atexit)
set(newlib_optim_flags
"-g -Oz")
else()
set(newlib_flags
--enable-newlib-io-long-long
--enable-newlib-register-fini
--disable-newlib-supplied-syscalls
--enable-newlib-io-c99-formats
--disable-nls
--enable-lite-exit
--disable-multilib
--enable-newlib-retargetable-locking)
set(newlib_optim_flags
"-g -O2")
endif()

include(${TOOLCHAIN_SOURCE_DIR}/cmake/fetch_newlib.cmake)
set(build_env
"CC_FOR_TARGET=${LLVM_BINARY_DIR}/bin/clang -target ${target_triple} -ffreestanding"
Expand All @@ -474,8 +512,8 @@ if(C_LIBRARY STREQUAL newlib)
"RANLIB_FOR_TARGET=${LLVM_BINARY_DIR}/bin/llvm-ranlib"
"READELF_FOR_TARGET=${LLVM_BINARY_DIR}/bin/llvm-readelf"
"STRIP_FOR_TARGET=${LLVM_BINARY_DIR}/bin/llvm-strip"
"CFLAGS_FOR_TARGET=${flags} -Wno-error=implicit-function-declaration -D__USES_INITFINI__ -U_HAVE_INIT_FINI --sysroot ${TEMP_LIB_DIR}"
"CCASFLAGS=${flags} -Wno-error=implicit-function-declaration -D__USES_INITFINI__ -U_HAVE_INIT_FINI --sysroot ${TEMP_LIB_DIR}"
"CFLAGS_FOR_TARGET=${flags} ${newlib_optim_flags} ${lib_compile_flags} -Wno-error=implicit-function-declaration -D__USES_INITFINI__ -U_HAVE_INIT_FINI"
"CCASFLAGS=${flags} ${newlib_optim_flags} ${lib_compile_flags} -Wno-error=implicit-function-declaration -D__USES_INITFINI__ -U_HAVE_INIT_FINI"
)

include(ProcessorCount)
Expand All @@ -486,7 +524,7 @@ if(C_LIBRARY STREQUAL newlib)
endif()

ExternalProject_Add(
newlib
${C_LIBRARY}
STAMP_DIR ${PROJECT_PREFIX}/newlib/${VARIANT_BUILD_ID}/stamp
BINARY_DIR ${PROJECT_PREFIX}/newlib/${VARIANT_BUILD_ID}/build
DOWNLOAD_DIR ${PROJECT_PREFIX}/newlib/${VARIANT_BUILD_ID}/dl
Expand All @@ -499,14 +537,7 @@ if(C_LIBRARY STREQUAL newlib)
--target=${target_triple}
--prefix "${TEMP_LIB_DIR}"
--exec_prefix <BINARY_DIR>/tmpinstall
--enable-newlib-io-long-long
--enable-newlib-register-fini
--disable-newlib-supplied-syscalls
--enable-newlib-io-c99-formats
--disable-nls
--enable-lite-exit
--disable-multilib
--enable-newlib-retargetable-locking
${newlib_flags}
BUILD_COMMAND
${CMAKE_COMMAND} -E env ${build_env}
make ${make_flags}
Expand Down Expand Up @@ -690,7 +721,7 @@ if(ENABLE_CXX_LIBS)
-DLLVM_LIT_ARGS=${cxxlibs_lit_args}
)
endif()
elseif(C_LIBRARY STREQUAL newlib)
elseif(C_LIBRARY MATCHES "^newlib")
set(cxxlibs_extra_cmake_options
-DLIBCXXABI_ENABLE_THREADS=OFF
-DLIBCXX_ENABLE_MONOTONIC_CLOCK=OFF
Expand All @@ -703,6 +734,9 @@ if(ENABLE_CXX_LIBS)
-DLIBCXX_ENABLE_EXCEPTIONS=${ENABLE_EXCEPTIONS}
-DLIBCXX_ENABLE_RTTI=${ENABLE_RTTI}
)
if(C_LIBRARY STREQUAL newlib-nano)
set(lib_compile_flags "${lib_compile_flags} -g -Oz")
endif()
endif()

ExternalProject_Add(
Expand Down
8 changes: 7 additions & 1 deletion arm-software/embedded/cmake/generate_version_txt.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ if(NOT ${armtoolchain_COMMIT} MATCHES "^[a-f0-9]+$")
endif()

if(NOT (LLVM_TOOLCHAIN_C_LIBRARY STREQUAL llvmlibc)) # libc in a separate repo?
if(LLVM_TOOLCHAIN_C_LIBRARY MATCHES "^newlib")
set(base_library newlib)
else()
set(base_library $(LLVM_TOOLCHAIN_C_LIBRARY))
endif()

execute_process(
COMMAND git -C ${${LLVM_TOOLCHAIN_C_LIBRARY}_SOURCE_DIR} rev-parse HEAD
COMMAND git -C ${${base_library}_SOURCE_DIR} rev-parse HEAD
OUTPUT_VARIABLE ${LLVM_TOOLCHAIN_C_LIBRARY}_COMMIT
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY
Expand Down
4 changes: 2 additions & 2 deletions arm-software/embedded/docs/migrating.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Armv8-M or later architecture, including the
|Binutils​|`objdump`, `readelf`, ...|`llvm-objdump`, `llvm-readelf`, ...|
|Compiler runtime library​|`libgcc​`|`compiler-rt`​|
|Unwinder​|`libgcc`​|`libunwind`​|
|C standard library​|`newlib`, `newlib-nano`|`picolibc`|​
|C standard library​|`newlib`, `newlib-nano`|`picolibc` (or `newlib`/`newlib-nano` as overlay)|​
|C++ ABI library​|`libsupc++.a`|`libc++abi`​|​
|C++ standard library​|`libstdc++​`|`libc++`​|

Expand Down Expand Up @@ -90,7 +90,7 @@ however uses different command line options to control selection of semihosting.
|--------|-----------|------------|
|No semihosting|`--specs=nosys.specs`|
|Semihosting|`--specs=rdimon.specs`|`-nostartfiles -lcrt0-semihost -lsemihost`|
|Newlib-nano|`--specs=nano.specs`|Not available: `picolibc` is an equivalent of `newlib-nano`.
|Newlib-nano|`--specs=nano.specs`|`--config=newlib-nano.cfg` (with [`newlib-nano` overlay](./newlib.md) installed)|

## Linker

Expand Down
8 changes: 7 additions & 1 deletion arm-software/embedded/docs/newlib.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,10 @@ overlay package.

Note that the `-DLLVM_TOOLCHAIN_LIBRARY_OVERLAY_INSTALL=on` option
only generates the `newlib` package, but does not install it as part
of the `install` CMake target.
of the `install` CMake target.

## About `newlib-nano`
`newlib-nano` is provided as a separate package, and is meant to be equal
to using GCC with `--specs=nano.specs`. In order to use the nano version
of newlib, where the documentation in this file refers to `newlib`, replace
it with `newlib-nano`.
1 change: 1 addition & 0 deletions arm-software/embedded/newlib-nano.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--sysroot <CFGDIR>/../lib/clang-runtimes/newlib-nano