|
| 1 | +#!/bin/bash |
| 2 | +# SPDX-License-Identifier: GPL-2.0 |
| 3 | +# Copyright 2025-2026 NXP |
| 4 | + |
| 5 | +HEAD=$(git rev-parse HEAD) |
| 6 | +nproc=$(grep -c processor /proc/cpuinfo) |
| 7 | +build_flags="-j $nproc" |
| 8 | +rc=0 |
| 9 | + |
| 10 | +architectures=( |
| 11 | + "arc" \ |
| 12 | + "arm" \ |
| 13 | + "arm64" \ |
| 14 | + "csky" \ |
| 15 | + "loongarch" \ |
| 16 | + "microblaze" \ |
| 17 | + "mips" \ |
| 18 | + "nios2" \ |
| 19 | + "openrisc" \ |
| 20 | + "powerpc" \ |
| 21 | + "riscv" \ |
| 22 | + "sh" \ |
| 23 | + "xtensa" \ |
| 24 | +) |
| 25 | + |
| 26 | +pr() { |
| 27 | + echo " ====== $* ======" | tee -a /dev/stderr |
| 28 | +} |
| 29 | + |
| 30 | +# "make dtbs" will fail on many archs during the syncconfig stage, where it |
| 31 | +# tries to probe the cross-compiler version. We don't actually need any |
| 32 | +# cross-compilation feature, the host gcc could in principle handle everything |
| 33 | +# as long as we filter out arch-specific flags. |
| 34 | +setup_shims() { |
| 35 | + local shims_dir="$1" |
| 36 | + |
| 37 | + mkdir -p "$shims_dir" |
| 38 | + |
| 39 | + cat > "$shims_dir/gcc" << 'EOF' |
| 40 | +#!/bin/bash |
| 41 | +args=() |
| 42 | +skip_next=false |
| 43 | +for arg in "$@"; do |
| 44 | + if [[ "$skip_next" == "true" ]]; then |
| 45 | + skip_next=false |
| 46 | + continue |
| 47 | + fi |
| 48 | + case "$arg" in |
| 49 | + -mdiv|-mno-stack-size|-mhard-float|-msoft-float|-mcpu=*|-march=*|-mtune=*|\ |
| 50 | + -mmedium-calls|-mlock|-mswape|-munaligned-access|-mno-sdata|-mbig-endian|\ |
| 51 | + -mabi=*|-mcmodel=*|-G|-mno-abicalls|-EB|0) |
| 52 | + ;; |
| 53 | + *) |
| 54 | + args+=("$arg") |
| 55 | + ;; |
| 56 | + esac |
| 57 | +done |
| 58 | +exec /usr/bin/gcc "${args[@]}" |
| 59 | +EOF |
| 60 | + |
| 61 | + chmod +x "$shims_dir/gcc" |
| 62 | + |
| 63 | + # Special case for xtensa |
| 64 | + ln -s $(which gcc) "$shims_dir/xtensa_fsf-gcc" |
| 65 | + ln -s "$(which ld)" "$shims_dir/xtensa_fsf-ld" |
| 66 | +} |
| 67 | + |
| 68 | +prep_config() { |
| 69 | + local arch=$1 |
| 70 | + local output_dir=$2 |
| 71 | + local shims_dir=$3 |
| 72 | + PATH="$shims_dir:$PATH" make ARCH=$arch O=$output_dir allmodconfig $build_flags |
| 73 | +} |
| 74 | + |
| 75 | +build() { |
| 76 | + local arch=$1 |
| 77 | + local output_dir=$2 |
| 78 | + local shims_dir=$3 |
| 79 | + PATH="$shims_dir:$PATH" make -s ARCH=$arch O=$output_dir $build_flags DT_CHECKER_FLAGS=-m CHECK_DT_BINDING=y dtbs 2>&1 |
| 80 | +} |
| 81 | + |
| 82 | +clean_build() { |
| 83 | + local output_dir=$1 |
| 84 | + rm -rf "$output_dir" |
| 85 | +} |
| 86 | + |
| 87 | +schema_modified=false |
| 88 | +if git show --diff-filter=AM --pretty="" --name-only "${HEAD}" | \ |
| 89 | + grep -q -E "^Documentation/devicetree/bindings/" |
| 90 | +then |
| 91 | + schema_modified=true |
| 92 | +fi |
| 93 | + |
| 94 | +touched_archs=() |
| 95 | +for arch in "${architectures[@]}"; do |
| 96 | + if git show --diff-filter=AM --pretty="" --name-only "${HEAD}" | \ |
| 97 | + grep -q -E "^arch/${arch}/boot/dts/" |
| 98 | + then |
| 99 | + touched_archs+=("$arch") |
| 100 | + fi |
| 101 | +done |
| 102 | + |
| 103 | +test_archs=() |
| 104 | +if [ "$schema_modified" = true ]; then |
| 105 | + test_archs=("${architectures[@]}") |
| 106 | + echo "DT schema files modified, testing all architectures" >&"$DESC_FD" |
| 107 | +elif [ ${#touched_archs[@]} -gt 0 ]; then |
| 108 | + test_archs=("${touched_archs[@]}") |
| 109 | + echo "DTS files touched for architectures: ${test_archs[*]}" >&"$DESC_FD" |
| 110 | +else |
| 111 | + echo "No DT schema or DTS files touched, skip" >&"$DESC_FD" |
| 112 | + exit 0 |
| 113 | +fi |
| 114 | + |
| 115 | +echo "Tree base:" |
| 116 | +git log -1 --pretty='%h ("%s")' HEAD~ |
| 117 | +echo "Now at:" |
| 118 | +git log -1 --pretty='%h ("%s")' HEAD |
| 119 | + |
| 120 | +# Set up compiler shims |
| 121 | +shims_dir="$PWD/shims" |
| 122 | +setup_shims "$shims_dir" |
| 123 | + |
| 124 | +for arch in "${test_archs[@]}"; do |
| 125 | + output_dir="build_dtbs_check_${arch}/" |
| 126 | + |
| 127 | + tmpfile_o_raw=$(mktemp) |
| 128 | + tmpfile_n_raw=$(mktemp) |
| 129 | + tmp_new_issues=$(mktemp) |
| 130 | + |
| 131 | + pr "Checking $arch before the patch" |
| 132 | + git checkout -q HEAD~ |
| 133 | + |
| 134 | + # Prepare config and run the check on the parent commit |
| 135 | + clean_build "$output_dir" |
| 136 | + prep_config "$arch" "$output_dir" "$shims_dir" |
| 137 | + (build "$arch" "$output_dir" "$shims_dir" | tee -a "$tmpfile_o_raw") || true |
| 138 | + |
| 139 | + # Sort the output |
| 140 | + sort "$tmpfile_o_raw" > "${tmpfile_o_raw}.sorted" |
| 141 | + mv "${tmpfile_o_raw}.sorted" "$tmpfile_o_raw" |
| 142 | + incumbent_total=$(wc -l < "$tmpfile_o_raw") |
| 143 | + |
| 144 | + pr "Checking $arch with the patch" |
| 145 | + git checkout -q "$HEAD" |
| 146 | + |
| 147 | + # Prepare config and run the check on the new commit |
| 148 | + clean_build "$output_dir" |
| 149 | + prep_config "$arch" "$output_dir" "$shims_dir" |
| 150 | + (build "$arch" "$output_dir" "$shims_dir" | tee -a "$tmpfile_n_raw") || true |
| 151 | + |
| 152 | + # Sort the output |
| 153 | + sort "$tmpfile_n_raw" > "${tmpfile_n_raw}.sorted" |
| 154 | + mv "${tmpfile_n_raw}.sorted" "$tmpfile_n_raw" |
| 155 | + current_total=$(wc -l < "$tmpfile_n_raw") |
| 156 | + |
| 157 | + # Compare the lists to find new and fixed issues |
| 158 | + # Use comm to find fixed issues (lines only in the old log, column 1). |
| 159 | + fixed_issues_count=$(comm -23 "$tmpfile_o_raw" "$tmpfile_n_raw" | wc -l) |
| 160 | + |
| 161 | + # Use comm to find new issues (lines only in the new log, column 2) |
| 162 | + # and save them for later display. |
| 163 | + comm -13 "$tmpfile_o_raw" "$tmpfile_n_raw" > "$tmp_new_issues" |
| 164 | + new_issues_count=$(wc -l < "$tmp_new_issues") |
| 165 | + |
| 166 | + echo "[$arch] Issues before: $incumbent_total, after: $current_total" \ |
| 167 | + "(Fixed: $fixed_issues_count, New: $new_issues_count)" >&"$DESC_FD" |
| 168 | + |
| 169 | + if [ "$new_issues_count" -gt 0 ]; then |
| 170 | + echo "[$arch] New issues added:" 1>&2 |
| 171 | + # Print the new issues we saved |
| 172 | + cat "$tmp_new_issues" 1>&2 |
| 173 | + rc=1 |
| 174 | + elif [ "$fixed_issues_count" -gt 0 ]; then |
| 175 | + echo "[$arch] Patch fixed $fixed_issues_count issue(s)." >&2 |
| 176 | + # No new issues, and some were fixed. This is a success. |
| 177 | + fi |
| 178 | + |
| 179 | + rm "$tmpfile_o_raw" "$tmpfile_n_raw" "$tmp_new_issues" |
| 180 | +done |
| 181 | + |
| 182 | +# Clean up shims directory |
| 183 | +rm -rf "$shims_dir" |
| 184 | + |
| 185 | +exit $rc |
0 commit comments