|
64 | 64 | MCPP_ROOT = path.normalize(MCPP_ROOT) |
65 | 65 | local MCPP_MANIFEST = path.join(MCPP_ROOT, "mcpp.toml") |
66 | 66 |
|
67 | | --- mcpp.toml pins mcpplibs.cmdline = "0.0.1" exactly; newer versions may also be |
68 | | --- unpacked in the registry, so pin rather than take the newest or the two builds |
69 | | --- would not be compiling the same code. |
70 | | -local CMDLINE_VER = "0.0.1" |
71 | | -local CMDLINE_SRC = bench_package_root("mcpplibs-x-cmdline", CMDLINE_VER) |
| 67 | +-- Which version of mcpplibs.cmdline to compile is read from the measured tree's |
| 68 | +-- own mcpp.lock, NOT hardcoded and NOT "the newest unpacked". |
| 69 | +-- |
| 70 | +-- * hardcoding it is what broke CI: this said "0.0.1" because mcpp.toml says |
| 71 | +-- `mcpplibs.cmdline = "0.0.1"`, but that is a REQUIREMENT, not a resolution. |
| 72 | +-- A developer box that had 0.0.1 unpacked from some earlier run worked; a |
| 73 | +-- fresh runner had only what mcpp resolved, `bench_package_root` returned |
| 74 | +-- nil, the `if` below quietly added no files, and the build died 137 units |
| 75 | +-- later with `missing mcpplibs.cmdline dependency for module mcpp.cli` — |
| 76 | +-- an error that names neither the version nor the registry. |
| 77 | +-- * "the newest unpacked" would silently compile different sources than mcpp |
| 78 | +-- did, which is the one thing a comparison arm may not do. |
| 79 | +-- |
| 80 | +-- The lockfile is the resolution mcpp itself performed on this exact tree, so |
| 81 | +-- both arms compile the same code by construction. |
| 82 | +-- Read inside on_load, not here: `io` is nil in xmake's DESCRIPTION scope, so a |
| 83 | +-- reader written at this level dies with `attempt to index a nil value (global |
| 84 | +-- 'io')` — the same trap ../common/xmake/payload.lua documents for its manifest |
| 85 | +-- reader, walked into a second time. Both the lock path and the registry root |
| 86 | +-- are captured as upvalues for the same reason: on_load's sandbox cannot see |
| 87 | +-- this file's globals, so `bench_package_root` is not callable from in there. |
| 88 | +local MCPP_LOCK = path.join(MCPP_ROOT, "mcpp.lock") |
| 89 | +local XPKGS = bench_xpkgs() |
72 | 90 |
|
73 | 91 | option("pin_payload") |
74 | 92 | set_default(true) |
@@ -102,9 +120,39 @@ target("mcpp") |
102 | 120 | -- has no such cache, so it compiles the 3 units from source. That is a ~1s |
103 | 121 | -- handicap on xmake's cold build and is called out in the benchmark report |
104 | 122 | -- rather than hidden. |
105 | | - if CMDLINE_SRC and os.isdir(path.join(CMDLINE_SRC, "src")) then |
106 | | - add_files(path.join(CMDLINE_SRC, "src", "*.cppm")) |
107 | | - end |
| 123 | + -- |
| 124 | + -- Absence is FATAL rather than skipped. Skipping produced a build missing |
| 125 | + -- three units out of 140 that announced itself only as |
| 126 | + -- `missing mcpplibs.cmdline dependency for module mcpp.cli.cmd_cache` — |
| 127 | + -- naming a consumer instead of the cause. A description that cannot name the |
| 128 | + -- same sources mcpp compiled is not a comparison arm. |
| 129 | + on_load(function (target) |
| 130 | + local ver |
| 131 | + if os.isfile(MCPP_LOCK) then |
| 132 | + local in_section = false |
| 133 | + for _, line in ipairs((io.readfile(MCPP_LOCK) or ""):split("\n", {plain = true})) do |
| 134 | + local section = line:match("^%s*%[(.-)%]") |
| 135 | + if section then in_section = (section == 'package."mcpplibs.cmdline"') |
| 136 | + elseif in_section then |
| 137 | + ver = ver or line:match('^%s*version%s*=%s*"([^"]+)"') |
| 138 | + end |
| 139 | + end |
| 140 | + end |
| 141 | + if not ver then |
| 142 | + raise("bench: cannot read mcpplibs.cmdline's resolved version from " .. MCPP_LOCK |
| 143 | + .. " — the measured tree must carry the lockfile mcpp resolved it with") |
| 144 | + end |
| 145 | + local base = path.join(XPKGS, "mcpplibs-x-cmdline", ver) |
| 146 | + local dirs = os.isdir(base) and os.dirs(path.join(base, "*")) or {} |
| 147 | + table.sort(dirs) |
| 148 | + local src = dirs[1] and path.join(dirs[1], "src") |
| 149 | + if not src or not os.isdir(src) then |
| 150 | + raise("bench: mcpplibs.cmdline " .. ver .. " is not unpacked under " .. XPKGS |
| 151 | + .. " — build the tree with mcpp once first, so both arms compile the " |
| 152 | + .. "same dependency sources") |
| 153 | + end |
| 154 | + target:add("files", path.join(src, "*.cppm")) |
| 155 | + end) |
108 | 156 |
|
109 | 157 | set_policy("build.c++.modules", true) |
110 | 158 | set_policy("build.c++.modules.std", true) |
|
0 commit comments