diff --git a/.github/workflows/build_sdk_libraries.yml b/.github/workflows/build_sdk_libraries.yml new file mode 100644 index 000000000..13f3c4e76 --- /dev/null +++ b/.github/workflows/build_sdk_libraries.yml @@ -0,0 +1,96 @@ +name: Build SDK libraries and make PR to update them +permissions: + contents: read + +on: + workflow_dispatch: + inputs: + target_sdk_branch: + type: string + required: false + default: 'master' + create_pr: + type: boolean + required: false + default: false + +env: + GIT_USER_EMAIL: 'ledger@github.com' + GIT_USER_NAME: 'SDKLibsUpdaterGithub' + UPDATE_BRANCH: 'sdk_libs_update' + +jobs: + build: + runs-on: ubuntu-latest + container: + image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest + strategy: + fail-fast: false + matrix: + target: + - core: cortex-m3 + se: st33 + - core: cortex-m35p+nodsp + se: st33k1 + + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: | + tools/build_clangrt_builtins.sh + tools/build_newlib.sh + sparse-checkout-cone-mode: false + + - run: ./tools/build_clangrt_builtins.sh -t ${{ matrix.target.core }} -o artifact/arch/${{ matrix.target.se }}/lib + + - run: ./tools/build_newlib.sh -t ${{ matrix.target.core }} -o artifact/arch/${{ matrix.target.se }}/lib + + - uses: actions/upload-artifact@v4 + with: + name: arch-${{ matrix.target.se }} + path: artifact/ + + merge: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/upload-artifact/merge@v4 + with: + name: arch + pattern: arch-* + delete-merged: true + + pr_create: + needs: merge + runs-on: ubuntu-latest + if: ${{ success() && inputs.create_pr }} + continue-on-error: true + permissions: + contents: write + pull-requests: write + steps: + - name: Clone repository + uses: actions/checkout@v4 + with: + # by default the action uses fetch-depth = 1, which creates + # shallow repositories from which we can't push + fetch-depth: 0 + ref: ${{ inputs.target_sdk_branch }} + + - name: Download Binaries artifact + uses: actions/download-artifact@v4 + with: + name: arch + + - name: PR creation + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TARGET_BRANCH: ${{ inputs.target_sdk_branch }} + run: | + git config --global user.email "$GIT_USER_EMAIL" + git config --global user.name "$GIT_USER_NAME" + git switch --create "$UPDATE_BRANCH" + git add -A . + git commit -m 'Updating static SDK libraries' + git push -u origin "$UPDATE_BRANCH" + gh pr create -B "$TARGET_BRANCH" --title '[SDK_LIBS_UPDATE] Updating static SDK libraries' --body 'Created by Github workflow "${{ github.workflow }}", job "${{ github.job }}", run "${{ github.run_id }}".' diff --git a/Makefile.standard_app b/Makefile.standard_app index a336faa7a..9b0db1939 100644 --- a/Makefile.standard_app +++ b/Makefile.standard_app @@ -255,14 +255,16 @@ APP_FLAGS_APP_LOAD_PARAMS = $(shell printf '0x%x' $$(( $(STANDARD_APP_FLAGS) + $ CC = $(CLANGPATH)clang AS = $(CLANGPATH)clang ifeq ($(TARGET_NAME),TARGET_NANOS) - LD = $(GCCPATH)arm-none-eabi-gcc + LD = $(GCCPATH)arm-none-eabi-gcc + LDLIBS += -lgcc else - LD = $(CLANGPATH)clang + LD = $(CLANGPATH)clang + LDLIBS += -lclang_rt.builtins endif AFLAGS += --target=arm-none-eabi -LDLIBS += -lm -lgcc -lc +LDLIBS += -lm -lc ##################################################################### # MISC # diff --git a/arch/st33/lib/libc.a b/arch/st33/lib/libc.a index 1c9151d7b..97c720704 100644 Binary files a/arch/st33/lib/libc.a and b/arch/st33/lib/libc.a differ diff --git a/arch/st33/lib/libclang_rt.builtins.a b/arch/st33/lib/libclang_rt.builtins.a new file mode 100644 index 000000000..36badb5d8 Binary files /dev/null and b/arch/st33/lib/libclang_rt.builtins.a differ diff --git a/arch/st33/lib/libm.a b/arch/st33/lib/libm.a index 63f3b5491..76c4bf6a8 100644 Binary files a/arch/st33/lib/libm.a and b/arch/st33/lib/libm.a differ diff --git a/arch/st33k1/lib/libc.a b/arch/st33k1/lib/libc.a index c45268e7b..f765914f1 100644 Binary files a/arch/st33k1/lib/libc.a and b/arch/st33k1/lib/libc.a differ diff --git a/arch/st33k1/lib/libclang_rt.builtins.a b/arch/st33k1/lib/libclang_rt.builtins.a new file mode 100644 index 000000000..a7b24160a Binary files /dev/null and b/arch/st33k1/lib/libclang_rt.builtins.a differ diff --git a/arch/st33k1/lib/libm.a b/arch/st33k1/lib/libm.a index ae7388dd2..86da81643 100644 Binary files a/arch/st33k1/lib/libm.a and b/arch/st33k1/lib/libm.a differ diff --git a/tools/build_clangrt_builtins.sh b/tools/build_clangrt_builtins.sh new file mode 100755 index 000000000..55460dc08 --- /dev/null +++ b/tools/build_clangrt_builtins.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +set -e + +TARGET_CPU="" +OUTPUT_DIR="" + +while getopts "t:o:" opt +do + case "$opt" in + t) + TARGET_CPU="$OPTARG" + ;; + o) + OUTPUT_DIR="$OPTARG" + ;; + ?) + exit 1 + ;; + esac +done +shift "$((OPTIND - 1))" + +if [ -z "$TARGET_CPU" ] || [ -z "$OUTPUT_DIR" ] +then + echo "Usage: $0 -t TARGET_CPU -o OUTPUT_FILE" >&2 + exit 1 +fi + +mkdir -p "$OUTPUT_DIR" +OUTPUT_DIR=$(realpath "$OUTPUT_DIR") + +# enable source repository +sed -i 's/^\(Types: deb\)$/\1 deb-src/g' /etc/apt/sources.list.d/debian.sources + +apt update + +apt install -y --no-install-recommends \ + dpkg-dev \ + llvm-dev + +LLVM_VERSION=$(clang --version | head -n1 | rev | cut -d" " -f1 | rev) +LLVM_MAJOR_VERSION=$(echo "$LLVM_VERSION" | cut -d. -f1) + +cd /tmp + +LLVM_DIR="llvm-toolchain-$LLVM_MAJOR_VERSION-$LLVM_VERSION" +if [ ! -d "$LLVM_DIR" ] +then + # install Debian source package + apt source "llvm-toolchain-$LLVM_MAJOR_VERSION" +fi + +cd "$LLVM_DIR" +rm -rf build +mkdir build +cd build + +TARGET=arm-none-eabi +SYSROOT=/usr/lib/arm-none-eabi + +cmake ../compiler-rt \ + -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \ + -DCOMPILER_RT_OS_DIR="baremetal" \ + -DCOMPILER_RT_BUILD_BUILTINS=ON \ + -DCOMPILER_RT_BUILD_CRT=OFF \ + -DCOMPILER_RT_BUILD_SANITIZERS=OFF \ + -DCOMPILER_RT_BUILD_XRAY=OFF \ + -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \ + -DCOMPILER_RT_BUILD_PROFILE=OFF \ + -DCOMPILER_RT_BUILD_MEMPROF=OFF \ + -DCOMPILER_RT_BUILD_ORC=OFF \ + -DCMAKE_C_COMPILER="$(which clang)" \ + -DCMAKE_C_COMPILER_TARGET="${TARGET}" \ + -DCMAKE_ASM_COMPILER_TARGET="${TARGET}" \ + -DCMAKE_AR="$(which llvm-ar)" \ + -DCMAKE_NM="$(which llvm-nm)" \ + -DCMAKE_RANLIB="$(which llvm-ranlib)" \ + -DCOMPILER_RT_BAREMETAL_BUILD=ON \ + -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \ + -DLLVM_CONFIG_PATH="$(which llvm-config)" \ + -DCOMPILER_RT_HAS_FPIC_FLAG=OFF \ + -DCMAKE_C_FLAGS="-mcpu=${TARGET_CPU} -mlittle-endian -mthumb -Oz -g0 -fropi -frwpi" \ + -DCMAKE_ASM_FLAGS="-mcpu=${TARGET_CPU} -mlittle-endian -mthumb" \ + -DCMAKE_SYSROOT="$SYSROOT" +make -j +mkdir -p "$OUTPUT_DIR" +cp lib/baremetal/libclang_rt.builtins-arm.a "$OUTPUT_DIR/libclang_rt.builtins.a" diff --git a/tools/build_newlib.sh b/tools/build_newlib.sh new file mode 100755 index 000000000..22aa604fa --- /dev/null +++ b/tools/build_newlib.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash + +set -exu + +TARGET_CPU="" +OUTPUT_DIR="" + +while getopts "t:o:" opt +do + case "$opt" in + t) + TARGET_CPU="$OPTARG" + ;; + o) + OUTPUT_DIR="$OPTARG" + ;; + ?) + exit 1 + ;; + esac +done +shift "$((OPTIND - 1))" + +if [ -z "${TARGET_CPU}" ] || [ -z "${OUTPUT_DIR}" ] +then + echo "Usage: $0 -t TARGET_CPU -o OUTPUT_FILE" >&2 + exit 1 +fi + +mkdir -p "$OUTPUT_DIR" +OUTPUT_DIR=$(realpath "$OUTPUT_DIR") + +# Working in a temporary folder +mkdir tmp && cd tmp + +# Enabling source repository +sed -i 's/^\(Types: deb\)$/\1 deb-src/g' /etc/apt/sources.list.d/debian.sources + +# Installing newlib build dependencies +apt update +apt install -y --no-install-recommends texinfo dpkg-dev + +# Get the latest fixed version for this OS version +apt source newlib + +# Entering the source directory +cd */ + +# ENV SETUP +WORKDIR="$(pwd)" +#SRC="${WORKDIR}/newlib" +BUILD="${WORKDIR}/arm_none_eabi_build" +INSTALL="${WORKDIR}/arm_none_eabi_install" + +# Build configuration +mkdir -p "${BUILD}" "${INSTALL}" +cd "${BUILD}" + +CFLAGS_FOR_TARGET="-ffunction-sections -fdata-sections -fshort-wchar -DPREFER_SIZE_OVER_SPEED -mcpu=${TARGET_CPU} -mthumb -mlittle-endian" \ + ../configure \ + `# Setup` \ + --host=x86_64-linux-gnu `# Host` \ + --target=arm-none-eabi ` # Target` \ + --disable-multilib `# Building only one library` \ + --prefix="${INSTALL}" `# Installation prefix` \ + `# Options` \ + --disable-silent-rules `# verbose build output (undo: "make V=0")` \ + --disable-dependency-tracking `# speeds up one-time build` \ + --enable-newlib-reent-small `# enable small reentrant struct support` \ + --disable-newlib-fvwrite-in-streamio `# disable iov in streamio ` \ + --disable-newlib-fseek-optimization `# disable fseek optimization` \ + --disable-newlib-wide-orient `# Turn off wide orientation in streamio`\ + --enable-newlib-nano-malloc `# use small-footprint nano-malloc implementation`\ + --disable-newlib-unbuf-stream-opt `# disable unbuffered stream optimization in streamio` \ + --enable-lite-exit `# enable light weight exit` \ + --enable-newlib-global-atexit `# enable atexit data structure as global` \ + --enable-newlib-nano-formatted-io `# Use small-footprint nano-formatted-IO implementation`\ + --disable-newlib-supplied-syscalls `# disable newlib from supplying syscalls`\ + --disable-nls `# do not use Native Language Support` \ + --enable-target-optspace `# optimize for space (emits -g -Os)` + + +# Compilation +make "-j$(nproc)" +make install + +# Removing the .ARM.exidx section +arm-none-eabi-objcopy -R .ARM.exidx "${INSTALL}/arm-none-eabi/lib/libc.a" + +# Stripping debug symbols +arm-none-eabi-strip --strip-debug "${INSTALL}/arm-none-eabi/lib/libc.a" +arm-none-eabi-strip --strip-debug "${INSTALL}/arm-none-eabi/lib/libm.a" + +# Copy back +cp "${INSTALL}/arm-none-eabi/lib/libc.a" "$OUTPUT_DIR" +cp "${INSTALL}/arm-none-eabi/lib/libm.a" "$OUTPUT_DIR"