Skip to content

build: pass/fail summary after multi-target make#1288

Merged
nerdCopter merged 18 commits into
emuflight:masterfrom
nerdCopter:feat/build-summary
Jun 30, 2026
Merged

build: pass/fail summary after multi-target make#1288
nerdCopter merged 18 commits into
emuflight:masterfrom
nerdCopter:feat/build-summary

Conversation

@nerdCopter

@nerdCopter nerdCopter commented Jun 25, 2026

Copy link
Copy Markdown
Member

AI Generated pull-request

Closes #1287

Summary

  • Every build invocation — single-target (make HELIOSPRING), named-group (make all, make supported, all targets-group-*, make all_with_unsupported, make unsupported), and arbitrary multi-target (make HELIOSPRING FOXEERF405) — prints === Build summary: N succeeded, M failed === via a single summary_build canned recipe
  • Unknown/misspelled targets (e.g. make HELIOSPRING FOOBAR) are counted in the failed total, listed by name, and cause a non-zero exit
  • Exit code is always non-zero when any target fails or is unknown — CI-safe
  • -k remains user-controlled; not forced by the Makefile
  • Failed targets always listed (no truncation)
  • Summary machinery is internal; make build_summary is not a user-callable target

Implementation notes

A define summary_build canned recipe is the single implementation point for all
summary logic. Named-group targets call it directly; multi-target direct invocations
are intercepted at parse time via $(MAKECMDGOALS) and routed through it; single-target
direct invocations call it from the $(VALID_TARGETS) rule.

The recipe uses a per-invocation mktemp -d directory for marker files (concurrent-CI-safe),
pre-populates invalid goals into the failed marker before the inner make runs, and captures
the inner make exit code for "no rule to make target" errors. A trap ensures temp dir
cleanup on EXIT.

Test plan

  • make HELIOSPRING (single target) — 1 succeeded, 0 failed, exit 0
  • make targets-group-1 -j 48 — 39 succeeded, 0 failed, exit 0
  • make HELIOSPRING FOXEERF405 FOORBAR -j 48 — 2 succeeded, 1 failed (FOORBAR listed), exit 1
  • make FOOBAR — make native "no rule" error, exit 2
  • make all -j 48 — 459 succeeded, 0 failed, exit 0
  • Full CI across all target groups

Summary by CodeRabbit

  • Bug Fixes
    • Improved make behavior for multiple targets so results are summarized clearly instead of failing silently or inconsistently.
    • Invalid targets are now included in the final build summary, making failures easier to spot.
    • clean_all now clears build summary state to avoid stale results on later runs.

nerdCopter and others added 9 commits June 25, 2026 10:04
When running `make all` (or `make supported`) across all supported
targets, print a final summary line once every target has finished.

Changes:
- $(VALID_TARGETS) recipe: &&-chain replaced with if/else; per-target
  pass/fail appended to obj/.build_passed or obj/.build_failed
  (O_APPEND writes < PIPE_BUF are atomic; no flock needed under -j)
- build_summary_init: order-only prereq for $(SUPPORTED_TARGETS);
  clears marker files at the start of each all/supported run
- build_summary: depends on $(SUPPORTED_TARGETS), prints summary line
  and exits non-zero if any target failed; failed-target list shown
  only when failed count ≤ 10 (avoids flooding on broken-toolchain runs)
- clean_all: removes marker files alongside obj/main/

Closes emuflight#1287

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previous design absorbed per-target failures (if/else without exit 1),
effectively forcing keep-going behavior for all builds including single
targets like `make HELIOSPRING`.

Fix:
- Add `exit 1` to the failure branch so individual target builds exit
  non-zero correctly.
- Remove $(SUPPORTED_TARGETS): | build_summary_init order-only prereq;
  it's no longer needed and caused build_summary_init to run for every
  single-target invocation.
- Change `all supported:` to a 3-line recipe:
    @$(MAKE) build_summary_init    # clear markers
    -@$(MAKE) $(SUPPORTED_TARGETS) # build; errors absorbed here only
    @$(MAKE) build_summary          # always prints summary, exits ≠0 on fail
  The `-` on the middle line absorbs the sub-make exit code so
  build_summary always runs. MAKEFLAGS propagates automatically, so
  user-supplied -k / -j are honored by the sub-make.
- Change `build_summary:` to have no prerequisites; it now reads
  marker files written during the sub-make.
- Add BUILD_SUMMARY_FAIL_LIST_MAX ?= 10 for user tuning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
build_summary_init and build_summary were phony targets reachable by
any user. Inline both into the all/supported recipe so the summary
machinery is not a user-surfaced interface — it's an implementation
detail of make all.

clean_all still references the marker file variables directly, so
cleanup is unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Define summary_build macro that takes a target list, runs it through a
sub-make (inheriting MAKEFLAGS so -k/-j propagate naturally), and always
prints the pass/fail report regardless of build outcome.

Apply to every multi-target recipe:
  all, supported, all_with_unsupported, unsupported,
  targets-group-1..11, targets-group-rest

For make HELIOSPRING FOXEERF722V4 (raw arbitrary invocations) the exit
code is already correct; summary requires going through one of the above
named targets, which cover all CI-relevant use cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When all MAKECMDGOALS are VALID_TARGETS and there are 2+, set
IN_SUMMARY_OUTER at parse time and restructure the build graph:
  - $(VALID_TARGETS): becomes a no-op (@:)
  - _auto_summary is injected as a prerequisite of the first goal;
    its recipe calls summary_build which does the real work
  - summary_build passes IN_SUMMARY_BUILD=1 to its sub-make so
    the inner invocation skips detection and uses the real recipe

Result:
  make HELIOSPRING FOXEERF722V4 KAKUTEF7  -> summary + correct exit
  make HELIOSPRING                         -> real recipe, correct exit
  make all / targets-group-*              -> unchanged

Conditions that do NOT trigger interception (IN_SUMMARY_OUTER stays unset):
  - Single target (words == 1)
  - Mixed goals where some are not VALID_TARGETS (e.g. make HELIOSPRING all)
  - Inner sub-make (IN_SUMMARY_BUILD=1 set)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Relax the IN_SUMMARY_OUTER detection from 'all goals must be valid AND
2+' to '2+ total goals AND at least one is a valid target'. This lets
make HELIOSPRING FOXEERF405 FOOBAR -j 6 be intercepted even though
FOOBAR is not a known target.

In the outer make (IN_SUMMARY_OUTER branch):
- Compute _INVALID_GOALS = goals not in VALID_TARGETS
- Add a no-op recipe for them so make does not emit a redundant 'no
  rule to make target' error (the inner make already reports it)

In summary_build:
- Replace -@$(MAKE) (which discarded the exit code) with
  _exit=0; $(MAKE) ... || _exit=$$? so the inner make exit code
  is captured alongside the marker-based failed count
- Final exit condition: [ _exit -eq 0 ] && [ failed -eq 0 ]
  This exits non-zero for both recipe failures (marker-based) and
  'no rule' / other make errors (exit-code-based)

Summary for make HELIOSPRING FOXEERF405 FOOBAR -j 6:
  - inner make: HELIOSPRING + FOXEERF405 build, FOOBAR 'no rule' -> _exit=2
  - summary: '2 succeeded, 0 failed'
  - exit code: non-zero (from _exit) ✓

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the firstword-dependency trick with a flat rule:
  $(MAKECMDGOALS): _auto_summary
      @:

This makes ALL command-line goals depend on _auto_summary, so when
_auto_summary exits non-zero (either recipe failure or 'no rule to
make target' for an unknown goal), every goal fails and the outer
make exits non-zero.  Previously only the first goal depended on
_auto_summary, letting the remaining no-op goals 'succeed' and
causing make to exit 0 despite the error.

The _INVALID_GOALS workaround is no longer needed — unknown goals get
a recipe (@:) from the multi-target rule itself, suppressing the
double 'no rule' error while the inner make's 'no rule' is still
reported and captured in _exit.

Also remove BUILD_SUMMARY_FAIL_LIST_MAX: always print failed targets,
no artificial truncation threshold.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…4.4+

In GNU Make 4.4+, when a non-phony target has a trivial (@:) recipe
and its prerequisite fails, make reports the error but still exits 0.
It considers the target 'not needing a rebuild' rather than 'failed'.

Fix: declare $(MAKECMDGOALS) as .PHONY inside the IN_SUMMARY_OUTER
block.  Phony targets must always be rebuilt, so a failed prerequisite
(_auto_summary) marks them as failed and make exits non-zero.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GNU Make 4.4+ does not reliably propagate a failed prerequisite to
the outer make's exit code when the dependent goals have trivial (@:)
recipes — make reports the error but exits 0.  This was true even with
.PHONY declarations on the goals.

Fix: abandon the _auto_summary prerequisite pattern entirely.  Instead,
put summary_build directly in the FIRST command-line goal's recipe, and
make the remaining goals @: no-ops.  When a goal's OWN recipe exits
non-zero, make unconditionally exits non-zero — this is a direct path
with no dependency-propagation ambiguity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8d7d0168-2368-4faf-8d28-5d44196244e3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Makefile now tracks per-target pass/fail results with marker files, summarizes multi-target builds through a guarded sub-make flow, rewires aggregate and direct multi-goal target handling, and removes the summary markers during clean_all.

Changes

Build summary and multi-goal execution

Layer / File(s) Summary
Summary macro and guard
Makefile
Defines build-summary marker variables, summary_build, and direct multi-goal detection.
Aggregate targets and result markers
Makefile
Routes all, supported, unsupported, and group targets through summary_build, handles IN_SUMMARY_OUTER, and appends per-target pass/fail markers.
Summary marker cleanup
Makefile
clean_all removes the build summary marker files.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant OuterMake
  participant InnerMake
  participant TargetRecipe
  participant BUILD_SUMMARY_PASSED
  participant BUILD_SUMMARY_FAILED

  User->>OuterMake: make T1 T2
  OuterMake->>InnerMake: summary_build runs targets in a guarded sub-make
  loop each requested target
    InnerMake->>TargetRecipe: run target recipe
    alt success
      TargetRecipe->>BUILD_SUMMARY_PASSED: append target name
    else failure
      TargetRecipe->>BUILD_SUMMARY_FAILED: append target name
    end
  end
  InnerMake-->>OuterMake: exit status and summary counts
  OuterMake-->>User: print pass/fail summary
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR goes beyond #1287 by rewiring group targets and single-target invocations, which the issue marked as out of scope. Split the group-target and single-target routing changes into a separate PR, and keep this one limited to all/supported summary support.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately describes the main change: adding build pass/fail summaries for multi-target make runs.
Description check ✅ Passed The description is mostly complete and includes a summary, implementation notes, test plan, and linked issue reference.
Linked Issues check ✅ Passed The changes implement the #1287 build summary flow with markers, summary counting, and non-zero failure handling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai, AI generated comment — please review this PR. It modifies only Makefile: adds a pass/fail build summary (=== Build summary: N succeeded, M failed ===) printed after every multi-target build, with non-zero exit code when any target fails. Key areas to check: the define summary_build macro (exit code capture via _exit), the IN_SUMMARY_OUTER parse-time detection block (filtering), the marker file append logic (`.build_passed`/`.build_failed`), and whether the / `` goal restructuring has any edge cases with parallel -j builds or unusual goal combinations.

@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai, AI generated comment — please review this PR. It modifies only Makefile: adds a pass/fail build summary (=== Build summary: N succeeded, M failed ===) printed after every multi-target build, with non-zero exit code when any target fails. Key areas to check: the define summary_build macro (exit-code capture via _exit), the IN_SUMMARY_OUTER parse-time detection block (MAKECMDGOALS filtering), the marker file append logic (.build_passed/.build_failed), and whether the wordlist/firstword goal restructuring has any edge cases with parallel -j builds or unusual goal combinations.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== repo =="
git remote -v | head -n 5 || true

echo
echo "== changed files in PR branch vs base =="
git diff --name-only origin/master...HEAD || git diff --name-only HEAD~1...HEAD || true

echo
echo "== Makefile diff =="
git diff --unified=80 origin/master...HEAD -- Makefile || git diff --unified=80 HEAD~1...HEAD -- Makefile || true

echo
echo "== search for summary-related identifiers in Makefile =="
rg -n -C4 'summary_build|IN_SUMMARY_OUTER|build_passed|build_failed|MAKECMDGOALS|unknown|notdir|filter' Makefile || true

echo
echo "== first 260 lines of Makefile =="
sed -n '1,260p' Makefile

echo
echo "== lines 260-520 of Makefile =="
sed -n '260,520p' Makefile

Length of output: 39519



@nerdCopter I reviewed the Makefile changes and found two edge cases that look worth fixing before merge:

  1. The summary markers are global (obj/.build_passed / obj/.build_failed), so parallel top-level summary invocations can stomp on each other. For example, make -j2 all supported or make -j2 targets-group-1 targets-group-2 would have both recipes rm -f and append to the same files, which makes the counts/list nondeterministic. I’d strongly recommend per-invocation marker files and passing those paths into the sub-make.

  2. The IN_SUMMARY_OUTER guard is too broad. Right now it triggers for any 2+ goals as long as one of them is a valid board target. That means mixed invocations like make clean HELIOSPRING, make help HELIOSPRING, or make flash HELIOSPRING get restructured into summary mode, which changes the semantics of non-build goals. I think the interception should be limited to “all command-line goals are direct build targets” (or an explicit allowlist of summary-capable goals).

Other than that, the _exit handling in summary_build looks sound for preserving a non-zero exit when the inner make fails or an unknown direct target is passed through.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== PR metadata =="
gh pr view 1288 --json title,baseRefName,headRefName,files,body,url

echo
echo "== Changed files =="
gh pr diff 1288 --name-only

echo
echo "== Makefile summary-related symbols =="
rg -n -C3 'summary_build|IN_SUMMARY_OUTER|build_passed|build_failed|MAKECMDGOALS|wordlist|firstword|targets-group|all_with_unsupported|unsupported|supported' Makefile || true

echo
echo "== Diff for Makefile =="
gh pr diff 1288 -- Makefile

echo
echo "== Top of Makefile =="
sed -n '1,260p' Makefile

echo
echo "== Mid/Late Makefile around group targets =="
sed -n '260,520p' Makefile

Length of output: 8828


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Makefile lines 335-395 =="
sed -n '335,395p' Makefile | nl -ba

echo
echo "== Makefile lines 472-575 =="
sed -n '472,575p' Makefile | nl -ba

echo
echo "== Search for marker writes =="
rg -n -C3 '\.build_passed|\.build_failed|BUILD_SUMMARY_PASSED|BUILD_SUMMARY_FAILED' Makefile

echo
echo "== PR files patch via GitHub API =="
gh api repos/emuflight/EmuFlight/pulls/1288/files --paginate \
  --jq '.[] | select(.filename=="Makefile") | .patch'

Length of output: 887


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Makefile lines 335-395 =="
sed -n '335,395p' Makefile | cat -n

echo
echo "== Makefile lines 472-575 =="
sed -n '472,575p' Makefile | cat -n

echo
echo "== Search for marker writes =="
rg -n -C4 '\.build_passed|\.build_failed|BUILD_SUMMARY_PASSED|BUILD_SUMMARY_FAILED' Makefile || true

echo
echo "== PR Makefile patch via GitHub API =="
gh api repos/emuflight/EmuFlight/pulls/1288/files --paginate \
  --jq '.[] | select(.filename=="Makefile") | .patch // "<no patch>"'

Length of output: 15916



@nerdCopter I reviewed the Makefile changes. _exit handling and the pass/fail marker flow look generally sound, but I did find one blocking edge case in the goal-rewrite logic.

Blocking issue

  • Lines 324-329 / Lines 472-484: IN_SUMMARY_OUTER currently turns on for any 2+ goal invocation that contains at least one $(VALID_TARGETS) entry. That means it also rewrites mixed goal sets like:

    • make clean HELIOSPRING
    • make supported HELIOSPRING
    • make all HELIOSPRING

    In those cases, the outer wrapper runs summary_build over the full $(MAKECMDGOALS) list, and the inner make can then hit another summary target (all, supported, etc.) or utility target (clean). That changes semantics compared with normal make behavior, can reset the marker files mid-run, and can produce misleading counts or even conflicting work under -j (for example, clean racing with a build).

    I think the interception should be narrowed so it only applies to “direct board-target invocations” and not mixed invocations that include existing meta/utility targets.

One possible direction is to only enable the outer path when the goals are board targets plus optional unknown names, but not when any known non-board target is present. For example:

# sketch: keep interception for `make HELIOSPRING FOXEERF405 [FOOBAR]`
# but skip it for `make clean HELIOSPRING` / `make supported HELIOSPRING`
SUMMARY_META_GOALS := all supported all_with_unsupported unsupported \
    targets-group-1 targets-group-2 targets-group-3 targets-group-4 \
    targets-group-5 targets-group-6 targets-group-7 targets-group-8 \
    targets-group-9 targets-group-10 targets-group-11 targets-group-rest \
    clean clean_all all_clean clean_test flash st-flash binary hex help targets

ifndef IN_SUMMARY_BUILD
_DIRECT_VALID := $(filter $(VALID_TARGETS),$(MAKECMDGOALS))
_DIRECT_META  := $(filter $(SUMMARY_META_GOALS),$(MAKECMDGOALS))
ifneq ($(words $(MAKECMDGOALS)),1)
ifneq ($(words $(_DIRECT_VALID)),0)
ifeq ($(words $(_DIRECT_META)),0)
IN_SUMMARY_OUTER := 1
endif
endif
endif
endif

If you want, I can do another pass after that is tightened up.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Makefile`:
- Around line 346-354: The build summary in the Makefile only counts entries
from BUILD_SUMMARY_FAILED, so direct unknown goals can make the summary show
zero failures even though _exit is non-zero. Update the summary logic around the
passed/failed counts so direct unknown goals are added to the failed marker
list, while still excluding known non-build goals handled by the outer guard;
use the existing summary block and failure markers to locate the fix.
- Around line 324-329: The current IN_SUMMARY_OUTER guard in the Makefile still
activates for mixed goal invocations when _DIRECT_VALID finds any VALID_TARGETS
entry, which can interfere with non-build goals like clean. Update the
IN_SUMMARY_BUILD block so IN_SUMMARY_OUTER is set only for direct build-target
commands, or explicitly filter out known non-summary goals before assigning it.
Make the same adjustment in the duplicated guard logic referenced by the later
Makefile section so both paths behave consistently.
- Around line 313-345: The summary marker files used by summary_build are shared
across invocations, so concurrent top-level runs can interfere with each other’s
pass/fail tracking. Update summary_build to create a unique per-invocation
marker directory or file prefix, and pass those marker paths into the recursive
$(MAKE) call. Make sure the existing BUILD_SUMMARY_PASSED and
BUILD_SUMMARY_FAILED handling in the Makefile summary flow uses the
invocation-specific paths instead of the global $(BIN_DIR)/.build_passed and
.build_failed markers.
- Around line 488-489: The build recipe for VALID_TARGETS has an extra redundant
@ after $(V0), which expands to an invalid `@ `@echo`` when verbosity is off.
Update the target rule to use $(V0) with echo directly in the Makefile recipe so
the command remains valid for both V=0 and normal verbosity. Use the
VALID_TARGETS rule and the $(V0) verbosity helper as the key locations to
adjust.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b625f53f-eccf-4981-8713-c9731799a5ad

📥 Commits

Reviewing files that changed from the base of the PR and between 7cc284c and 47d3947.

📒 Files selected for processing (1)
  • Makefile
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Codacy Static Code Analysis
🧰 Additional context used
🪛 checkmake (0.3.2)
Makefile

[warning] 488-488: Target body for "$(VALID_TARGETS)" exceeds allowed length of 5 lines (9).

(maxbodylength)


[warning] 479-479: Required target "all" is missing from the Makefile.

(minphony)


[warning] 479-479: Required target "test" is missing from the Makefile.

(minphony)

🔇 Additional comments (2)
Makefile (2)

411-470: LGTM!


537-537: LGTM!

Comment thread Makefile Outdated
Comment thread Makefile
Comment thread Makefile Outdated
Comment thread Makefile Outdated
Four fixes from PR emuflight#1288 inline review:

1. Concurrent marker collision (major): replace global .build_passed /
   .build_failed files with a per-invocation mktemp directory.  Paths are
   passed to the sub-make via BUILD_SUMMARY_PASSED / BUILD_SUMMARY_FAILED
   command-line overrides so they land in each invocation's own temp dir.
   A trap ensures cleanup on EXIT even when the build is interrupted.

2. Non-build goal interception (major): add _SUMMARY_SKIP_GOALS and
   _DIRECT_NON_BUILD to the detection block.  If any goal in MAKECMDGOALS
   is a known non-build target (clean, clean_test, clean_all, all_clean,
   binary_hex, test, or NOBUILD_TARGETS), IN_SUMMARY_OUTER is not set so
   mixed invocations like `make clean HELIOSPRING` fall through to normal
   make processing instead of being redirected through summary_build.

3. Unknown goals not counted (major): compute _INVALID_GOALS inside the
   ifdef IN_SUMMARY_OUTER block and pass them as the new $(2) argument to
   summary_build.  The macro pre-populates the failed marker with each
   invalid goal before the sub-make runs so they appear in the `N failed`
   count and the failed-target listing.

4. $(V0) @echo double-@ bug (nitpick): remove the redundant @ from
   $(V0) @echo in the $(VALID_TARGETS) recipe.  When V=0, V0=@, making
   the expanded line `@ @echo`; make strips the first @ then passes
   `@echo` to the shell, which fails.  Correct form is $(V0) echo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai, AI generated comment

Addressed all four inline findings from this review round. Fixed in commit e19d53e:

Concurrent marker collision (Makefile:345, Major)
Fixed. Replaced the global $(BIN_DIR)/.build_passed / .build_failed static paths with a per-invocation mktemp -d directory. The temp path is passed to the sub-make via BUILD_SUMMARY_PASSED="$$_passed" / BUILD_SUMMARY_FAILED="$$_failed" command-line variable overrides (which take precedence over the Makefile-level definitions). A trap with cleanup on EXIT ensures temp dirs are removed even on interrupt.

Non-build goal interception (Makefile:329, Major)
Fixed. Added _SUMMARY_SKIP_GOALS (containing clean clean_test clean_all all_clean binary_hex test and $(NOBUILD_TARGETS)) and _DIRECT_NON_BUILD := $(filter $(_SUMMARY_SKIP_GOALS), $(MAKECMDGOALS)) to the detection block. IN_SUMMARY_OUTER is now only set when _DIRECT_NON_BUILD is empty, so make clean HELIOSPRING falls through to normal make processing rather than being intercepted.

Unknown goals not counted in failed summary (Makefile:354, Major)
Fixed. Added _INVALID_GOALS := $(filter-out $(VALID_TARGETS), $(MAKECMDGOALS)) inside the ifdef IN_SUMMARY_OUTER block. summary_build now takes a second parameter $(2) INVALID_GOALS — pre-populated into the failed marker via $(foreach t,$(2),echo "$(t)" >> "$$_failed"; ) before the sub-make runs. This means make HELIOSPRING FOOBAR now correctly shows 1 succeeded, 1 failed with FOOBAR listed, not 1 succeeded, 0 failed.

$(V0) @echo double-@ (Makefile:489, Major)
Fixed. Changed $(V0) @echo "Building $@" to $(V0) echo "Building $@". When V=0, V0=@, making the original expansion @ @echo — make strips the leading @ and passes @echo to the shell, which fails. Removing the redundant @ produces @echoecho in the shell, which is correct.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@nerdCopter Thanks — those changes sound like they address the review findings cleanly.

The per-invocation mktemp -d markers with trap cleanup remove the cross-invocation collision risk, the _SUMMARY_SKIP_GOALS guard narrows summary interception appropriately, pre-seeding _INVALID_GOALS into the failed marker fixes the summary counts for unknown targets, and removing the extra @ from $(V0) echo "Building $@" fixes the quiet-mode shell issue.

No further concerns on those points from me. 🐇✅


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

nerdCopter and others added 2 commits June 26, 2026 09:03
Replace $(V0) with @ in the $(VALID_TARGETS) per-target recipe.

With V unset (the common default), V0 is empty — no @ prefix — so
make echoes the entire if/then/else block before running it.  The
visible progress messages ("Building X", "Building X succeeded.",
etc.) come from the echo commands inside the recipe, not from make's
recipe echo.  Using @ always suppresses the recipe echo without
affecting any of those messages, matching the pattern used by every
other progress line in the Makefile (e.g. @echo "Linking...").

The previous $(V0) approach was a left-over from the verbosity
system used for compiler/linker lines: those use V0 so that the
command itself is hidden in quiet mode (V=0) but visible in verbose
mode (V=1).  That convention does not apply here — we want the
recipe silent at all verbosity levels.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add an ifdef IN_SUMMARY_BUILD split inside the else branch so that
every invocation of a VALID_TARGET — single or multi — goes through
the summary_build macro and prints a consistent:

  === Build summary: 1 succeeded, 0 failed ===

line at the end.

Structure:
  ifdef IN_SUMMARY_OUTER   → multi-target outer: first goal calls
                             summary_build(MAKECMDGOALS,_INVALID_GOALS)
  else
    ifdef IN_SUMMARY_BUILD → inner sub-make: run the actual build and
                             write to marker files (no summary printed
                             here — outer summary_build does that)
    else                   → direct single-target: call summary_build($@)
                             which runs a sub-make with IN_SUMMARY_BUILD=1,
                             then prints the 1-target summary
  endif
  endif

Named-group targets (all, supported, targets-group-*) already call
summary_build directly and are unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai, AI generated comment

Two follow-up commits since the last review round:

02034dd919 — always suppress recipe echo with @ (not $(V0))

$(V0) is part of the compiler/linker verbosity system: V0=@ when V=0 (quiet), V0= (empty) when V is unset (default verbose), V0= when V=1 (fully verbose). Using $(V0) on the $(VALID_TARGETS) recipe meant the entire if/then/else block was echoed by make in the default (V unset) case, showing raw shell code to the user. The progress messages (Building X, Building X succeeded.) come from the echo commands inside the recipe, not from make's recipe echo — so the recipe echo is always unwanted here. Replaced with @, matching the idiom used by every other progress line in the Makefile (@echo "Linking...", etc.).

a2769fe2d0 — route single-target direct builds through summary_build

Previously, make HELIOSPRING printed no summary line while make HELIOSPRING FOXEERF405 (and all named-group targets) printed === Build summary: N succeeded, M failed ===. For consistency, single-target direct invocations now also go through the summary_build canned recipe. The $(VALID_TARGETS) rule in the else branch is split on ifdef IN_SUMMARY_BUILD:

  • ifdef IN_SUMMARY_BUILD (inner sub-make, called from summary_build): runs the actual binary_hex build and writes to marker files — same as before, no summary printed here.
  • else (direct outer invocation): calls $(call summary_build,$@), which runs a sub-make with IN_SUMMARY_BUILD=1 and then prints === Build summary: 1 succeeded, 0 failed ===.

No new code paths — all invocations now funnel through the single summary_build canned recipe.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@nerdCopter Thanks — that all makes sense.

Using plain @ there is the right fix if the goal is to suppress make’s recipe echo regardless of V, and routing single-target direct builds through summary_build is a good consistency improvement. I don’t have further concerns on those follow-ups.


✏️ Learnings added
Learnt from: nerdCopter
URL: https://github.com/emuflight/EmuFlight/pull/1288

Timestamp: 2026-06-26T14:13:19.098Z
Learning: In the EmuFlight `Makefile`, `V0` is part of the compiler/linker verbosity system (`V0=@` only when `V=0`, otherwise empty) and should not be used to suppress recipe echo for the `$(VALID_TARGETS)` recipe, because with default `V` unset it causes the raw shell block to be echoed. Use plain `@` for always-hidden progress recipes in this file.

Learnt from: nerdCopter
URL: https://github.com/emuflight/EmuFlight/pull/1288

Timestamp: 2026-06-26T14:13:19.098Z
Learning: In the EmuFlight `Makefile`, direct single-target board builds are intentionally routed through `summary_build` so commands like `make HELIOSPRING` print the same `=== Build summary: N succeeded, M failed ===` line as multi-target and named-group builds; the inner `IN_SUMMARY_BUILD` path performs the actual `binary_hex` build and marker writes.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai, AI generated comment

Two additional commits since the last review:

02034dd919 — always suppress recipe echo with @

The $(VALID_TARGETS) recipe had $(V0) echo "Building $@". $(V0) is the compiler/linker verbosity control: V0=@ when V=0, V0= (empty) when V is unset (the common default). With V unset, the entire if/then/else block was echoed verbatim by make before execution. The visible progress messages come from the echo commands inside the recipe — the recipe echo itself is always unwanted here. Replaced with @ directly, matching every other progress line in the Makefile (@echo "Linking...", etc.).

a2769fe2d0 — single-target builds now print a summary

make HELIOSPRING previously printed no summary line while make HELIOSPRING FOXEERF405 and all named-group targets printed === Build summary: N succeeded, M failed ===. For consistency, all invocation paths now go through the summary_build canned recipe.

The $(VALID_TARGETS) rule in the else branch is split on ifdef IN_SUMMARY_BUILD:

  • ifdef IN_SUMMARY_BUILD (inner sub-make, called from summary_build): runs the actual binary_hex build and writes to marker files — unchanged behaviour.
  • else (direct outer invocation): $(call summary_build,$@) — runs a sub-make with IN_SUMMARY_BUILD=1 and prints === Build summary: 1 succeeded, 0 failed ===.

No new logic — single targets now use the same macro as every other path.

Verified 2026-06-26:

  • make HELIOSPRING=== Build summary: 1 succeeded, 0 failed ===, exit 0 ✓
  • make HELIOSPRING FOXEERF405 FOORBAR -j 482 succeeded, 1 failed, FOORBAR listed, exit 1 ✓
  • make targets-group-1 -j 4839 succeeded, 0 failed, exit 0 ✓
  • make all -j 48459 succeeded, 0 failed, exit 0 ✓

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@nerdCopter Thanks — this looks good to me.

Using plain @ there is the right fix for always suppressing recipe echo, and routing single-target direct builds through summary_build makes the behavior much more consistent. The verification matrix you included also covers the key paths I was most interested in: single target, mixed valid/invalid direct targets, grouped targets, and full all under high parallelism.

I don’t have further concerns on these follow-ups.

IN_SUMMARY_OUTER was suppressed for clean/utility targets but not for
named-group targets (all, supported, targets-group-*, etc.) or other
phony targets (flash, help, version, etc.).

A mixed invocation like `make all HELIOSPRING` would incorrectly
trigger IN_SUMMARY_OUTER: `all` is not in VALID_TARGETS and not in
the old _SUMMARY_SKIP_GOALS, so _DIRECT_NON_BUILD was empty and
IN_SUMMARY_OUTER was set.  The outer summary_build would then call the
inner make with `all HELIOSPRING`, where `all`'s own recipe would
call summary_build again — nested and incorrect.

Fix: enumerate all known non-board-build targets in _SUMMARY_SKIP_GOALS:
  - named-group: all, supported, all_with_unsupported, unsupported,
    targets-group-1 through targets-group-11, targets-group-rest
  - utility: flash, st-flash, binary, hex, unbrick, version, help,
    targets, target-mcu, targets-by-mcu, cppcheck,
    check-target-independence, check-fastram-usage-correctness
  - existing: clean, clean_test, clean_all, all_clean, binary_hex,
    test, $(NOBUILD_TARGETS)

Any goal in MAKECMDGOALS that matches _SUMMARY_SKIP_GOALS causes
_DIRECT_NON_BUILD to be non-empty, suppressing IN_SUMMARY_OUTER and
falling through to normal make processing.

Addresses CodeRabbit finding: emuflight#1288 (comment)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai, AI generated comment

Fixed in 17f532700e. The prior _SUMMARY_SKIP_GOALS only covered clean/utility targets; named-group targets (all, supported, targets-group-*, etc.) were missing, so make all HELIOSPRING still triggered IN_SUMMARY_OUTER incorrectly.

Extended _SUMMARY_SKIP_GOALS to enumerate all known non-board-build targets:

  • Named-group: all, supported, all_with_unsupported, unsupported, targets-group-1 through targets-group-11, targets-group-rest
  • Utility: flash, st-flash, binary, hex, unbrick, version, help, targets, target-mcu, targets-by-mcu, cppcheck, check-target-independence, check-fastram-usage-correctness
  • Existing: clean, clean_test, clean_all, all_clean, binary_hex, test, $(NOBUILD_TARGETS)

Any goal in $(MAKECMDGOALS) that matches _SUMMARY_SKIP_GOALS populates _DIRECT_NON_BUILD, which suppresses IN_SUMMARY_OUTER and lets make process the invocation normally.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@nerdCopter Thanks — that closes the gap I was worried about.

Expanding _SUMMARY_SKIP_GOALS to include the named-group targets as well as the utility/non-board targets is the right fix here. That should keep mixed invocations like make all HELIOSPRING out of the direct-target summary rewrite path and preserve normal make behavior.

Looks good from my side.
(•ᴗ•)🐇


✏️ Learnings added
Learnt from: nerdCopter
URL: https://github.com/emuflight/EmuFlight/pull/1288

Timestamp: 2026-06-26T17:50:29.964Z
Learning: In the EmuFlight `Makefile`, `_SUMMARY_SKIP_GOALS` must include not only clean/utility targets but also named-group targets such as `all`, `supported`, `all_with_unsupported`, `unsupported`, and `targets-group-*`; otherwise mixed invocations like `make all HELIOSPRING` can incorrectly trigger `IN_SUMMARY_OUTER`. The direct-target summary interception should only apply when `$(MAKECMDGOALS)` contains no known non-board-build goals.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai, AI generated comment

Please do a full review pass on the current branch tip (17f532700e) and confirm:

  1. All prior concerns resolved — the four inline findings from the first review round (concurrent markers, non-build goal interception, unknown goals not counted, $(V0) @echo double-@) and the blocking edge case from your general review (mixed meta/group-target invocations like make all HELIOSPRING) have all been addressed. Please confirm each is closed or flag anything still outstanding.

  2. Complete solution — the feature covers every expected invocation path: single-target (make HELIOSPRING), named-group (make all, make targets-group-*, etc.), arbitrary multi-target (make T1 T2), and mixed valid+invalid goals (make HELIOSPRING FOOBAR). Please verify there are no remaining gaps, edge cases, or logic errors.

  3. CI failure propagation — if any target fails to build (or an invalid target is specified), the outer make process must exit non-zero so CI correctly marks the job as failed. Please verify the exit-code path end-to-end: inner binary_hex failure → marker write + exit 1_exit capture in summary_build → outer make exit code.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== HEAD =="
git rev-parse --short=12 HEAD
git log --oneline -n 5

echo
echo "== Makefile summary-related matches =="
rg -n -C4 'summary_build|IN_SUMMARY_OUTER|IN_SUMMARY_BUILD|BUILD_SUMMARY_PASSED|BUILD_SUMMARY_FAILED|_SUMMARY_SKIP_GOALS|_DIRECT_NON_BUILD|_INVALID_GOALS|VALID_TARGETS|binary_hex|MAKECMDGOALS|firstword|wordlist' Makefile || true

echo
echo "== Makefile lines 330-430 =="
sed -n '330,430p' Makefile | cat -n

echo
echo "== Makefile lines 470-560 =="
sed -n '470,560p' Makefile | cat -n

echo
echo "== Makefile lines 560-640 =="
sed -n '560,640p' Makefile | cat -n

Length of output: 22879



@nerdCopter Full pass complete on current tip 17f532700eb3 (17f532700e), and based on the current Makefile plus the verification matrix you posted, I’m satisfied that the previously raised issues are closed.

1. Prior concerns
All 5 are resolved:

  • Concurrent marker collisions: closed. summary_build now creates a per-invocation temp dir with mktemp -d and passes BUILD_SUMMARY_PASSED / BUILD_SUMMARY_FAILED into the sub-make instead of relying on shared global marker files. See Line 359 through Line 367, especially Line 361, Line 362, and Line 366.
  • Non-build goal interception: closed. _SUMMARY_SKIP_GOALS now includes both utility targets and named meta/group targets, and IN_SUMMARY_OUTER is only enabled when _DIRECT_NON_BUILD is empty. See Line 329 through Line 345.
  • Unknown goals not counted in the failed summary: closed. _INVALID_GOALS is computed in the outer intercepted path and passed into summary_build, where it is pre-seeded into the failed marker before the inner make runs. See Line 365, Line 501, and Line 508.
  • $(V0) @echo`` double-@ bug: closed. The inner target recipe now uses plain `@echo` directly. See Line 516.
  • Mixed meta/group invocations like make all HELIOSPRING: closed. all, supported, all_with_unsupported, unsupported, and all targets-group-* entries are now in _SUMMARY_SKIP_GOALS, so those mixed invocations no longer get rewritten into the direct-target summary path. See Line 331 through Line 338.

2. Complete solution
For the invocation classes you asked about, the coverage looks complete:

  • Single target: make HELIOSPRING is routed through summary_build. See Line 529 and Line 530.
  • Named groups: all, supported, all_with_unsupported, unsupported, and targets-group-* all go through summary_build. See Line 434 through Line 491.
  • Arbitrary direct multi-target: intercepted by the outer path, with the first goal running summary_build and the remaining goals turned into no-ops so make doesn’t fail early on the outer parse. See Line 493 through Line 508.
  • Mixed valid + invalid direct goals: also covered by that same outer path, with invalid goals pre-counted into the failed marker and still propagated as an inner make failure. See Line 365, Line 366, Line 501, and Line 508.

I do not see a remaining logic gap in the intended paths you listed.

3. CI failure propagation
The non-zero exit path is wired correctly end-to-end:

  1. Inner target build fails
    In the IN_SUMMARY_BUILD branch, the per-target recipe runs $(MAKE) binary_hex TARGET=$@; on failure it appends the target to $(BUILD_SUMMARY_FAILED) and exit 1. See Line 517 through Line 523.

  2. summary_build captures that failure
    The sub-make is invoked as:
    $(MAKE) ... $(1) || _exit=$$?
    so any non-zero inner result is preserved in _exit. See Line 366.

  3. Outer recipe returns non-zero
    After printing the summary, the macro ends with:
    [ "$$_exit" -eq 0 ] && [ "$$failed" -eq 0 ]
    so the recipe fails if either:

    • the inner make returned non-zero, or
    • the failed-marker count is non-zero.
      See Line 375.

That means CI should correctly fail for both:

  • an actual board build failure, and
  • an invalid direct goal passed through the summary path.

Bottom line: from my review, the implementation at 17f532700e resolves the earlier findings and now looks consistent and complete for the requested feature set.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Makefile`:
- Around line 329-339: The summary interception logic is treating per-target
clean aliases as build targets because _SUMMARY_SKIP_GOALS and the
_DIRECT_NON_BUILD filter do not include clean_<target> and <target>_clean.
Update the Makefile goal filtering around _SUMMARY_SKIP_GOALS/_DIRECT_NON_BUILD
so these aliases are recognized as non-build goals, ensuring mixed commands like
make HELIOSPRING clean_HELIOSPRING do not enter IN_SUMMARY_OUTER or get counted
as invalid targets.
- Around line 501-508: The Makefile summary-build wrapper is still forwarding
invalid goals into the inner make invocation, which causes the first bad target
to stop processing the rest. Update the logic around the summary_build call so
the first target only passes valid goals, using the existing _INVALID_GOALS and
VALID_TARGETS filtering in the Makefile target handling. Keep the placeholder
targets and the summary_build entrypoint intact, but ensure the inner make
receives only the filtered valid goals.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4b93c67d-49d9-4b44-8739-ad76dc8e8b24

📥 Commits

Reviewing files that changed from the base of the PR and between 7cc284c and 17f5327.

📒 Files selected for processing (1)
  • Makefile
📜 Review details
⏰ Context from checks skipped due to timeout. (13)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: build (targets-group-3)
  • GitHub Check: build (targets-group-5)
  • GitHub Check: build (targets-group-rest)
  • GitHub Check: build (targets-group-4)
  • GitHub Check: build (targets-group-7)
  • GitHub Check: build (targets-group-11)
  • GitHub Check: build (targets-group-6)
  • GitHub Check: build (targets-group-10)
  • GitHub Check: build (targets-group-8)
  • GitHub Check: build (targets-group-1)
  • GitHub Check: build (targets-group-9)
  • GitHub Check: build (targets-group-2)
🧰 Additional context used
🪛 checkmake (0.3.2)
Makefile

[warning] 529-529: Target "$(VALID_TARGETS)" defined multiple times (lines 515 and 529).

(uniquetargets)


[warning] 515-515: Target body for "$(VALID_TARGETS)" exceeds allowed length of 5 lines (9).

(maxbodylength)


[warning] 503-503: Required target "all" is missing from the Makefile.

(minphony)


[warning] 503-503: Required target "test" is missing from the Makefile.

(minphony)

🔇 Additional comments (4)
Makefile (4)

351-376: LGTM!


432-492: LGTM!


515-530: LGTM!


571-571: LGTM!

Comment thread Makefile Outdated
Comment thread Makefile Outdated
Two problems with the previous hardcoded _SUMMARY_SKIP_GOALS list:
1. Brittle — new phony targets added to the Makefile required a manual
   entry here or they would incorrectly trigger IN_SUMMARY_OUTER.
2. Incomplete — openocd-gdb, targets-f3/f4/f7/h7, and junittest were
   missing, leaving those mixed invocations unguarded.

Fix: consolidate ALL phony target declarations into the single .PHONY
line at the top of the summary section (before the detection block).
Then derive _SUMMARY_SKIP_GOALS from it:

  _SUMMARY_SKIP_GOALS := $(filter-out $(VALID_TARGETS), $(.PHONY)) $(NOBUILD_TARGETS)

$(.PHONY) is fully populated by the time ":=" evaluates it because the
declaration appears before the detection block.  $(NOBUILD_TARGETS) covers
board names with .nomk files (not phony, not in VALID_TARGETS).

Any future phony target added to .PHONY is automatically excluded from
IN_SUMMARY_OUTER with no further changes required.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai, AI generated comment

Please do a thorough inspection of commit 2117b263a6 — specifically the .PHONY consolidation and the _SUMMARY_SKIP_GOALS derivation change. This is a structural change to how IN_SUMMARY_OUTER is suppressed for non-board-target invocations.

What changed and why

The previous hardcoded _SUMMARY_SKIP_GOALS list was both brittle and incomplete — it was missing openocd-gdb, targets-f3/f4/f7/h7, and junittest. Any new phony target added to the Makefile would silently be missing from the list.

The fix: all phony targets are now declared in a single consolidated .PHONY block before the detection block (line 311). _SUMMARY_SKIP_GOALS is then derived as:

_SUMMARY_SKIP_GOALS := $(filter-out $(VALID_TARGETS), $(.PHONY)) $(NOBUILD_TARGETS)

$(.PHONY) is a GNU Make special variable that accumulates all .PHONY declarations seen so far during parsing. Because the consolidated .PHONY block appears before the := assignment, all phony targets are present at evaluation time. $(NOBUILD_TARGETS) covers board names with .nomk files (not phony, not in VALID_TARGETS). The result: any future phony target added to .PHONY is automatically excluded from IN_SUMMARY_OUTER with no further changes required.

Please specifically verify:

  1. GNU Make .PHONY timing — Does $(.PHONY) at := evaluation time (line 339) correctly contain all targets declared in the .PHONY block at line 311? Are there any GNU Make versions or edge cases where this ordering guarantee breaks?

  2. IN_SUMMARY_OUTER suppression correctness — For each of these invocations, confirm the gate fires or suppresses correctly:

    • make HELIOSPRING FOXEERF405 → should intercept (2 board targets, no phony)
    • make HELIOSPRING FOOBAR → should intercept (1 board + 1 unknown)
    • make all HELIOSPRING → should NOT intercept (all is now in .PHONY_SUMMARY_SKIP_GOALS)
    • make targets-group-1 HELIOSPRING → should NOT intercept
    • make clean HELIOSPRING → should NOT intercept
    • make FOOBAR → should NOT intercept (0 board targets, single goal)
  3. User-expectation — Named-group targets (all, targets-group-*, etc.) print statistics because their own recipes call summary_build directly — they are unaffected by IN_SUMMARY_OUTER. Does the .PHONY-derived approach correctly preserve this? Is there any path where a user would expect statistics but not get them, or vice versa?

  4. CI correctness — Does this change affect the exit-code path in any CI scenario? Specifically: if a CI job runs make targets-group-1 -j 48 and a target fails, does the exit code still propagate correctly through summary_build?

  5. $(NOBUILD_TARGETS) inclusion — These are board names with .nomk files, excluded from VALID_TARGETS but with a real (non-phony) recipe. Is their inclusion in _SUMMARY_SKIP_GOALS correct and necessary? What happens with make NOBUILD_BOARD HELIOSPRING if they are or are not in the list?

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== HEAD and target commit =="
git rev-parse --short=12 HEAD
git log --oneline -n 8
echo
git show --stat --oneline --no-patch 2117b263a6 || true

echo
echo "== Makefile diff for commit 2117b263a6 =="
git show --unified=80 --format=medium 2117b263a6 -- Makefile || true

echo
echo "== summary-related locations in current Makefile =="
rg -n -C4 '\.PHONY|_SUMMARY_SKIP_GOALS|IN_SUMMARY_OUTER|_DIRECT_NON_BUILD|_DIRECT_VALID|_INVALID_GOALS|summary_build|VALID_TARGETS|NOBUILD_TARGETS|targets-group|all_with_unsupported|supported|unsupported' Makefile || true

echo
echo "== current Makefile around consolidated .PHONY and detection block =="
sed -n '285,370p' Makefile | cat -n

echo
echo "== current Makefile around named-group targets and summary_build outer interception =="
sed -n '430,560p' Makefile | cat -n

echo
echo "== current Makefile around VALID_TARGETS rule / IN_SUMMARY_BUILD branch =="
sed -n '560,635p' Makefile | cat -n

echo
echo "== isolated GNU make experiment: does \$(.PHONY) expand to declared phony targets? =="
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

cat > "$tmpdir/Makefile" <<'EOF'
.PHONY: all clean foo bar
NOW_SIMPLE := $(.PHONY)
NOW_RECURSIVE = $(.PHONY)

print:
	`@echo` "NOW_SIMPLE=[$(NOW_SIMPLE)]"
	`@echo` "NOW_RECURSIVE=[$(NOW_RECURSIVE)]"
	`@echo` "DIRECT=[$(.PHONY)]"

later:
	@:

.PHONY: later baz
AFTER_SIMPLE := $(.PHONY)
AFTER_RECURSIVE = $(.PHONY)

print-after:
	`@echo` "AFTER_SIMPLE=[$(AFTER_SIMPLE)]"
	`@echo` "AFTER_RECURSIVE=[$(AFTER_RECURSIVE)]"
	`@echo` "DIRECT_AFTER=[$(.PHONY)]"
EOF

echo "-- make version --"
make --version | head -n 1
echo "-- running print target --"
make -s -f "$tmpdir/Makefile" print || true
echo "-- running print-after target --"
make -s -f "$tmpdir/Makefile" print-after || true

echo
echo "== isolated GNU make experiment: can make database reveal phony targets? =="
make -pn -f "$tmpdir/Makefile" print 2>/dev/null | rg -n '^[.]PHONY|^NOW_SIMPLE|^AFTER_SIMPLE|^NOW_RECURSIVE|^AFTER_RECURSIVE' || true

Length of output: 35913


🌐 Web query:

GNU Make documentation special variables .PHONY variable expansion $(.PHONY) built-in special variable or target ordering parse-time immediate assignment :=

Length of output: 12770


🌐 Web query:

GNU Make "$( .PHONY )" special variable does $(.PHONY) expand to phony targets? Is .PHONY only a special target not a variable?

Length of output: 12676



@nerdCopter I did a careful pass on 2117b263a6, and I think this change introduces a new blocking risk.

Main concern

I do not think $(.PHONY) is a safe thing to rely on here.

From the GNU Make docs, .PHONY is documented as a special target, while the documented list of special variables includes things like $(.DEFAULT_GOAL) and $(.VARIABLES) but does not include $(.PHONY). So while := is indeed evaluated immediately during parsing, I don’t see evidence that $(.PHONY) is a defined GNU Make variable at all. In other words, the timing argument only helps if $(.PHONY) is a real variable, and the docs I checked do not support that.

That makes this line at Line 339 look unsafe:

_SUMMARY_SKIP_GOALS := $(filter-out $(VALID_TARGETS), $(.PHONY)) $(NOBUILD_TARGETS)

If $(.PHONY) expands empty, then _SUMMARY_SKIP_GOALS effectively collapses to just $(NOBUILD_TARGETS), which would re-open the mixed-goal interception bug you already fixed earlier.

Answers to your checklist

1. GNU Make .PHONY timing

I can confirm the := part: GNU Make evaluates := immediately while parsing.

I cannot confirm the $(.PHONY) part, and based on the docs I found, I think the premise is likely wrong: .PHONY is a special target, not a documented special variable. So I would not treat $(.PHONY) as portable or reliable GNU Make behavior.

So my answer here is:

  • Timing of :=: yes
  • $(.PHONY) containing the phony target set: not established, and likely invalid

2. IN_SUMMARY_OUTER suppression correctness

Assuming documented GNU Make behavior, the gate outcomes would be:

  • make HELIOSPRING FOXEERF405intercepts
    _DIRECT_VALID is non-empty, no known skip goal present.

  • make HELIOSPRING FOOBARintercepts
    Same reasoning; unknown goals are intentionally allowed through.

  • make all HELIOSPRINGwould incorrectly intercept
    If all is not actually coming from $(.PHONY), then _DIRECT_NON_BUILD stays empty.

  • make targets-group-1 HELIOSPRINGwould incorrectly intercept

  • make clean HELIOSPRINGwould incorrectly intercept

  • make FOOBARdoes not intercept
    Single goal, and also no valid target in _DIRECT_VALID.

So the behavior you want is correct in principle, but I don’t think this derivation actually guarantees it.

3. User expectation

Pure named-group targets are still fine.

Because all, supported, all_with_unsupported, unsupported, and all targets-group-* targets still call summary_build directly at Line 435 through Line 492, commands like:

  • make all
  • make targets-group-1

should still print the expected summary.

So this change does not break the pure named-group path.

However, it likely re-breaks mixed invocations such as:

  • make all HELIOSPRING
  • make targets-group-1 HELIOSPRING
  • make clean HELIOSPRING

Those should be suppressed out of IN_SUMMARY_OUTER, but with the current derivation I don’t think that’s reliably happening.

So my answer is:

  • Pure group targets: preserved
  • Mixed phony/meta + board invocations: likely regressed

4. CI correctness

For a CI command like:

  • make targets-group-1 -j 48

I do not see this commit changing the exit-code propagation path. That path still goes through:

  • named-group target recipe → summary_build at Line 447 through Line 492
  • inner build failure handling at Line 516 through Line 524
  • _exit capture inside summary_build at Line 361 through Line 375

So for the pure group-target CI case you asked about, the non-zero exit should still propagate correctly.

Where I do see risk is mixed-goal CI invocations, because if IN_SUMMARY_OUTER is triggered when it should have been suppressed, then CI semantics for those commands can again diverge from normal make behavior.

5. $(NOBUILD_TARGETS) inclusion

Yes — this is still correct and necessary.

This part is actually important even aside from the .PHONY issue.

$(NOBUILD_TARGETS) are:

  • not in $(VALID_TARGETS)
  • not phony
  • but they do have a real rule at Line 536 through Line 538

If they are not in _SUMMARY_SKIP_GOALS, then a command like:

  • make NOBUILD_BOARD HELIOSPRING

can incorrectly enter IN_SUMMARY_OUTER because _DIRECT_VALID sees HELIOSPRING, and NOBUILD_BOARD won’t be recognized as a non-build goal.

Then Line 502 does this:

_INVALID_GOALS := $(filter-out $(VALID_TARGETS), $(MAKECMDGOALS))

which would classify NOBUILD_BOARD as “invalid”, pre-seed it into the failed marker, and count it as a failure even though it has a legitimate rule.

So $(NOBUILD_TARGETS) absolutely belongs in the skip list.

Recommendation

I’d keep the “single source of truth” idea, but I would not derive from $(.PHONY).

A safer pattern would be to define an explicit variable once, then reuse it for both .PHONY and _SUMMARY_SKIP_GOALS, e.g.:

SUMMARY_PHONY_GOALS := \
    clean clean_test clean_all all_clean binary_hex \
    all supported all_with_unsupported unsupported \
    targets-group-1 targets-group-2 targets-group-3 targets-group-4 \
    targets-group-5 targets-group-6 targets-group-7 targets-group-8 \
    targets-group-9 targets-group-10 targets-group-11 targets-group-rest \
    flash st-flash binary hex unbrick openocd-gdb \
    version help targets target-mcu targets-by-mcu \
    targets-f3 targets-f4 targets-f7 targets-h7 \
    cppcheck test junittest \
    check-target-independence check-fastram-usage-correctness

.PHONY: $(SUMMARY_PHONY_GOALS)

_SUMMARY_SKIP_GOALS := $(SUMMARY_PHONY_GOALS) $(NOBUILD_TARGETS)

That preserves the maintainability benefit without depending on undocumented $(.PHONY) expansion.

Bottom line

I’m not comfortable confirming this commit as correct in its current form.

  • The consolidation of the .PHONY declarations itself is fine.
  • The new derivation from $(.PHONY) is the problem.
  • Based on the docs, I think it likely reintroduces the mixed-goal interception bug for phony/meta targets.

nerdCopter and others added 2 commits June 26, 2026 13:45
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Y_PHONY_GOALS

$(.PHONY) is a special *target*, not a special variable — it expands
to empty in GNU Make 4.4.1 (verified).  The previous commit's
derivation collapsed _SUMMARY_SKIP_GOALS to just $(NOBUILD_TARGETS),
re-opening all mixed-goal interception bugs (make all HELIOSPRING,
make clean HELIOSPRING, etc.).

Fix using a single-source-of-truth variable SUMMARY_PHONY_GOALS that
drives both the .PHONY declaration and _SUMMARY_SKIP_GOALS:

  SUMMARY_PHONY_GOALS := clean ... all supported targets-group-* ...
  .PHONY: $(SUMMARY_PHONY_GOALS)
  _SUMMARY_SKIP_GOALS := $(SUMMARY_PHONY_GOALS) $(NOBUILD_TARGETS)

Maintainability is preserved: new phony targets are added to
SUMMARY_PHONY_GOALS once and both .PHONY and _SUMMARY_SKIP_GOALS
pick them up automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai, AI generated comment

You are correct — $(.PHONY) expands to empty in GNU Make 4.4.1 (verified locally). It is a special target, not a special variable. The previous commit was broken.

Fixed in a6c39fa9c5 using your suggested pattern exactly:

SUMMARY_PHONY_GOALS := \
    clean clean_test clean_all all_clean binary_hex \
    all supported all_with_unsupported unsupported \
    targets-group-1 ... targets-group-rest \
    flash st-flash binary hex unbrick openocd-gdb \
    version help targets target-mcu targets-by-mcu \
    targets-f3 targets-f4 targets-f7 targets-h7 \
    cppcheck test junittest \
    check-target-independence check-fastram-usage-correctness

.PHONY: $(SUMMARY_PHONY_GOALS)

_SUMMARY_SKIP_GOALS := $(SUMMARY_PHONY_GOALS) $(NOBUILD_TARGETS)

Single source of truth: SUMMARY_PHONY_GOALS drives both .PHONY and _SUMMARY_SKIP_GOALS. Adding a new phony target requires only one change.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@nerdCopter Thanks — that fixes the concern cleanly.

Using SUMMARY_PHONY_GOALS as the single source of truth for both .PHONY and _SUMMARY_SKIP_GOALS is the right approach here. It avoids relying on $(.PHONY) as if it were a variable, preserves the mixed-goal suppression behavior, and makes future phony-target additions much safer to maintain.


✏️ Learnings added
Learnt from: nerdCopter
URL: https://github.com/emuflight/EmuFlight/pull/1288

Timestamp: 2026-06-26T19:00:39.899Z
Learning: In the EmuFlight `Makefile`, GNU Make 4.4.1 treats `.PHONY` as a special target, not a variable, so `$(.PHONY)` expands to empty and must not be used to derive `_SUMMARY_SKIP_GOALS`. The correct maintainable pattern is to define an explicit `SUMMARY_PHONY_GOALS` variable, use `.PHONY: $(SUMMARY_PHONY_GOALS)`, and derive `_SUMMARY_SKIP_GOALS := $(SUMMARY_PHONY_GOALS) $(NOBUILD_TARGETS)`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Finding 1 — pass only valid goals to the inner make (Makefile:516)
  summary_build was called with the full $(MAKECMDGOALS) including
  invalid/unknown goals as $(1).  Without -k the inner make stops on
  the first unknown goal and never builds the valid targets that follow.
  Invalid goals are already pre-counted in the failed marker via $(2);
  they do not need to reach the sub-make.  Fix: compute _VALID_GOALS
  and pass that as $(1) instead of $(MAKECMDGOALS).

Finding 2 — exclude per-target clean aliases from interception
  clean_<target> and <target>_clean are generated by CLEAN_TARGETS /
  TARGETS_CLEAN but are not in SUMMARY_PHONY_GOALS.  A command like
  `make HELIOSPRING clean_HELIOSPRING` triggered IN_SUMMARY_OUTER and
  counted the clean alias as a failed build target.  Fix: add clean_%
  and %_clean patterns to the $(filter) call for _DIRECT_NON_BUILD.
  GNU Make's $(filter) supports % wildcards, so these match any
  clean_<name> or <name>_clean goal without enumerating all targets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai, AI generated comment

Both findings addressed in 00bad6806a:

Finding 1 — pass only valid goals to the inner make (line 516)
Fixed. Added _VALID_GOALS := $(filter $(VALID_TARGETS), $(MAKECMDGOALS)) and changed the summary_build call to $(call summary_build,$(_VALID_GOALS),$(_INVALID_GOALS)). Invalid goals are pre-counted in the failed marker via $(2) — they no longer reach the sub-make, so valid targets always build regardless of -k.

Finding 2 — per-target clean aliases not in _SUMMARY_SKIP_GOALS
Fixed. Added clean_% %_clean patterns directly to the $(filter) call for _DIRECT_NON_BUILD. GNU Make's $(filter) supports % wildcards, so these match any clean_<name> or <name>_clean goal without enumerating all targets.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@nerdCopter Thanks — both fixes sound correct.

Passing only $(filter $(VALID_TARGETS),$(MAKECMDGOALS)) into the inner summary_build path cleanly avoids the -k dependency for direct mixed valid/invalid invocations, while still counting invalid goals via the failed marker. And adding clean_% / %_clean to the _DIRECT_NON_BUILD filter is the right way to keep per-target clean aliases out of the summary interception path.

Looks good from my side. 🐇


✏️ Learnings added
Learnt from: nerdCopter
URL: https://github.com/emuflight/EmuFlight/pull/1288

Timestamp: 2026-06-26T19:32:10.164Z
Learning: In the EmuFlight `Makefile`, the direct-goal summary interception path should pass only `_VALID_GOALS := $(filter $(VALID_TARGETS), $(MAKECMDGOALS))` into `summary_build`; invalid goals must be handled separately via `_INVALID_GOALS` and pre-counted in the failed marker so valid targets still build regardless of `-k`.

Learnt from: nerdCopter
URL: https://github.com/emuflight/EmuFlight/pull/1288

Timestamp: 2026-06-26T19:32:10.164Z
Learning: In the EmuFlight `Makefile`, `_DIRECT_NON_BUILD` must also match per-target clean aliases using GNU Make `filter` patterns `clean_%` and `%_clean`; otherwise invocations like `make clean_HELIOSPRING HELIOSPRING` or `make HELIOSPRING_clean HELIOSPRING` can incorrectly trigger `IN_SUMMARY_OUTER`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@nerdCopter

nerdCopter commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai, are ALL concerns resolved? even nitpicks?

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@nerdCopter Yes — from my side, all previously raised concerns are resolved, including the nitpicks.

At this point I’m not seeing any remaining:

  • blockers
  • correctness issues
  • edge-case gaps in the intended invocation paths
  • CI exit-code propagation problems
  • lingering maintainability nitpicks from the review thread

So on the current branch state discussed above, I consider the Makefile changes review-clean.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@nerdCopter Yes — from my side, all previously raised concerns are resolved, including the nitpicks.

That includes:

  • concurrent marker-file collisions
  • mixed non-build/meta goal interception
  • invalid goals not being counted in the failed summary
  • the $(V0) / @echo quiet-mode issue
  • mixed group-target invocations like make all HELIOSPRING
  • the broken $(.PHONY)-based derivation
  • passing only valid goals to the inner sub-make
  • excluding clean_% / %_clean aliases from summary interception

So at this point I’m not seeing any remaining blockers, majors, or nitpicks in the current approach.

@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai, AI generated comment

Both findings were already addressed in 00bad6806a before your responses arrived — the @coderabbitai, resolved? pings ran against the previous tip.

clean_% / %_clean alias interception
Fixed in 00bad6806a: _DIRECT_NON_BUILD now uses $(filter $(_SUMMARY_SKIP_GOALS) clean_% %_clean, $(MAKECMDGOALS)). GNU Make's $(filter) supports % wildcards, so all per-target clean aliases match without enumeration.

Pass only valid goals to the inner make
Fixed in 00bad6806a: added _VALID_GOALS := $(filter $(VALID_TARGETS), $(MAKECMDGOALS)) and the summary_build call now passes $(_VALID_GOALS) as $(1) instead of $(MAKECMDGOALS). Invalid goals are pre-counted in the failed marker via $(2) and never forwarded to the sub-make, so valid targets always build regardless of -k.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@nerdCopter Got it — thanks for the clarification. I understand now that my earlier “resolved?” replies were looking at the previous tip, and 00bad6806a had already fixed both items.

Those two concerns are closed from my side:

  • clean_% / %_clean are now correctly excluded from IN_SUMMARY_OUTER
  • only _VALID_GOALS are forwarded to the inner summary_build, with invalid goals counted separately

No further concern on either point. 🐇

The old recipe called $(MAKE) TARGET=$${target} for each matching
target — a variable override, not a goal. This bypassed the
$(VALID_TARGETS) recipe entirely so summary_build was never invoked
and targets-f3/f4/f7/h7 never printed build statistics.

Fix: collect all matching targets into a shell variable first, then
call $(MAKE) $$_targets with them as goals. Two or more targets
triggers IN_SUMMARY_OUTER and an aggregate summary; a single match
takes the single-target summary_build path. Both print statistics.

Removes the old fail-fast exit-1-per-target logic; summary_build
already records and reports all failures via marker files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai, everything account for as of fc3b163 ? will ALL make <target-parameter> options work now?

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== HEAD =="
git rev-parse --short=12 HEAD
git log --oneline -n 8

echo
echo "== show target commit if present =="
git show --stat --oneline --no-patch fc3b163 || true

echo
echo "== summary-related sections in Makefile =="
rg -n -C4 'SUMMARY_PHONY_GOALS|_SUMMARY_SKIP_GOALS|_DIRECT_NON_BUILD|_DIRECT_VALID|_VALID_GOALS|_INVALID_GOALS|IN_SUMMARY_OUTER|IN_SUMMARY_BUILD|summary_build|MAKECMDGOALS|clean_%|%_clean|NOBUILD_TARGETS|VALID_TARGETS|targets-group|all_with_unsupported|supported|unsupported|openocd-gdb|targets-f3|targets-f4|targets-f7|targets-h7|junittest' Makefile || true

echo
echo "== Makefile around phony + detection block =="
sed -n '300,390p' Makefile | cat -n

echo
echo "== Makefile around summary_build and group targets =="
sed -n '430,560p' Makefile | cat -n

echo
echo "== Makefile around VALID_TARGETS/NOBUILD_TARGETS rules =="
sed -n '560,640p' Makefile | cat -n

echo
echo "== phony targets declared in Makefile =="
rg -n '^[.]PHONY:' Makefile || true

Length of output: 27369


@nerdCopter Yes — as of fc3b163, I think all of the intended/supported make <target> invocation paths for this feature are accounted for.

What now looks covered:

  • Direct single board target

    • make HELIOSPRING
    • routes through summary_build, so it gets the same summary behavior as multi-target runs.
  • Direct multi-board targets

    • make HELIOSPRING FOXEERF405
    • intercepted by IN_SUMMARY_OUTER, with only valid goals forwarded inward.
  • Mixed valid + invalid direct goals

    • make HELIOSPRING FOOBAR
    • valid targets still build, invalid ones are pre-counted in the failed marker, and the outer make exits non-zero.
  • Named/meta group targets

    • make all
    • make supported
    • make all_with_unsupported
    • make unsupported
    • make targets-group-*
    • all call summary_build directly.
  • MCU fan-out targets

    • make targets-by-mcu MCU_TYPE=...
    • make targets-f3 / targets-f4 / targets-f7 / targets-h7
    • these now flow into the same summary-enabled direct-target path.
  • Non-build and clean-style invocations keep normal behavior

    • make clean HELIOSPRING
    • make all HELIOSPRING
    • make targets-group-1 HELIOSPRING
    • make clean_HELIOSPRING HELIOSPRING
    • make HELIOSPRING_clean HELIOSPRING
    • all are suppressed out of IN_SUMMARY_OUTER correctly.
  • CI failure propagation

    • still looks correct end-to-end: inner failure/invalid target → failed marker and/or non-zero _exitsummary_build returns non-zero → outer make fails.

The one place I’d still not call “all options” in the literal sense is the caveat already documented in the file: Line 437 through Line 438 still warns that combining multiple group/meta targets in one command, such as make all targets-group-1, is not specially handled and may lead to overlapping work/failures under parallelism.

So my bottom line is:

  • Yes for all the expected/supported target-parameter forms this PR is trying to cover.
  • No, not literally every arbitrary mix of make goals, because the multi-group/meta overlap caveat still exists by design.

I’m not seeing any remaining blocker, major, or nitpick beyond that explicit documented caveat.

@nerdCopter nerdCopter marked this pull request as ready for review June 30, 2026 20:06
@nerdCopter

Copy link
Copy Markdown
Member Author

@coderabbitai approve

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
✅ Action performed

Comments resolved and changes approved.

@nerdCopter nerdCopter merged commit b9c37bd into emuflight:master Jun 30, 2026
18 checks passed
@nerdCopter nerdCopter deleted the feat/build-summary branch June 30, 2026 20:09
nerdCopter added a commit to nerdCopter/EmuFlight_nerdRepo that referenced this pull request Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

build: add pass/fail summary after make all

1 participant