@@ -10642,6 +10642,91 @@ def _audit_rp2_reject_driver_overrides(
1064210642 )
1064310643
1064410644
10645+ def _audit_rp2_build_environment(
10646+ builder_text: str,
10647+ *,
10648+ firmware_version: str,
10649+ ) -> list[str]:
10650+ """Parse one scrub command and its source-era-specific offline setup."""
10651+
10652+ marker = (
10653+ "# Never allow ambient compiler/make flags to influence the pinned build.\n"
10654+ "unset \\\n"
10655+ )
10656+ end = '\n\nmake -C "$RETAINED_UPSTREAM/mpy-cross"'
10657+ _require(
10658+ isinstance(builder_text, str)
10659+ and builder_text.count(marker) == 1
10660+ and builder_text.count(end) == 1,
10661+ "RP2 build driver environment scrub is missing or ambiguous",
10662+ )
10663+ before_make = builder_text.split(marker, 1)[1]
10664+ _require(end in before_make, "RP2 environment scrub does not precede mpy-cross")
10665+ section = before_make.split(end, 1)[0]
10666+ scrub, separator, setup = section.partition("\n\n")
10667+ lines = scrub.splitlines()
10668+ variables: list[str] = []
10669+ for index, line in enumerate(lines):
10670+ continued = line.endswith(" \\")
10671+ value = line[2:-2] if continued else line[2:]
10672+ _require(
10673+ line.startswith(" ")
10674+ and re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", value) is not None
10675+ and continued == (index < len(lines) - 1),
10676+ "RP2 build driver environment scrub is malformed",
10677+ )
10678+ variables.append(value)
10679+ _require(
10680+ len(variables) == len(set(variables))
10681+ and set(_RP2_GCC_ENVIRONMENT_OVERRIDES) <= set(variables),
10682+ "RP2 build driver does not scrub every GCC resolution override",
10683+ )
10684+ pinned_picotool = _firmware_release_core(
10685+ firmware_version, "RP2 environment source version"
10686+ ) >= (0, 6, 1)
10687+ if pinned_picotool:
10688+ _require(
10689+ {
10690+ "CMAKE_ARGS", "picotool_DIR", "FETCHCONTENT_FULLY_DISCONNECTED",
10691+ "FETCHCONTENT_SOURCE_DIR_PICOTOOL", "PICOTOOL_FETCH_FROM_GIT_PATH",
10692+ "PICOTOOL_FORCE_FETCH_FROM_GIT", "CMAKE_FIND_USE_PACKAGE_REGISTRY",
10693+ "CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY", "CMAKE_PREFIX_PATH",
10694+ } <= set(variables),
10695+ "RP2 build driver does not scrub every pinned package override",
10696+ )
10697+ expected_setup = r'''# Bind Pico SDK's CMake configure to the verified package and make every
10698+ # fallback/network or ambient package-registry path unavailable. These values
10699+ # are supplied both in CMAKE_ARGS (the MicroPython rp2 Makefile interface) and
10700+ # the environment so nested configure steps cannot inherit hostile settings.
10701+ CMAKE_ARGS="-Dpicotool_DIR=$PICOTOOL_PACKAGE_DIR \
10702+ -DFETCHCONTENT_FULLY_DISCONNECTED:BOOL=ON \
10703+ -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF \
10704+ -DCMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY=OFF \
10705+ -DPICOTOOL_FORCE_FETCH_FROM_GIT=OFF"
10706+ picotool_DIR="$PICOTOOL_PACKAGE_DIR"
10707+ FETCHCONTENT_FULLY_DISCONNECTED=ON
10708+ PICOTOOL_FORCE_FETCH_FROM_GIT=OFF
10709+ CMAKE_FIND_USE_PACKAGE_REGISTRY=OFF
10710+ CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY=OFF
10711+ export \
10712+ CMAKE_ARGS \
10713+ picotool_DIR \
10714+ FETCHCONTENT_FULLY_DISCONNECTED \
10715+ PICOTOOL_FORCE_FETCH_FROM_GIT \
10716+ CMAKE_FIND_USE_PACKAGE_REGISTRY \
10717+ CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY'''
10718+ _require(
10719+ separator == "\n\n" and setup == expected_setup,
10720+ "RP2 build driver pinned offline environment setup changed",
10721+ )
10722+ else:
10723+ _require(
10724+ not separator and not setup,
10725+ "historical RP2 scrub has unexpected intervening commands",
10726+ )
10727+ return variables
10728+
10729+
1064510730def _audit_observe_rp2_arm_runtime_closure(
1064610731 *,
1064710732 repo_root: Path,
@@ -10677,33 +10762,9 @@ def _audit_observe_rp2_arm_runtime_closure(
1067710762 builder_text = _read_regular_file_bytes(
1067810763 builder_path, "RP2 retained-source build driver"
1067910764 ).decode("utf-8", errors="strict")
10680- scrub_marker = (
10681- "# Never allow ambient compiler/make flags to influence the pinned build.\n"
10682- "unset \\\n"
10683- )
10684- scrub_end = '\n\nmake -C "$RETAINED_UPSTREAM/mpy-cross"'
10685- _require(
10686- builder_text.count(scrub_marker) == 1
10687- and builder_text.count(scrub_end) == 1,
10688- "RP2 build driver environment scrub is missing or ambiguous",
10689- )
10690- scrub_source = builder_text.split(scrub_marker, 1)[1].split(scrub_end, 1)[0]
10691- scrub_lines = scrub_source.splitlines()
10692- scrubbed_variables: list[str] = []
10693- for index, line in enumerate(scrub_lines):
10694- continued = line.endswith(" \\")
10695- value = line[:-2] if continued else line
10696- _require(
10697- line.startswith(" ")
10698- and re.fullmatch(r"[A-Z][A-Z0-9_]*", value.strip()) is not None
10699- and continued == (index < len(scrub_lines) - 1),
10700- "RP2 build driver environment scrub is malformed",
10701- )
10702- scrubbed_variables.append(value.strip())
10703- _require(
10704- len(scrubbed_variables) == len(set(scrubbed_variables))
10705- and set(_RP2_GCC_ENVIRONMENT_OVERRIDES) <= set(scrubbed_variables),
10706- "RP2 build driver does not scrub every GCC resolution override",
10765+ _audit_rp2_build_environment(
10766+ builder_text,
10767+ firmware_version=_read_lock(root)["pyble"]["agent_version"],
1070710768 )
1070810769
1070910770 cache_text = _read_regular_file_bytes(cache, "RP2 CMake cache").decode(
0 commit comments