From e8bb2e2120357a43d2e549c786792026cbd2f0d4 Mon Sep 17 00:00:00 2001 From: Yuma Endo Date: Sun, 22 Mar 2026 12:27:20 +0900 Subject: [PATCH 1/2] feat: add per-mold platform support declaration Add optional source.platforms.supported field to mold schema. When specified, only listed platforms are built. When omitted, all Tier 1 platforms are used (backward compatible). Changes: - schema: add platformSupport definition with validated platform IDs - GCC 15.2.0 mold.toml: set supported to linux-x86_64 + linux-aarch64 (upstream GCC does not support aarch64-apple-darwin natively) - ingot-cast.yml: filter build matrix by source.platforms.supported - ingot-cast.yml: use per-mold expected count in completeness check --- .github/workflows/ingot-cast.yml | 40 ++++++++++++++++++++++++++------ molds/gcc/15.2.0/mold.toml | 5 ++++ schema/mold-v1.schema.json | 16 +++++++++++++ 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ingot-cast.yml b/.github/workflows/ingot-cast.yml index a550e79..8795c9e 100644 --- a/.github/workflows/ingot-cast.yml +++ b/.github/workflows/ingot-cast.yml @@ -183,7 +183,9 @@ jobs: done # === Step 3: Generate build matrix === - # Cross each build-type mold with all Tier 1 platforms from platforms.toml. + # Cross each build-type mold with its supported platforms. + # If source.platforms.supported is specified, only those platforms are used. + # Otherwise, all Tier 1 platforms from platforms.toml are used. # The matrix is consumed by cast-build-configure/make/package jobs. if [[ "$HAS_BUILD" == "true" ]]; then @@ -213,21 +215,33 @@ jobs: mold = os.environ['MOLD_VAR'] with open(f'{mold}/mold.toml', 'rb') as f: data = tomllib.load(f) + supported = data.get('source', {}).get('platforms', {}).get('supported', []) print(json.dumps({ 'family': data['metadata']['family'], 'version': data['metadata']['version'], - 'glibc_min': data.get('source', {}).get('glibc_min', '') + 'glibc_min': data.get('source', {}).get('glibc_min', ''), + 'supported_platforms': supported })) ") FAMILY=$(echo "$MOLD_META" | jq -r '.family') VERSION=$(echo "$MOLD_META" | jq -r '.version') GLIBC_MIN=$(echo "$MOLD_META" | jq -r '.glibc_min') + SUPPORTED_PLATFORMS=$(echo "$MOLD_META" | jq -r '.supported_platforms | if length > 0 then .[] else empty end') while IFS= read -r platform_entry; do [[ -z "$platform_entry" ]] && continue PLAT=$(echo "$platform_entry" | jq -r '.platform') ARCH=$(echo "$platform_entry" | jq -r '.arch') + + # Filter by mold's supported platforms if specified + if [[ -n "$SUPPORTED_PLATFORMS" ]]; then + PLATFORM_ID="${PLAT}-${ARCH}" + if ! echo "$SUPPORTED_PLATFORMS" | grep -qx "$PLATFORM_ID"; then + echo " Skip: ${mold} ${PLATFORM_ID} (not in source.platforms.supported)" + continue + fi + fi RUNNER=$(echo "$platform_entry" | jq -r '.runner') CONTAINER=$(echo "$platform_entry" | jq -r '.container // ""') @@ -615,7 +629,7 @@ jobs: MOLD_META_FILES["$KEY"]+="${meta_file}"$'\n' done - # Read Tier 1 platform count for completeness check + # Read Tier 1 platform count (default for molds without source.platforms) TIER1_COUNT=$(python3 -c " import tomllib with open('platforms.toml', 'rb') as f: @@ -634,12 +648,24 @@ jobs: [[ -z "${META_LIST[-1]}" ]] && unset 'META_LIST[-1]' PLATFORM_COUNT=${#META_LIST[@]} + # Determine expected platform count: use source.platforms.supported + # if specified, otherwise fall back to Tier 1 count. + MOLD_DIR="molds/${key}" + EXPECTED_COUNT=$(MOLD_VAR="$MOLD_DIR" python3 -c " + import tomllib, os + mold = os.environ['MOLD_VAR'] + with open(f'{mold}/mold.toml', 'rb') as f: + data = tomllib.load(f) + supported = data.get('source', {}).get('platforms', {}).get('supported', []) + print(len(supported) if supported else ${TIER1_COUNT}) + ") + echo "" - echo "=== Processing: ${key} (${PLATFORM_COUNT}/${TIER1_COUNT} platforms) ===" + echo "=== Processing: ${key} (${PLATFORM_COUNT}/${EXPECTED_COUNT} platforms) ===" - # Per-mold completeness check: skip if not all Tier 1 platforms present - if [[ "$PLATFORM_COUNT" -lt "$TIER1_COUNT" ]]; then - echo "::warning::Skipping ${key}: only ${PLATFORM_COUNT}/${TIER1_COUNT} platforms available" + # Per-mold completeness check: skip if not all expected platforms present + if [[ "$PLATFORM_COUNT" -lt "$EXPECTED_COUNT" ]]; then + echo "::warning::Skipping ${key}: only ${PLATFORM_COUNT}/${EXPECTED_COUNT} platforms available" SKIP_COUNT=$((SKIP_COUNT + 1)) continue fi diff --git a/molds/gcc/15.2.0/mold.toml b/molds/gcc/15.2.0/mold.toml index c41b109..e2c319b 100644 --- a/molds/gcc/15.2.0/mold.toml +++ b/molds/gcc/15.2.0/mold.toml @@ -15,6 +15,11 @@ stdlib = "libstdc++" [source] type = "build" +# GCC 15.2.0 does not support aarch64-apple-darwin natively. +# Homebrew applies custom patches (iains/gcc-14-branch) to enable it. +[source.platforms] +supported = ["linux-x86_64", "linux-aarch64"] + [source.build] source_url = "https://ftp.gnu.org/gnu/gcc/gcc-15.2.0/gcc-15.2.0.tar.xz" source_sha256 = "438fd996826b0c82485a29da03a72d71d6e3541a83ec702df4271f6fe025d24e" diff --git a/schema/mold-v1.schema.json b/schema/mold-v1.schema.json index 22822e9..ba85552 100644 --- a/schema/mold-v1.schema.json +++ b/schema/mold-v1.schema.json @@ -109,10 +109,26 @@ "pattern": "^[0-9]+\\.[0-9]+$", "description": "Minimum glibc version required by pre-built binaries (e.g., 2.34). When specified, the build container is selected to satisfy this requirement." }, + "platforms": { "$ref": "#/$defs/platformSupport" }, "build_fallback": { "$ref": "#/$defs/buildFallback" }, "build": { "$ref": "#/$defs/buildDefinition" } } }, + "platformSupport": { + "type": "object", + "additionalProperties": false, + "properties": { + "supported": { + "type": "array", + "items": { + "type": "string", + "pattern": "^(linux|darwin)-(x86_64|aarch64)$" + }, + "minItems": 1, + "description": "Platforms this mold officially supports. If omitted, all Tier 1 platforms are assumed." + } + } + }, "sourceFetchRequired": { "if": { "properties": { From df023d5c64b976b8da56c310cf28b5974257a0be Mon Sep 17 00:00:00 2001 From: Yuma Endo Date: Sun, 22 Mar 2026 12:48:37 +0900 Subject: [PATCH 2/2] fix: intersect supported platforms with Tier 1 in completeness check - Completeness check now counts intersection of source.platforms.supported and Tier 1 platforms, preventing permanently unpushable molds when supported contains non-Tier-1 platform IDs - Add uniqueItems constraint to source.platforms.supported schema --- .github/workflows/ingot-cast.yml | 17 ++++++++++++----- schema/mold-v1.schema.json | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ingot-cast.yml b/.github/workflows/ingot-cast.yml index 8795c9e..5f9c91a 100644 --- a/.github/workflows/ingot-cast.yml +++ b/.github/workflows/ingot-cast.yml @@ -648,16 +648,23 @@ jobs: [[ -z "${META_LIST[-1]}" ]] && unset 'META_LIST[-1]' PLATFORM_COUNT=${#META_LIST[@]} - # Determine expected platform count: use source.platforms.supported - # if specified, otherwise fall back to Tier 1 count. + # Determine expected platform count: intersect source.platforms.supported + # with Tier 1 platforms. If source.platforms is omitted, use Tier 1 count. MOLD_DIR="molds/${key}" EXPECTED_COUNT=$(MOLD_VAR="$MOLD_DIR" python3 -c " import tomllib, os mold = os.environ['MOLD_VAR'] with open(f'{mold}/mold.toml', 'rb') as f: - data = tomllib.load(f) - supported = data.get('source', {}).get('platforms', {}).get('supported', []) - print(len(supported) if supported else ${TIER1_COUNT}) + mold_data = tomllib.load(f) + with open('platforms.toml', 'rb') as f: + plat_data = tomllib.load(f) + tier1_ids = {f\"{p['platform']}-{p['arch']}\" for p in plat_data['platforms']['tier1']} + supported = mold_data.get('source', {}).get('platforms', {}).get('supported', []) + if supported: + count = len(set(supported) & tier1_ids) + else: + count = len(tier1_ids) + print(count) ") echo "" diff --git a/schema/mold-v1.schema.json b/schema/mold-v1.schema.json index ba85552..7e0c32f 100644 --- a/schema/mold-v1.schema.json +++ b/schema/mold-v1.schema.json @@ -125,6 +125,7 @@ "pattern": "^(linux|darwin)-(x86_64|aarch64)$" }, "minItems": 1, + "uniqueItems": true, "description": "Platforms this mold officially supports. If omitted, all Tier 1 platforms are assumed." } }