[Fix] (Purity, Program, Pipe): close the review minors of the three P0.5 packages

- check_include_closure.py keeps the directory of a two-token -isystem, makes --require-all
  fail on a missing required header even when --probe narrowed the run, and removes its
  temp dir at exit
- ProgramArtifactsTest follows whichever STL branch the header pinned (#ifdef the size
  macro) instead of re-spelling the libstdc++ condition, and loses its stray executable bit
- MGPipeTypes.h's debt comment says what its closure still reaches (TextureEnum.h via
  BackendObject.h), which is why gate A asserts MGPipeValueTypes.h and not this header
This commit is contained in:
2026-09-05 23:14:30 -04:00
parent 09d2bb11b7
commit b566bf4db9
4 changed files with 23 additions and 4 deletions
+2 -1
View File
@@ -24,7 +24,8 @@
//
// P0.5 DEBT, half repaid. The MG_State half is gone: ResidualValueBlock's
// RenderStateParameters and PixelStoreParameters now come from MGPipeValueTypes.h, so
// this header no longer reaches into MG_State. What remains is MGPCaps embedding
// this header no longer reaches RenderState.h (its closure still touches TextureEnum.h,
// through BackendObject.h, for the reason in the next sentence). What remains is MGPCaps embedding
// MG_Backend's DynamicBackendParameters - deliberate, the caps block IS that struct
// (section 4.4.1) - and that one include is what still keeps purity gate A (section
// 10.3) off this header; the gate asserts MGPipeValueTypes.h instead. The caps block
@@ -15,7 +15,7 @@
#include <set> // std::set<String> (LinkArtifacts); NOT provided by Includes.h on its own terms
// PURITY: no ShaderObject.h, no SpvcSession.h, nothing under MG_Util/ShaderTranspiler/, no Config.h,
// no MG_Backend/, no BufferState/. scripts/check_include_closure.py probe "artifacts-header" (ROADMAP P0.5;
// ARCHITECTURE.md:260) asserts that closure. the glslang scope token appears exactly twice below (B.0 D5: the two
// ARCHITECTURE.md:260) asserts that closure. The glslang scope token appears exactly twice below (B.0 D5: the two
// glslang-typed LinkArtifacts members moved verbatim) and the gate pins that count.
namespace MobileGL::MG_State::GLState {
+1 -1
View File
@@ -121,7 +121,7 @@ namespace {
std::printf("sizeof: TypeFacts=%zu ResourceReflection=%zu XfbVarying=%zu LinkArtifacts=%zu SpirvArtifacts=%zu\n",
sizeof(TypeFacts), sizeof(ResourceReflection), sizeof(XfbVarying), sizeof(LinkArtifacts),
sizeof(SpirvArtifacts));
#if defined(__GLIBCXX__) && !defined(_GLIBCXX_DEBUG) && (SIZE_MAX == UINT64_MAX)
#ifdef MGL_LINKARTIFACTS_SIZE // whichever STL branch the header pinned, this twin follows it
EXPECT_EQ(sizeof(ResourceReflection), static_cast<std::size_t>(MGL_RESOURCEREFLECTION_SIZE));
EXPECT_EQ(sizeof(XfbVarying), static_cast<std::size_t>(MGL_XFBVARYING_SIZE));
EXPECT_EQ(sizeof(LinkArtifacts), static_cast<std::size_t>(MGL_LINKARTIFACTS_SIZE));
+19 -1
View File
@@ -50,6 +50,7 @@ once they exist - the integrator flips `--require-all` on as the ratchet.
"""
import argparse
import atexit
import json
import os
import re
@@ -317,7 +318,12 @@ def flags_from_compile_commands(path):
tokens = shlex.split(entry.get("command", ""))
flags = []
skip_next = False
keep_next = False
for token in tokens[1:]:
if keep_next:
keep_next = False
flags.append(token)
continue
if skip_next:
skip_next = False
continue
@@ -325,8 +331,9 @@ def flags_from_compile_commands(path):
skip_next = token in ("-o", "-MF", "-MT", "-MQ")
continue
if token == "-isystem":
skip_next = False
# two-token form: keep the flag AND its directory
flags.append(token)
keep_next = True
continue
if token.startswith(keep_prefixes):
flags.append(token)
@@ -570,6 +577,7 @@ def main():
check_clang_prereqs()
tmpdir = tempfile.mkdtemp(prefix="mgl-include-closure-")
atexit.register(shutil.rmtree, tmpdir, True)
context = {
"tmpdir": tmpdir,
"counter": [0],
@@ -600,6 +608,16 @@ def main():
results = []
problems = 0
skipped = 0
if args.require_all:
# The ratchet is about the two P0.5 headers existing, whether or not --probe
# narrowed this run to something else: a required header that is missing is a
# failure even when its probe was not selected.
selected_names = {probe["Name"] for probe in selected}
for probe in PROBES:
if probe["Name"] in REQUIRED_PROBE_NAMES and probe["Name"] not in selected_names and not os.path.isfile(os.path.join(REPO_ROOT, probe["Header"])):
problems += 1
say("{} is required under --require-all but its header does not exist: {}".format(
probe["Name"], probe["Header"]))
for probe in selected:
# D9: a header that does not exist yet is one SKIP line, counted once, and a
# failure only under --require-all (the ratchet the integrator flips).