mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2026-10-06 06:59:08 +08:00
#618 fixed the arm9 and arm11 shell scripts, but not their .bat counterparts, and did not look at cortex_r4 and cortex_r5 at all. An audit of every build script against the files actually present in its directory found the rest. The .bat scripts for arm9, arm11, cortex_r4 and cortex_r5 still linked libc.a, libgcc.a and, for arm11, libnosys.a from their own example_build directories, and the cortex_r4 and cortex_r5 shell scripts did too. Those archives went in 6.1.10 under "Removal of unneeded files", so on Windows all four examples failed exactly as the shell versions did before #618, and on Linux the two R-profile ones still did. Link through the compiler driver, as the other examples have since #594. This does not make the examples link, and the change stops there deliberately. All four now fail the same way, undefined reference to `_fini' because their linker scripts define the .init and .fini sections but not the _init and _fini symbols, which live in crti.o and crtn.o and are omitted by -nostartfiles. Reviving four very old cores is separate work. Correct the comment on EXAMPLES_EXPECTED_TO_FAIL again. It had cortex_r4 and cortex_r5 failing for want of newlib multilib variants; they do not. All four share the single cause above, and the multilib explanation was wrong for the R-profile pair just as it was for arm9 and arm11. Verified by running each shell script: cortex_r4 and cortex_r5 fail on _fini rather than on missing files, matching arm9 and arm11. The .bat changes mirror link lines proven that way in the same directories; they cannot be run here. Three scripts are left alone and reported instead, because a blind edit could not be verified: ports_module/cortex_m3 and cortex_m4 have Windows-only .bat scripts that also name sources which are absent or differ in case, and ports_smp/mips32_interaptiv_smp needs a MIPS toolchain. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
449 lines
19 KiB
Bash
Executable File
449 lines
19 KiB
Bash
Executable File
#!/bin/bash
|
|
##############################################################################
|
|
# Copyright (c) 2026 Eclipse ThreadX contributors
|
|
#
|
|
# This program and the accompanying materials are made available under the
|
|
# terms of the MIT License which is available at
|
|
# https://opensource.org/licenses/MIT.
|
|
#
|
|
# AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5).
|
|
# The AI-generated portions may be considered public domain (CC0-1.0)
|
|
# and not subject to the project's licence. The human contributor has
|
|
# reviewed and verified that the code is correct.
|
|
#
|
|
# SPDX-License-Identifier: MIT and CC0-1.0
|
|
##############################################################################
|
|
|
|
# Builds the Arm ports with an LLVM based toolchain, in five stages: assemble
|
|
# every assembly source of every Arm gnu port, assemble again the parts guarded
|
|
# by feature macros, compile the common C sources for one core per architecture
|
|
# profile, then link the example builds, both the script-driven ones and those
|
|
# driven by CMake. Only the linking stages need a target C library.
|
|
#
|
|
# scripts/check_clang.sh # clang from PATH
|
|
# scripts/check_clang.sh --clang /path/to/clang
|
|
# CLANG=/path/to/clang scripts/check_clang.sh
|
|
#
|
|
# Options:
|
|
# --clang <path> Compiler to use; defaults to $CLANG then to clang.
|
|
# --asm-only Skip the C sources and the example builds.
|
|
# --no-examples Skip the example builds.
|
|
# --quiet Print only failures and the summary.
|
|
#
|
|
# Exit status is 0 when everything builds and 1 otherwise.
|
|
#
|
|
# Why this exists: the gnu ports are only ever built with GNU tooling, and GNU
|
|
# as accepts several non-canonical forms that LLVM's assembler rejects. Those
|
|
# forms accumulated unnoticed. This check also covers Arm Toolchain for
|
|
# Embedded, which is LLVM based and is the successor to Arm Compiler 6, so the
|
|
# ac6 code paths are exercised here as well.
|
|
#
|
|
# Arm Toolchain for Embedded releases:
|
|
# https://github.com/arm/arm-toolchain/releases
|
|
|
|
set -u
|
|
|
|
cd "$(dirname "$(realpath "$0")")/.."
|
|
|
|
CC="${CLANG:-clang}"
|
|
asm_only=0
|
|
no_examples=0
|
|
quiet=0
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
case "$1" in
|
|
--clang) [ "$#" -ge 2 ] || { echo "Error: --clang needs a path" >&2; exit 2; }; CC="$2"; shift 2 ;;
|
|
--asm-only) asm_only=1; no_examples=1; shift ;;
|
|
--no-examples) no_examples=1; shift ;;
|
|
--quiet) quiet=1; shift ;;
|
|
-h|--help) sed -n '17,33p' "$0"; exit 0 ;;
|
|
*) echo "Error: unknown option '$1'" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
say() { [ "$quiet" -eq 1 ] || echo "$@"; }
|
|
fail() { echo " FAIL: $*"; }
|
|
|
|
if ! command -v "$CC" >/dev/null 2>&1 && [ ! -x "$CC" ]; then
|
|
echo "Error: compiler '$CC' not found."
|
|
echo "Pass --clang <path>, set CLANG, or install Arm Toolchain for Embedded:"
|
|
echo " https://github.com/arm/arm-toolchain/releases"
|
|
exit 1
|
|
fi
|
|
|
|
# Resolve to an absolute path. The example stage runs the build scripts from
|
|
# inside their own directories, so a relative compiler path would stop
|
|
# resolving there.
|
|
if [ -e "$CC" ]; then
|
|
CC="$(realpath "$CC")"
|
|
else
|
|
CC="$(command -v "$CC")"
|
|
fi
|
|
|
|
say ""
|
|
say "Using: $CC"
|
|
say " $("$CC" --version | head -1)"
|
|
|
|
# Each port directory is mapped explicitly to a target triple and CPU. Do not
|
|
# replace this with prefix matching: cortex_a5* also matches cortex_a53 and
|
|
# cortex_a55, which are AArch64, and assembling those as ARM32 produces a flood
|
|
# of misleading errors.
|
|
declare -A PORT_TARGET=(
|
|
[cortex_m0]="arm-none-eabi cortex-m0 -mthumb"
|
|
[cortex_m0+]="arm-none-eabi cortex-m0plus -mthumb"
|
|
[cortex_m3]="arm-none-eabi cortex-m3 -mthumb"
|
|
[cortex_m4]="arm-none-eabi cortex-m4 -mthumb"
|
|
[cortex_m7]="arm-none-eabi cortex-m7 -mthumb"
|
|
[cortex_m23]="arm-none-eabi cortex-m23 -mthumb"
|
|
[cortex_m33]="arm-none-eabi cortex-m33 -mthumb"
|
|
[cortex_m55]="arm-none-eabi cortex-m55 -mthumb -mfloat-abi=hard"
|
|
[cortex_m85]="arm-none-eabi cortex-m85 -mthumb -mfloat-abi=hard"
|
|
[cortex_a5]="arm-none-eabi cortex-a5"
|
|
[cortex_a7]="arm-none-eabi cortex-a7"
|
|
[cortex_a8]="arm-none-eabi cortex-a8"
|
|
[cortex_a9]="arm-none-eabi cortex-a9"
|
|
[cortex_a12]="arm-none-eabi cortex-a12"
|
|
[cortex_a15]="arm-none-eabi cortex-a15"
|
|
[cortex_a17]="arm-none-eabi cortex-a17"
|
|
[cortex_a5_smp]="arm-none-eabi cortex-a5"
|
|
[cortex_a7_smp]="arm-none-eabi cortex-a7"
|
|
[cortex_a9_smp]="arm-none-eabi cortex-a9"
|
|
[cortex_r4]="arm-none-eabi cortex-r4"
|
|
[cortex_r5]="arm-none-eabi cortex-r5"
|
|
[cortex_r52]="arm-none-eabi cortex-r52"
|
|
[cortex_a34]="aarch64-none-elf cortex-a34"
|
|
[cortex_a35]="aarch64-none-elf cortex-a35"
|
|
[cortex_a53]="aarch64-none-elf cortex-a53"
|
|
[cortex_a55]="aarch64-none-elf cortex-a55"
|
|
[cortex_a57]="aarch64-none-elf cortex-a57"
|
|
[cortex_a65]="aarch64-none-elf cortex-a65"
|
|
[cortex_a65ae]="aarch64-none-elf cortex-a65ae"
|
|
[cortex_a72]="aarch64-none-elf cortex-a72"
|
|
[cortex_a73]="aarch64-none-elf cortex-a73"
|
|
[cortex_a75]="aarch64-none-elf cortex-a75"
|
|
[cortex_a76]="aarch64-none-elf cortex-a76"
|
|
[cortex_a76ae]="aarch64-none-elf cortex-a76ae"
|
|
[cortex_a77]="aarch64-none-elf cortex-a77"
|
|
[cortex_a34_smp]="aarch64-none-elf cortex-a34"
|
|
[cortex_a35_smp]="aarch64-none-elf cortex-a35"
|
|
[cortex_a53_smp]="aarch64-none-elf cortex-a53"
|
|
[cortex_a55_smp]="aarch64-none-elf cortex-a55"
|
|
[cortex_a57_smp]="aarch64-none-elf cortex-a57"
|
|
[cortex_a65_smp]="aarch64-none-elf cortex-a65"
|
|
[cortex_a65ae_smp]="aarch64-none-elf cortex-a65ae"
|
|
[cortex_a72_smp]="aarch64-none-elf cortex-a72"
|
|
[cortex_a73_smp]="aarch64-none-elf cortex-a73"
|
|
[cortex_a75_smp]="aarch64-none-elf cortex-a75"
|
|
[cortex_a76_smp]="aarch64-none-elf cortex-a76"
|
|
[cortex_a76ae_smp]="aarch64-none-elf cortex-a76ae"
|
|
[cortex_a77_smp]="aarch64-none-elf cortex-a77"
|
|
[cortex_a78_smp]="aarch64-none-elf cortex-a78"
|
|
)
|
|
|
|
# Assembly guarded by a feature macro is invisible to the stage above, which
|
|
# assembles with default flags and so lets the preprocessor discard every #ifdef
|
|
# block before the assembler sees it. These are the macros a user can turn on;
|
|
# each file carrying one is assembled again with it defined.
|
|
#
|
|
# This is not hypothetical. It is where "POP {r0, lr}" was found in the Cortex-M0
|
|
# and Cortex-M23 execution-profile paths: invalid on Armv6-M and Armv8-M
|
|
# Baseline, where the 16-bit POP takes r0-r7 and pc only, and rejected by GNU as
|
|
# well as by LLVM. Turning the feature on had never once been tried.
|
|
FEATURE_MACROS="TX_ENABLE_VFP_SUPPORT TX_ENABLE_FIQ_SUPPORT TX_LOW_POWER
|
|
TX_ENABLE_EXECUTION_CHANGE_NOTIFY"
|
|
|
|
# TX_ENABLE_IRQ_NESTING and TX_ENABLE_FIQ_NESTING are deliberately not here.
|
|
# They guard no assembly in the trees this script walks: the nesting start and end
|
|
# routines are separate files compiled unconditionally, and the macros only feed
|
|
# the TX_PORT_SPECIFIC_BUILD_OPTIONS bitfield in tx_port.h. Adding them would
|
|
# assemble nothing new and imply coverage that does not exist.
|
|
|
|
# Extra flags for the VFP paths, per core, needed only where -mcpu alone cannot
|
|
# assemble them. Cortex-R4's FPU is an option rather than part of the core, so
|
|
# both toolchains reject its VFP code without an -mfpu.
|
|
#
|
|
# Do not extend this to the A profile ports. They save D16-D31, which exists only
|
|
# on a 32-register FPU, so naming a -d16 FPU takes those registers away and turns
|
|
# 28 working files into "register expected". Their defaults are already correct.
|
|
declare -A VFP_EXTRA=(
|
|
[cortex_r4]="-mfpu=vfpv3-d16 -mfloat-abi=softfp"
|
|
)
|
|
|
|
# One core per architecture profile for the C sources. Compiling all of them
|
|
# for every core would multiply the run time without adding coverage, since the
|
|
# port headers differ by profile rather than by core.
|
|
#
|
|
# cortex_r52 earns a slot of its own next to cortex_r5 because Armv8-R AArch32
|
|
# is a separate profile rather than a variant of Armv7-R. That port is written
|
|
# by hand instead of generated from ports_arch, and its tx_port.h differs
|
|
# accordingly, so cortex_r5 does not stand in for it.
|
|
C_CORES="cortex_m0 cortex_m4 cortex_m23 cortex_m33 cortex_m55 cortex_a7 cortex_a53 cortex_r5 cortex_r52"
|
|
|
|
# Example builds driven by CMake rather than by a build_threadx.sh pair. These
|
|
# are covered by their own stage below, so the script-driven loop passes over
|
|
# them without reporting them as a gap.
|
|
CMAKE_EXAMPLE_CORES="cortex_r52"
|
|
|
|
# Example builds that are not expected to link, with the reason. Named by
|
|
# their port directory, which covers both ports/ and ports_smp/. Listed
|
|
# explicitly rather than silently skipped, so the gaps stay visible.
|
|
#
|
|
# These fail with the GNU toolchain too, so they are not LLVM problems. All four
|
|
# fail the same way, for the same reason:
|
|
#
|
|
# their linker scripts define the .init and .fini sections but not the _init
|
|
# and _fini symbols. Those come from crti.o and crtn.o, which -nostartfiles
|
|
# leaves out, so newlib's fini.c cannot resolve them and the link ends with
|
|
# "undefined reference to `_fini'". Reproduced with arm-none-eabi-gcc 13.2.1.
|
|
#
|
|
# Until 6.1.10 the four linked libc.a and libgcc.a checked in beside them, which
|
|
# supplied those symbols. That sweep removed the archives without updating the
|
|
# link lines, so for years the examples failed earlier still, on the missing
|
|
# files themselves. Fixing the link lines exposed the _fini gap underneath.
|
|
EXAMPLES_EXPECTED_TO_FAIL="arm9 arm11 cortex_r4 cortex_r5"
|
|
|
|
failures=0
|
|
skipped=""
|
|
|
|
# --------------------------------------------------------------------------
|
|
say ""
|
|
say "== Assembly sources of every Arm gnu port =="
|
|
|
|
total=0
|
|
for dir in ports/*/gnu/src ports_smp/*/gnu/src ports_module/*/gnu/src; do
|
|
[ -d "$dir" ] || continue
|
|
core="$(echo "$dir" | cut -d/ -f2)"
|
|
spec="${PORT_TARGET[$core]:-}"
|
|
if [ -z "$spec" ]; then
|
|
skipped="$skipped $core"
|
|
continue
|
|
fi
|
|
# shellcheck disable=SC2086
|
|
set -- $spec
|
|
target="$1"; cpu="$2"; shift 2; extra="$*"
|
|
|
|
for src in "$dir"/*.S "$dir"/*.s; do
|
|
[ -f "$src" ] || continue
|
|
total=$((total + 1))
|
|
output="$("$CC" --target="$target" -mcpu="$cpu" $extra -c "$src" -o /dev/null 2>&1)"
|
|
if [ -n "$output" ]; then
|
|
fail "$src"
|
|
echo "$output" | sed 's/^/ /'
|
|
failures=$((failures + 1))
|
|
fi
|
|
done
|
|
done
|
|
say " $((total - failures)) of $total assembled"
|
|
if [ -n "$skipped" ]; then
|
|
say " not Arm, skipped:$(echo $skipped | tr ' ' '\n' | sort -u | tr '\n' ' ')"
|
|
fi
|
|
|
|
# --------------------------------------------------------------------------
|
|
say ""
|
|
say "== Assembly behind feature macros =="
|
|
|
|
for macro in $FEATURE_MACROS; do
|
|
macro_total=0
|
|
macro_bad=0
|
|
for src in $(grep -rl "$macro" ports/*/gnu/src/*.S ports_smp/*/gnu/src/*.S \
|
|
2>/dev/null | sort); do
|
|
core="$(echo "$src" | cut -d/ -f2)"
|
|
spec="${PORT_TARGET[$core]:-}"
|
|
[ -n "$spec" ] || continue
|
|
# shellcheck disable=SC2086
|
|
set -- $spec
|
|
target="$1"; cpu="$2"; shift 2; extra="$*"
|
|
|
|
# The FPU flags apply to the VFP paths only; the other macros guard no
|
|
# floating-point code and do not need them.
|
|
fpu=""
|
|
if [ "$macro" = "TX_ENABLE_VFP_SUPPORT" ]; then
|
|
fpu="${VFP_EXTRA[$core]:-}"
|
|
fi
|
|
|
|
macro_total=$((macro_total + 1))
|
|
output="$("$CC" --target="$target" -mcpu="$cpu" $extra $fpu \
|
|
-D"$macro" -c "$src" -o /dev/null 2>&1)"
|
|
if [ -n "$output" ]; then
|
|
fail "$src with -D$macro"
|
|
echo "$output" | grep "error:" | head -3 | sed 's/^/ /'
|
|
macro_bad=$((macro_bad + 1))
|
|
failures=$((failures + 1))
|
|
fi
|
|
done
|
|
if [ "$macro_total" -eq 0 ]; then
|
|
say " $macro: no assembly is guarded by it"
|
|
else
|
|
say " $macro: $((macro_total - macro_bad)) of $macro_total assembled"
|
|
fi
|
|
done
|
|
|
|
# --------------------------------------------------------------------------
|
|
if [ "$asm_only" -eq 0 ]; then
|
|
say ""
|
|
say "== Common C sources, one core per architecture profile =="
|
|
|
|
for core in $C_CORES; do
|
|
spec="${PORT_TARGET[$core]:-}"
|
|
[ -n "$spec" ] || continue
|
|
# shellcheck disable=SC2086
|
|
set -- $spec
|
|
target="$1"; cpu="$2"; shift 2; extra="$*"
|
|
|
|
count=0; bad=0
|
|
for src in common/src/*.c; do
|
|
count=$((count + 1))
|
|
output="$("$CC" --target="$target" -mcpu="$cpu" $extra \
|
|
-Iports/"$core"/gnu/inc -Icommon/inc -c "$src" -o /dev/null 2>&1)"
|
|
if [ -n "$output" ]; then
|
|
fail "$core: $src"
|
|
echo "$output" | grep "error:" | head -3 | sed 's/^/ /'
|
|
bad=$((bad + 1)); failures=$((failures + 1))
|
|
fi
|
|
done
|
|
say " $core: $((count - bad)) of $count compiled"
|
|
done
|
|
fi
|
|
|
|
|
|
# --------------------------------------------------------------------------
|
|
if [ "$no_examples" -eq 0 ]; then
|
|
say ""
|
|
say "== Example builds, linked with lld =="
|
|
|
|
example_ok=0
|
|
example_total=0
|
|
example_known=""
|
|
example_nodriver=""
|
|
example_nosample=""
|
|
for dir in ports/*/gnu/example_build ports_smp/*/gnu/example_build; do
|
|
[ -d "$dir" ] || continue
|
|
core="$(echo "$dir" | cut -d/ -f2)"
|
|
|
|
# Anything on the expected-to-fail list is reported before any other
|
|
# filter is applied, so a name placed there can never drop out of the
|
|
# output. arm9 and arm11 are the cases that matter: they are Arm ports
|
|
# with example drivers, but they carry no PORT_TARGET entry, so the
|
|
# Arm test below would discard them.
|
|
case " $EXAMPLES_EXPECTED_TO_FAIL " in
|
|
*" $core "*) example_known="$example_known $core"; continue ;;
|
|
esac
|
|
|
|
# Arm ports only, the same rule the assembly stage applies. Naming
|
|
# linux or mips32 as a gap here would be noise, not information.
|
|
[ -n "${PORT_TARGET[$core]:-}" ] || continue
|
|
|
|
# Covered by the CMake stage below rather than here.
|
|
case " $CMAKE_EXAMPLE_CORES " in
|
|
*" $core "*) continue ;;
|
|
esac
|
|
|
|
# A driverless example is not covered by this stage, so say so rather
|
|
# than dropping out in silence. A port that is simply absent from the
|
|
# count reads as covered.
|
|
if [ ! -f "$dir/build_threadx.sh" ]; then
|
|
example_nodriver="$example_nodriver $core"
|
|
continue
|
|
fi
|
|
if [ ! -f "$dir/build_threadx_sample.sh" ]; then
|
|
example_nosample="$example_nosample $core"
|
|
continue
|
|
fi
|
|
example_total=$((example_total + 1))
|
|
|
|
rm -f "$dir"/*.o "$dir"/*.a "$dir"/*.out "$dir"/*.map 2>/dev/null || true
|
|
log="$(cd "$dir" && TOOLCHAIN=atfe ATFE_CLANG="$CC" ./build_threadx.sh 2>&1 && \
|
|
TOOLCHAIN=atfe ATFE_CLANG="$CC" ./build_threadx_sample.sh 2>&1)" || true
|
|
|
|
if [ -f "$dir/sample_threadx.out" ]; then
|
|
example_ok=$((example_ok + 1))
|
|
else
|
|
fail "$core: example build produced no image"
|
|
# Not filtered on "error": a missing tool reports "command not
|
|
# found" or "Permission denied", and filtering hid exactly that.
|
|
echo "$log" | tail -6 | sed 's/^/ /'
|
|
failures=$((failures + 1))
|
|
fi
|
|
rm -f "$dir"/*.o "$dir"/*.a "$dir"/*.out "$dir"/*.map 2>/dev/null || true
|
|
done
|
|
say " $example_ok of $example_total example builds linked"
|
|
if [ -n "$example_known" ]; then
|
|
say " known not to link, see the list at the top of this script:$example_known"
|
|
fi
|
|
if [ -n "$example_nosample" ]; then
|
|
say " has build_threadx.sh but no build_threadx_sample.sh, so not linked:$example_nosample"
|
|
fi
|
|
if [ -n "$example_nodriver" ]; then
|
|
say " no script driver, so outside this stage:$example_nodriver"
|
|
fi
|
|
fi
|
|
# --------------------------------------------------------------------------
|
|
# The Cortex-R52 examples are built by CMake, so they need a toolchain file
|
|
# rather than TOOLCHAIN=atfe. Same compiler, same linker, same purpose as the
|
|
# stage above: confirm the images still link when the toolchain is not GNU.
|
|
if [ "$no_examples" -eq 0 ]; then
|
|
say ""
|
|
say "== CMake example builds, linked with lld =="
|
|
|
|
if ! command -v cmake >/dev/null 2>&1 || ! command -v ninja >/dev/null 2>&1; then
|
|
say " skipped: cmake and ninja are both required"
|
|
else
|
|
for core in $CMAKE_EXAMPLE_CORES; do
|
|
build_dir="$(mktemp -d)"
|
|
# ATFE_TOOLCHAIN_PATH follows --clang, so the stage uses the same
|
|
# compiler as every other stage rather than whatever is on PATH.
|
|
if cmake -S . -B "$build_dir" -G Ninja \
|
|
-DCMAKE_TOOLCHAIN_FILE="cmake/${core}_clang.cmake" \
|
|
-DATFE_TOOLCHAIN_PATH="$(cd "$(dirname "$CC")" && pwd)" \
|
|
-DTX_R52_BUILD_FVP_EXAMPLE=ON \
|
|
-DTX_R52_ENABLE_MPU=ON >"$build_dir/configure.log" 2>&1; then
|
|
# Read the image list from the generated graph instead of
|
|
# repeating it here, so adding a target cannot silently escape
|
|
# this check. The images are EXCLUDE_FROM_ALL, so "ninja" alone
|
|
# would build none of them.
|
|
#
|
|
# The cmake_object_order_depends_target_* entries are CMake's
|
|
# own ordering phonies, one per real image and named after it.
|
|
# Counting those doubled the total and reported ten images built
|
|
# where there are five.
|
|
images="$(ninja -C "$build_dir" -t targets all 2>/dev/null \
|
|
| grep -oE '^[A-Za-z0-9_]+\.elf' \
|
|
| grep -v '^cmake_' | sort -u)"
|
|
if [ -z "$images" ]; then
|
|
fail "$core: no .elf targets found in the CMake graph"
|
|
failures=$((failures + 1))
|
|
else
|
|
built=0; total=0
|
|
for image in $images; do
|
|
total=$((total + 1))
|
|
if ninja -C "$build_dir" "$image" \
|
|
>"$build_dir/$image.log" 2>&1; then
|
|
built=$((built + 1))
|
|
else
|
|
fail "$core: $image did not build"
|
|
tail -6 "$build_dir/$image.log" | sed 's/^/ /'
|
|
failures=$((failures + 1))
|
|
fi
|
|
done
|
|
say " $core: $built of $total images linked"
|
|
fi
|
|
else
|
|
fail "$core: CMake configure failed"
|
|
tail -6 "$build_dir/configure.log" | sed 's/^/ /'
|
|
failures=$((failures + 1))
|
|
fi
|
|
rm -rf "$build_dir"
|
|
done
|
|
fi
|
|
fi
|
|
|
|
# --------------------------------------------------------------------------
|
|
say ""
|
|
if [ "$failures" -eq 0 ]; then
|
|
say "All LLVM toolchain checks passed."
|
|
exit 0
|
|
fi
|
|
|
|
echo "$failures LLVM toolchain check(s) failed."
|
|
exit 1
|