|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Run only the exact public release inside the real native ARM64 SubOS. |
| 3 | +set -euo pipefail |
| 4 | +phase="${1:?usage: ecosystem-cn.sh release VERSION}" |
| 5 | +version="${2:?mcpp version under test required}" |
| 6 | +base="${XLINGS_HOME:?explicit isolated XLINGS_HOME required}" |
| 7 | +[[ "$(uname -m)" == aarch64 ]] || { echo "native ARM64 required"; exit 1; } |
| 8 | +[[ "$phase" == release ]] || { echo "published release only"; exit 1; } |
| 9 | +[[ ! -d "${CN_HOST_CHECKOUT:?host checkout path required}" ]] || { |
| 10 | + echo 'host checkout must not be visible in the SubOS'; exit 1; |
| 11 | +} |
| 12 | +xl="${CN_PUBLISHED_XLINGS:?published client path required}" |
| 13 | +work="${CN_PROBE_RUN_DIR:-$base/probes/runs/$phase-$version-$(date +%Y%m%dT%H%M%S)}" |
| 14 | +[[ "$work" == "$base/probes/runs/"* ]] || exit 1 |
| 15 | +mkdir -p "$work" |
| 16 | +exec > >(tee -a "$work/probe.log") 2>&1 |
| 17 | +printf 'phase=%s version=%s XLINGS_HOME=%s sandbox_HOME=%s\n' "$phase" "$version" "$base" "$HOME" |
| 18 | +cat /proc/self/mountinfo > "$work/subos-mountinfo.txt" |
| 19 | +export MCPP_HOME="$work/mcpp-home" |
| 20 | +export MCPP_VENDORED_XLINGS="$xl" |
| 21 | +export MCPP_E2E_MIRROR=CN MCPP_E2E_LLVM_VERSION=23.1.3 MCPP_E2E_EXPECT_ARCH=aarch64 |
| 22 | +unset LD_LIBRARY_PATH LD_PRELOAD MCPP_TOOLCHAIN |
| 23 | +"$xl" config --mirror CN |
| 24 | +"$xl" install "mcpp@$version" -y -u |
| 25 | +MCPP="$base/data/xpkgs/xim-x-mcpp/$version/bin/mcpp" |
| 26 | +[[ -x "$MCPP" ]] || { echo "mcpp not executable: $MCPP"; exit 1; } |
| 27 | +export MCPP |
| 28 | +"$MCPP" --version | tee "$work/mcpp-version.txt" |
| 29 | +got=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$work/mcpp-version.txt" | head -1) |
| 30 | +[[ "$got" == "$version" ]] || { echo "unexpected mcpp version $got"; exit 1; } |
| 31 | +sha256sum "$MCPP" > "$work/mcpp-binary.sha256" |
| 32 | +[[ "$(sha256sum "$MCPP" | cut -d ' ' -f 1)" == "${CN_EXPECTED_BINARY_SHA:?CN archive identity required}" ]] || exit 1 |
| 33 | +"$MCPP" self config --mirror CN |
| 34 | +# No default setter or explicit install may conceal the engine's ARM64 default. |
| 35 | +[[ "$(file -b "$MCPP")" == *"ARM aarch64"* ]] || exit 1 |
| 36 | +case "$(uname -m)" in |
| 37 | + x86_64) native=x86_64-linux-gnu ;; |
| 38 | + aarch64) native=aarch64-linux-gnu ;; |
| 39 | + *) echo 'unsupported native host'; exit 1 ;; |
| 40 | +esac |
| 41 | +cd "$work" |
| 42 | +project="${CN_PROBE_PROJECT:-hello}" |
| 43 | +"$MCPP" new "$project" |
| 44 | +cd "$work/$project" |
| 45 | +"$MCPP" build 2>&1 | tee "$work/native-default-build.log" |
| 46 | +grep -q 'Resolved llvm@23.1.3' "$work/native-default-build.log" |
| 47 | +grep -Eq 'aarch64-(unknown-)?linux-gnu' "$work/native-default-build.log" |
| 48 | +mapfile -t native_bins < <(find target -type f -path "*/bin/$project") |
| 49 | +[[ "${#native_bins[@]}" == 1 ]] || exit 1 |
| 50 | +readelf -hW "${native_bins[0]}" | tee "$work/native-header.txt" |
| 51 | +grep -q 'Machine:.*AArch64' "$work/native-header.txt" |
| 52 | +readelf -lW "${native_bins[0]}" > "$work/native-program-headers.txt" |
| 53 | +python3 - "$MCPP_HOME" "$work/native-program-headers.txt" <<'PYLOADER' |
| 54 | +import pathlib,re,sys |
| 55 | +home=pathlib.Path(sys.argv[1]).resolve() |
| 56 | +text=pathlib.Path(sys.argv[2]).read_text() |
| 57 | +m=re.search(r'Requesting program interpreter: ([^\]]+)',text) |
| 58 | +assert m,text |
| 59 | +loader=pathlib.Path(m[1]).resolve() |
| 60 | +loader.relative_to(home/'registry/data/xpkgs/xim-x-glibc') |
| 61 | +assert loader.name=='ld-linux-aarch64.so.1',loader |
| 62 | +PYLOADER |
| 63 | +"$MCPP" run | tee "$work/native-run.log" |
| 64 | +grep -q "Hello from $project!" "$work/native-run.log" |
| 65 | +"$MCPP" pack --mode self-contained --format dir --message-format json > "$work/pack.json" |
| 66 | +bundle=$(python3 - "$work/pack.json" <<'PY' |
| 67 | +import json, sys |
| 68 | +artifact=json.load(open(sys.argv[1]))['data']['artifacts'][0] |
| 69 | +assert artifact['type']=='directory', artifact |
| 70 | +print(artifact['path']) |
| 71 | +PY |
| 72 | +) |
| 73 | +cp -a "$bundle" "$work/deployed" |
| 74 | +(cd / && env -u LD_LIBRARY_PATH "$work/deployed/$project") | tee "$work/deployed.log" |
| 75 | +grep -q "Hello from $project!" "$work/deployed.log" |
| 76 | +cd "$work" |
| 77 | +git clone --depth 1 --branch "v$version" https://github.com/mcpp-community/mcpp mcpp-source |
| 78 | +git -C mcpp-source rev-parse HEAD | tee "$work/mcpp-source-sha.txt" |
| 79 | +cd mcpp-source |
| 80 | +bash tests/e2e/286_the_openkal_stack_still_builds.sh | tee "$work/openkal-native.log" |
| 81 | +! grep -q 'SKIP' "$work/openkal-native.log" |
| 82 | +grep -qF 'OK: the openkal stack builds, links statically and runs' "$work/openkal-native.log" |
| 83 | +cd "$work" |
| 84 | +git clone --depth 1 https://github.com/mcpp-community/mcpp-index index-source |
| 85 | +git -C index-source rev-parse HEAD | tee "$work/index-source-sha.txt" |
| 86 | +export CN_PROBE_MCPP="$MCPP" CN_PROBE_TARGET="$native" CN_PROBE_WORK="$work" |
| 87 | +cat > "$work/llvm-consumer" <<'ADAPTER' |
| 88 | +#!/usr/bin/env bash |
| 89 | +set -euo pipefail |
| 90 | +case "${1:-}" in build|test|run) set -- "$@" --toolchain llvm@23.1.3 --target "$CN_PROBE_TARGET" ;; esac |
| 91 | +{ printf 'argv:'; printf ' %q' "$@"; printf '\n'; } >> "$CN_PROBE_WORK/consumer-argv.log" |
| 92 | +exec "$CN_PROBE_MCPP" "$@" |
| 93 | +ADAPTER |
| 94 | +chmod +x "$work/llvm-consumer" |
| 95 | +cd "$work/index-source" |
| 96 | +MCPP="$work/llvm-consumer" MCPP_VERBOSE=1 MCPP_TIMINGS="$work/members.tsv" \ |
| 97 | + bash tests/run_members.sh cjson sqlite3 fmtlib.fmt nlohmann.json | tee "$work/members.log" |
| 98 | +python3 - "$work/members.tsv" <<'PY' |
| 99 | +import pathlib,sys |
| 100 | +rows=[line.split('\t') for line in pathlib.Path(sys.argv[1]).read_text().splitlines()] |
| 101 | +assert len(rows)==4 and {r[1] for r in rows}=={'cjson','sqlite3','fmtlib.fmt','nlohmann.json'},rows |
| 102 | +assert all(r[2]=='ok' for r in rows),rows |
| 103 | +PY |
| 104 | +# The ecosystem's own same-source example generates its target runtimes from |
| 105 | +# the graph. Foreign artifacts are inspected here; target OS execution is a |
| 106 | +# separate acceptance gate, never implied by this Linux sandbox. |
| 107 | +cd "$work" |
| 108 | +git clone --depth 1 --branch "${OPENKAL_SOURCE_REF:-main}" https://github.com/mcpplibs/openkal-llvm-runtime openkal-source |
| 109 | +git -C openkal-source rev-parse HEAD | tee "$work/openkal-source-sha.txt" |
| 110 | +cp "$work/openkal-source-sha.txt" "$work/source-sha.txt" |
| 111 | +cd "$work/openkal-source/examples/same-source" |
| 112 | +readobj="$MCPP_HOME/registry/data/xpkgs/xim-x-llvm/23.1.3/bin/llvm-readobj" |
| 113 | +[[ -x "$readobj" ]] || { echo 'LLVM readobj unavailable'; exit 1; } |
| 114 | +mkdir -p "$work/cross" |
| 115 | +for target in x86_64-linux-gnu aarch64-macos x86_64-windows-gnu; do |
| 116 | + rm -rf target |
| 117 | + "$MCPP" build --target "$target" --toolchain llvm@23.1.3 | tee "$work/cross/$target.build.log" |
| 118 | + mapfile -t artifacts < <(find target -type f \( -name openkal-same-source -o -name openkal-same-source.exe \)) |
| 119 | + [[ "${#artifacts[@]}" == 1 ]] || { echo 'cross artifact missing or ambiguous'; exit 1; } |
| 120 | + "$readobj" --file-headers "${artifacts[0]}" > "$work/cross/$target.headers.txt" |
| 121 | + case "$target" in |
| 122 | + x86_64-linux-gnu) grep -q 'Format: elf64-x86-64' "$work/cross/$target.headers.txt"; grep -q 'Arch: x86_64' "$work/cross/$target.headers.txt" ;; |
| 123 | + aarch64-macos) grep -q 'Format: Mach-O' "$work/cross/$target.headers.txt"; grep -q 'Arch: aarch64' "$work/cross/$target.headers.txt" ;; |
| 124 | + x86_64-windows-gnu) grep -q 'Format: COFF' "$work/cross/$target.headers.txt"; grep -q 'Arch: x86_64' "$work/cross/$target.headers.txt" ;; |
| 125 | + *) echo "unreviewed selected target: $target"; exit 1 ;; |
| 126 | + esac |
| 127 | + case "$target" in |
| 128 | + x86_64-linux-gnu) output=linux ;; |
| 129 | + aarch64-macos) output=macos ;; |
| 130 | + x86_64-windows-gnu) output=windows.exe ;; |
| 131 | + esac |
| 132 | + cp "${artifacts[0]}" "$work/cross/$output" |
| 133 | + (cd "$work/cross" && sha256sum "$output") >> "$work/cross/SHA256SUMS" |
| 134 | +done |
| 135 | +echo 'RELEASE BUILD PASS: CN install/default/new/build/run/pack, native openkal, four consumers and three target artifacts.' |
| 136 | +cp "$work/openkal-source-sha.txt" "$work/cross/source-sha.txt" |
| 137 | +printf '%s\n' "$work" > "$base/probes/last-run.txt" |
| 138 | +echo 'Foreign target execution is pending the three target-system jobs.' |
0 commit comments