|
| 1 | +#!/usr/bin/env bash |
| 2 | +# TEMPORARY PROBE (do not merge): where [profile.*], [workspace.build] and a |
| 3 | +# rooted workspace's own [build] reach, per member and per selection. |
| 4 | +# Prints the markers each ninja edge carries; asserts nothing. |
| 5 | +set -u |
| 6 | +M="${MCPP_BUILT:?}" |
| 7 | +W="$RUNNER_TEMP/ws-profile"; rm -rf "$W"; mkdir -p "$W" |
| 8 | +section() { echo; echo "### $1"; } |
| 9 | +markers() { # every compile/link edge and the markers it (or the file-level default) carries |
| 10 | + local found=0 |
| 11 | + for n in $(find target -name build.ninja | sort); do found=1 |
| 12 | + echo " [graph $(basename "$(dirname "$n")")]" |
| 13 | + python3 - "$n" <<'PY' |
| 14 | +import re, sys |
| 15 | +glob, edges, cur = {}, {}, None |
| 16 | +for line in open(sys.argv[1], encoding="utf-8", errors="replace"): |
| 17 | + line = line.rstrip("\n") |
| 18 | + if line.startswith("build "): |
| 19 | + cur = line.split(" : ")[0][6:].strip() |
| 20 | + rule = line.split(" : ", 1)[1].split()[0] if " : " in line else "?" |
| 21 | + edges[cur] = {"_rule": rule}; continue |
| 22 | + if line.startswith(" ") and cur: |
| 23 | + k, _, v = line.strip().partition(" = "); edges[cur][k] = v; continue |
| 24 | + cur = None |
| 25 | + m = re.match(r"^(\w+)\s*=\s*(.*)$", line) |
| 26 | + if m: glob[m.group(1)] = m.group(2) |
| 27 | +pat = re.compile(r"MARK_[A-Z_]+|-O[0-3s]\b") |
| 28 | +for e, v in sorted(edges.items()): |
| 29 | + r = v["_rule"] |
| 30 | + if r in ("cxx_object", "cxx_module", "c_object"): |
| 31 | + text = " ".join([glob.get("cxxflags", ""), v.get("unit_cxxflags", ""), v.get("cxxflags", ""), v.get("package_cxxflags", "")] + [x for k, x in v.items() if "flags" in k]) |
| 32 | + elif r in ("cxx_link", "cxx_shared", "c_link"): |
| 33 | + text = v.get("ldflags", glob.get("ldflags", "")) + " " + v.get("unit_ldflags", "") |
| 34 | + else: |
| 35 | + continue |
| 36 | + found = sorted(set(pat.findall(text))) |
| 37 | + print(f" {r:11s} {e}: {' '.join(found) or '-'}") |
| 38 | +PY |
| 39 | + done |
| 40 | + [ $found = 1 ] || echo "(no build.ninja)" |
| 41 | +} |
| 42 | +build() { echo "\$ mcpp $*"; rm -rf target; "$M" "$@" 2>&1 | grep -E "warning|error|note|Finished" | head -8; markers; } |
| 43 | + |
| 44 | +prof() { # a [profile.release] table whose markers name its file |
| 45 | + cat <<EOF |
| 46 | +[profile.release] |
| 47 | +opt = 3 |
| 48 | +cxxflags = ["-DMARK_PROFILE_$1"] |
| 49 | +ldflags = ["-Wl,-rpath,/MARK_PROFILE_$1"] |
| 50 | +EOF |
| 51 | +} |
| 52 | +member() { # member <dir> <name> <kind> [extra toml] |
| 53 | + mkdir -p "$1/src" |
| 54 | + { printf '[package]\nname = "%s"\nversion = "0.1.0"\n\n' "$2" |
| 55 | + printf '[build]\ncxxflags = ["-DMARK_OWN_%s"]\nldflags = ["-Wl,-rpath,/MARK_OWN_%s"]\n\n' "${2^^}" "${2^^}" |
| 56 | + [ "$3" = shared ] && printf '[targets.%s]\nkind = "shared"\n' "$2" |
| 57 | + [ "$3" = bin ] && printf '[dependencies]\nlib = { path = "%s" }\n\n[targets.%s]\nkind = "bin"\nmain = "src/main.cpp"\n' "${DEP_PATH:-../lib}" "$2" |
| 58 | + printf '%s\n' "${4:-}"; } > "$1/mcpp.toml" |
| 59 | + if [ "$3" = shared ]; then printf 'export module ws_lib;\nexport int lv() { return 1; }\n' > "$1/src/lib.cppm" |
| 60 | + else printf 'import ws_lib;\nint main() { return lv() == 1 ? 0 : 1; }\n' > "$1/src/main.cpp"; fi |
| 61 | +} |
| 62 | + |
| 63 | +section "W1 virtual root: [profile.release] + [workspace.build] at the root; members declare no profile" |
| 64 | +mkdir -p "$W/w1" && cd "$W/w1" |
| 65 | +{ printf '[workspace]\nmembers = ["app", "lib"]\n\n[workspace.build]\ncxxflags = ["-DMARK_WS_BUILD"]\nldflags = ["-Wl,-rpath,/MARK_WS_BUILD"]\n\n'; prof WSROOT; } > mcpp.toml |
| 66 | +member lib lib shared; member app app bin |
| 67 | +build build --release |
| 68 | +build build --release -p app |
| 69 | + |
| 70 | +section "W2 virtual root with a profile, and member app declares its own [profile.release]" |
| 71 | +mkdir -p "$W/w2" && cd "$W/w2" |
| 72 | +{ printf '[workspace]\nmembers = ["app", "lib"]\n\n'; prof WSROOT; } > mcpp.toml |
| 73 | +member lib lib shared; member app app bin "$(prof APP)" |
| 74 | +build build --release |
| 75 | +build build --release -p app |
| 76 | +build build --release -p lib |
| 77 | + |
| 78 | +section "W3 rooted workspace: the root file is [package] app + [workspace] + [profile.release] + its own [build]" |
| 79 | +mkdir -p "$W/w3" && cd "$W/w3" |
| 80 | +DEP_PATH=lib member . app bin "$(printf '[workspace]\nmembers = ["lib"]\n\n[workspace.build]\ncxxflags = ["-DMARK_WS_BUILD"]\n\n'; prof ROOTFILE)" |
| 81 | +member lib lib shared |
| 82 | +build build --release |
| 83 | +build build --release --workspace |
| 84 | +build build --release -p lib |
| 85 | + |
| 86 | +section "W4 a plain project (no workspace), for comparison" |
| 87 | +mkdir -p "$W/w4" && cd "$W/w4" |
| 88 | +member lib lib shared |
| 89 | +mkdir -p app && member app app bin "$(prof APP)" |
| 90 | +cd app && build build --release |
0 commit comments