1#
2# Arm SCP/MCP Software
3# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
4#
5# SPDX-License-Identifier: BSD-3-Clause
6#
7
8STEPS=4
9
10llvm_version=$1
11
12SCRIPT_NAME=$(basename "$0")
13TMP_FOLDER=/tmp/"${SCRIPT_NAME}_data"
14LOG_OUTPUT_FILE=${TMP_FOLDER}/out.log
15
16# helper functions
17error() {
18    >&2 echo "error: $@"
19    echo "error: $@" >> "$LOG_OUTPUT_FILE"
20}
21
22log() {
23    echo -n "$@" >> "$LOG_OUTPUT_FILE"
24}
25
26logln() {
27    echo "$@" >> "$LOG_OUTPUT_FILE"
28}
29
30lindent() {
31    log "  $@"
32}
33
34lindentln() {
35    logln "  $@"
36}
37
38println() {
39    logln "$@"
40    echo "$@"
41}
42
43indentln() {
44    lindentln "$@"
45    echo "  $@"
46}
47
48indent() {
49    lindent "$@"
50    echo -n "  $@"
51}
52
53input() {
54    read -p "$1" "$2"
55    logln "$1$$2"
56}
57
58step() {
59    STEP=$1
60    shift
61    println "[$STEP/$STEPS] $@"
62}
63
64eexit() {
65    >&2 echo
66    >&2 echo "error: please find the complete logs in ${LOG_OUTPUT_FILE}. Aborting..."
67    exit 1
68}
69
70cmd() {
71    logln "$ $@"
72    eval "$@" >> "$LOG_OUTPUT_FILE" 2>&1 || { echo "error!"; eexit; }
73}
74
75cmdp() {
76    logln "$1"
77    echo -n "  $1..."
78    shift
79    cmd "$@"
80    echo "ok!"
81}
82
83echo "Setting up temporary directory at ${TMP_FOLDER}"
84mkdir -p "$TMP_FOLDER"
85echo -n "" > "$LOG_OUTPUT_FILE"
86
87
88# Step 1 : obtaining the GNU Arm Embedded Toolchain sysroot for later...
89
90step 1 "Obtaining the sysroot of the GNU Arm Embedded Toolchain..."
91SYSROOT=""
92
93if [[ -n $GCC_TOOLCHAIN ]]; then
94    lindentln "\$GCC_TOOLCHAIN was found set, using it..."
95    SYSROOT=${GCC_TOOLCHAIN}/arm-none-eabi
96elif command -v arm-none-eabi-gcc &> /dev/null; then
97    lindentln "arm-none-eabi-gcc was found! Fetching the sysroot..."
98    SYSROOT=$(arm-none-eabi-gcc -print-sysroot)
99else
100    indentln "Could not find the GNU Arm Embedded Toolchain!"
101    indentln
102    indentln "Please enter the path to the GNU Arm Embedded Toolchain:"
103    input "> " GCC_TOOLCHAIN
104
105    SYSROOT=${GCC_TOOLCHAIN}/arm-none-eabi
106fi
107
108if [[ ! -d $SYSROOT ]]; then
109    error "${GCC_TOOLCHAIN} is not a valid GNU Arm Embedded Toolchain path!"
110    eexit
111fi
112
113step 1 "Toolchain sysroot found at: ${SYSROOT}"
114
115# Step 2: retrieve LLVM
116step 2 "Installing the LLVM ${llvm_version} toolchain..."
117lindentln "Checking if clang-${llvm_version} is present in the path..."
118if command -v clang-${llvm_version} &> /dev/null; then
119    indentln "LLVM {llvm_version} is already installed! Skipping..."
120else
121    cmdp "Downloading the LLVM installation script" wget https://apt.llvm.org/llvm.sh -O $TMP_FOLDER/install-llvm.sh
122    cmd chmod +x $TMP_FOLDER/install-llvm.sh
123    cmdp "Downloading and installing LLVM ${llvm_version} (this will take a while)" $TMP_FOLDER/install-llvm.sh ${llvm_version}
124fi
125
126# Step 3: Retrieving Compiler-RT source code
127step 3 "Installing the Compiler-RT Arm builtins..."
128cmdp "Downloading the source code" wget https://github.com/llvm/llvm-project/releases/download/llvmorg-${llvm_version}.0.1/compiler-rt-${llvm_version}.0.1.src.tar.xz -O ${TMP_FOLDER}/rt-src.tar.xz
129cmdp "Extracting the source code" tar -xf ${TMP_FOLDER}/rt-src.tar.xz -C ${TMP_FOLDER}
130cmd cd ${TMP_FOLDER}/compiler-rt-${llvm_version}.0.1.src
131
132BAREMETAL_PATH=$(clang-${llvm_version} -print-resource-dir)/lib/baremetal
133cmd mkdir -p $BAREMETAL_PATH
134
135for ARCH in armv7m armv7em armv8m.main armv8.1m.main; do
136    cmdp "Preparing Compiler-RT builtins for target ${ARCH}" cmake -GNinja \
137        -DLLVM_CONFIG_PATH=$(command -v llvm-config-${llvm_version}) \
138        -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
139        -DCOMPILER_RT_OS_DIR="baremetal" \
140        -DCOMPILER_RT_BUILD_BUILTINS=ON \
141        -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
142        -DCOMPILER_RT_BUILD_XRAY=OFF \
143        -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
144        -DCOMPILER_RT_BUILD_PROFILE=OFF \
145        -DCMAKE_C_COMPILER=$(command -v clang-${llvm_version}) \
146        -DCMAKE_C_COMPILER_TARGET="${ARCH}-none-eabi" \
147        -DCMAKE_ASM_COMPILER_TARGET="${ARCH}-none-eabi" \
148        -DCMAKE_AR=$(command -v llvm-ar-${llvm_version}) \
149        -DCMAKE_NM=$(command -v llvm-nm-${llvm_version}) \
150        -DCMAKE_RANLIB=$(command -v llvm-ranlib-${llvm_version}) \
151        -DCOMPILER_RT_BAREMETAL_BUILD=ON \
152        -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
153        -DCOMPILER_RT_INCLUDE_TESTS=OFF \
154        -DCMAKE_C_FLAGS=\"-march=${ARCH} -mthumb -mfpu=none -mfloat-abi=soft \
155            -I${SYSROOT}/include\" \
156        -DCMAKE_ASM_FLAGS=\"-march=${ARCH} -mthumb -mfpu=none -mfloat-abi=soft \
157            -I${SYSROOT}/include\"
158    cmdp "Building builtins for target ${ARCH}" ninja builtins
159    cmdp "Installing the builtins" \
160        cp ./lib/baremetal/libclang_rt.builtins-arm.a \
161           ${BAREMETAL_PATH}/libclang_rt.builtins-${ARCH}.a
162done
163
164echo
165rm -rf ${TMP_FOLDER}
166