Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
93e59b5
0.19.0: one resolver for where a member's tool comes from, payloads i…
speak-agent Oct 1, 2026
1fc2c37
docs: the plan records what was built, and the two portability findin…
speak-agent Oct 1, 2026
e042567
ci: the release every job fetches is its own variable, so a change ca…
speak-agent Oct 1, 2026
5d92352
testing: a case sees only the payloads it states, and one CI criterio…
speak-agent Oct 1, 2026
e67e6db
testing: the environment array is reached the way each platform offer…
speak-agent Oct 1, 2026
a694d16
docs: the plan record carries the lab result and the ecosystem-level …
speak-agent Oct 1, 2026
11cf1cf
docs: two usage examples name the current version, and dist-apk says …
speak-agent Oct 1, 2026
e48c481
rules-sycl: the compiler and the root its libraries sit under are two…
speak-agent Oct 1, 2026
358841d
docs: the plan record carries the sycl finding and why the local roun…
speak-agent Oct 1, 2026
789a0bb
docs: the toolchain builders listed are the ones the module has
speak-agent Oct 1, 2026
8a7d604
tool: a stated program path resolves whichever executable suffix the …
speak-agent Oct 1, 2026
be3dfbd
manifest: the test kit's comment sits above the test kit again
speak-agent Oct 1, 2026
10a8662
docs: the plan record carries the linker and executable-suffix findings
speak-agent Oct 1, 2026
87c7f9d
docs: the plan record carries the framework lab's results and the mea…
speak-agent Oct 1, 2026
141f416
docs: the plan record carries the toolchain lab's before-and-after re…
speak-agent Oct 1, 2026
5eb083b
rules-qt: warn() walks the message by index, because gcc 16 refuses t…
speak-agent Oct 1, 2026
40a5d21
docs: the plan record carries the gcc 16 inlining finding
speak-agent Oct 1, 2026
e00da73
ci: the bootstrap pin is the released 2026.10.1.3, which is this coll…
speak-agent Oct 1, 2026
eb29dc5
Merge main: the qrc resource-input fix (#42) lands before this release
speak-agent Oct 1, 2026
bbf0f50
docs: a project that names its own Qt SDK states where the payload co…
speak-agent Oct 1, 2026
14ff15c
docs: where a tool comes from, as scenarios for authors, designers an…
speak-agent Oct 1, 2026
96b856b
docs: the plan record carries the reference page and why it exists
speak-agent Oct 1, 2026
1911600
docs: the final self-review, with the readings this delivery actually…
speak-agent Oct 1, 2026
7d22dc0
docs: the four ways a build program names its own tool, compiled befo…
speak-agent Oct 1, 2026
d1a3cf5
docs: replacing the default tool from build.mcpp is its own chapter
speak-agent Oct 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
tool: a stated program path resolves whichever executable suffix the …
…file carries

A build program writes the path a shell gave it, and on Windows `command -v cmake`
answers `C:/Program Files/CMake/bin/cmake` for a `cmake.exe`. The resolver
insisted on the exact spelling and refused a program the host itself would have
run -- measured in CI, where the cmake consumer reported
`options::cmake = "C:/Program Files/CMake/bin/cmake" (not found)` on a runner
carrying cmake, and then failed to compile because the subproject it configures
never built. A stated path now follows the same suffix rule as a discovered one,
which `program_in` has always applied, and a case states it on a Linux row
because the rule is the same on every host.
  • Loading branch information
speak-agent committed Oct 1, 2026
commit 8a7d6049b240478d438146e406770a291da3940e
26 changes: 23 additions & 3 deletions src/tool.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,26 @@ inline std::string program_in(const std::filesystem::path& dir, std::string_view
return {};
}

// A STATED PATH, WITH THE SAME SUFFIX RULE AS A DISCOVERED ONE. A build program
// writes the path a shell gave it, and on Windows `command -v cmake` answers
// `C:/Program Files/CMake/bin/cmake` for a `cmake.exe`; process creation there
// appends the suffix itself, so a resolver that insisted on the exact spelling
// refused a program the host would have run (measured in CI: the cmake consumer
// reported `options::cmake = "C:/Program Files/CMake/bin/cmake" (not found)` on a
// runner carrying cmake). Empty when neither spelling is a file.
inline std::string program_at(const std::filesystem::path& p) {
if (is_file(p)) return generic(p);
auto with = p;
with += ".exe";
if (is_file(with)) return generic(with);
if (p.extension() == ".exe") {
auto without = p;
without.replace_extension();
if (is_file(without)) return generic(without);
}
return {};
}

inline std::string find_on_path(std::string_view name) {
const char* path = std::getenv("PATH");
if (!path) return {};
Expand Down Expand Up @@ -226,9 +246,9 @@ inline found resolve(const spec& s, const choice& c = {}) {
record(from::choice, file, line);
return out;
}
} else if (detail::is_file(p)) {
out.program = detail::generic(p);
out.root = detail::root_of(p);
} else if (auto hit = detail::program_at(p); !hit.empty()) {
out.program = std::move(hit);
out.root = detail::root_of(out.program);
record(from::choice, file, line);
return out;
}
Expand Down
21 changes: 21 additions & 0 deletions tests/plugin-logic/build.mcpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,27 @@ int main(int argc, char** argv) {
"the decision names the choice and the program");
} },

{ "tool: a stated path resolves whichever executable suffix the file carries",
// What a shell hands a build program on Windows: `command -v cmake`
// answers a path with no `.exe`, for a `cmake.exe`. Process creation
// there appends the suffix, so the resolver does too -- stated on a
// Linux row, because the rule is the same on every host.
t::row::linux_libcxx().file("pkg/opt/bin/cmake.exe")
.xpkg_source("xim", "cmake", "pending"),
[] {
const auto f = tool_resolve(mcpp::plugins::tool::program(
std::string(mcpp::manifest_dir()) + "/opt/bin/cmake"));
std::printf("source=%s program=%s\n",
std::string(mcpp::plugins::tool::name(f.source)).c_str(),
f.program.c_str());
return f ? 0 : 1;
},
[](const t::result& r, t::checker& c) {
c.expect(r.has_line("source=choice", "opt/bin/cmake.exe"),
"the file beside the stated path answers");
c.expect(!r.has_line("mcpp:xpkg-request="), "a choice requests no payload");
} },

{ "tool: an override answers, and the payload is not consulted",
t::row::linux_libcxx().file("opt/bin/cmake")
.xpkg("xim", "cmake", "{root}/opt")
Expand Down
Loading