From 7c24b69e62790c82a2dda858fbaa50847fc42ada Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 3 Jun 2026 11:32:06 +1200 Subject: [PATCH] register.cc: Make cmd paths proximate The CMake refactor changes relative paths to absolute when calling `source_location::current()`. Use the path to `register.cc` to find the root yosys dir, and use that as the base for other paths. Includes provisions for when plugins have a valid location; if it's not in the yosys source tree we shouldn't try to make the path relative, and we shouldn't try to auto group by path (since such groups will never be allocated, leaving them as unknown is preferable). Limited to non wasm (I think that's the only one where we can't (easily) use ``). But where we do use `` we can also simplify the auto group to use `fs::path::parent_path()`. --- kernel/register.cc | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/kernel/register.cc b/kernel/register.cc index 705ec628a..bfb442dae 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -29,6 +29,11 @@ #include #include +#if !defined(__wasm) +#include +namespace fs = std::filesystem; +#endif + YOSYS_NAMESPACE_BEGIN #define MAX_REG_COUNT 1000 @@ -772,6 +777,11 @@ struct HelpPass : public Pass { bool raise_error = false; std::map> groups; +#if !defined(__wasm) + auto this_path = fs::path(source_location::current().file_name()); + auto source_root = this_path.parent_path().parent_path(); +#endif + json.name("cmds"); json.begin_object(); // iterate over commands for (auto &it : pass_register) { @@ -912,10 +922,31 @@ struct HelpPass : public Pass { } } + string source_file = pass->location.file_name(); + bool has_source = source_file.compare("unknown") != 0; +#if !defined(__wasm) + // fix path + fs::path source_path; + auto no_source_group = false; + if (has_source) { + source_path = fs::path(pass->location.file_name()); + if (source_path.is_absolute()) { + // using proximate instead of relative means that we + // still get the source path if they aren't relative + auto proximate_path = fs::proximate(source_path, source_root); + if (proximate_path == fs::weakly_canonical(proximate_path)) + // we're only interested if it's a subpath of our root dir + source_path = proximate_path; + else + // don't try to group external paths + no_source_group = true; + } + source_file = source_path.string(); + } +#endif + // attempt auto group if (!cmd_help.has_group()) { - string source_file = pass->location.file_name(); - bool has_source = source_file.compare("unknown") != 0; if (pass->internal_flag) cmd_help.group = "internal"; else if (source_file.find("backends/") == 0 || (!has_source && name.find("read_") == 0)) @@ -923,11 +954,16 @@ struct HelpPass : public Pass { else if (source_file.find("frontends/") == 0 || (!has_source && name.find("write_") == 0)) cmd_help.group = "frontends"; else if (has_source) { +#if !defined(__wasm) + if (source_path.has_parent_path() && !no_source_group) + cmd_help.group = source_path.parent_path(); +#else auto last_slash = source_file.find_last_of('/'); if (last_slash != string::npos) { auto parent_path = source_file.substr(0, last_slash); cmd_help.group = parent_path; } +#endif } // implicit !has_source else if (name.find("equiv") == 0) @@ -955,7 +991,7 @@ struct HelpPass : public Pass { json.value(content.to_json()); json.end_array(); json.entry("group", cmd_help.group); - json.entry("source_file", pass->location.file_name()); + json.entry("source_file", source_file); json.entry("source_line", pass->location.line()); json.entry("source_func", pass->location.function_name()); json.entry("experimental_flag", pass->experimental_flag);