[rust-project] Remove the emitting of sysroot crates Now that rust-analyzer is able to automatically add the sysroot crates, if a 'sysroot' value is specified in the file, remove the addition of the sysroot crates, and let rust-analyzer find the crates from within the sysroot path specified. This is more maintainable over time (doesn't duplicate the logic of finding the sysroot crates), and removes the current double- addition of the sysroot crates which is breaking rust-analyzer's ability to locate the implementations of items like Deref<>. Change-Id: I84db1591525e8b7a5c46952a9d076990eb9c3540 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/14800 Reviewed-by: Dan Johnson <computerdruid@google.com> Reviewed-by: Brett Wilson <brettw@chromium.org> Commit-Queue: Aaron Wood <aaronwood@google.com>
diff --git a/src/gn/rust_project_writer.cc b/src/gn/rust_project_writer.cc index 0eb2a53..8bcd495 100644 --- a/src/gn/rust_project_writer.cc +++ b/src/gn/rust_project_writer.cc
@@ -29,7 +29,7 @@ // Current structure of rust-project.json output file // // { -// "sysroot": "path/to/rust/sysroot", // if there is only one sysroot found +// "sysroot": "path/to/rust/sysroot", // "crates": [ // { // "deps": [ @@ -45,7 +45,7 @@ // ], // "exclude_dirs": [] // }, -// "edition": "2018", // edition of crate +// "edition": "2021", // edition of crate // "cfg": [ // "unix", // "atomic" value config options // "rust_panic=\"abort\""", // key="value" config options @@ -162,99 +162,9 @@ return values; } -// TODO(bwb) Parse sysroot structure from toml files. This is fragile and -// might break if upstream changes the dependency structure. -const std::string_view sysroot_crates[] = {"std", - "core", - "alloc", - "panic_unwind", - "proc_macro", - "test", - "panic_abort", - "unwind"}; - -// Multiple sysroot crates have dependenices on each other. This provides a -// mechanism for specifying that in an extendible manner. -const std::unordered_map<std::string_view, std::vector<std::string_view>> - sysroot_deps_map = {{"alloc", {"core"}}, - {"std", {"alloc", "core", "panic_abort", "unwind"}}}; - -// Add each of the crates a sysroot has, including their dependencies. -void AddSysrootCrate(const BuildSettings* build_settings, - std::string_view crate, - std::string_view current_sysroot, - SysrootCrateIndexMap& sysroot_crate_lookup, - CrateList& crate_list) { - if (sysroot_crate_lookup.find(crate) != sysroot_crate_lookup.end()) { - // If this sysroot crate is already in the lookup, we don't add it again. - return; - } - - // Add any crates that this sysroot crate depends on. - auto deps_lookup = sysroot_deps_map.find(crate); - if (deps_lookup != sysroot_deps_map.end()) { - auto deps = (*deps_lookup).second; - for (auto dep : deps) { - AddSysrootCrate(build_settings, dep, current_sysroot, - sysroot_crate_lookup, crate_list); - } - } - - size_t crate_index = crate_list.size(); - sysroot_crate_lookup.insert(std::make_pair(crate, crate_index)); - - base::FilePath rebased_out_dir = - build_settings->GetFullPath(build_settings->build_dir()); - auto crate_path = - FilePathToUTF8(rebased_out_dir) + std::string(current_sysroot) + - "/lib/rustlib/src/rust/library/" + std::string(crate) + "/src/lib.rs"; - - Crate sysroot_crate = Crate(SourceFile(crate_path), std::nullopt, crate_index, - std::string(crate), "2018"); - - sysroot_crate.AddConfigItem("debug_assertions"); - - if (deps_lookup != sysroot_deps_map.end()) { - auto deps = (*deps_lookup).second; - for (auto dep : deps) { - auto idx = sysroot_crate_lookup[dep]; - sysroot_crate.AddDependency(idx, std::string(dep)); - } - } - - crate_list.push_back(sysroot_crate); -} - -// Add the given sysroot to the project, if it hasn't already been added. -void AddSysroot(const BuildSettings* build_settings, - std::string_view sysroot, - SysrootIndexMap& sysroot_lookup, - CrateList& crate_list) { - // If this sysroot is already in the lookup, we don't add it again. - if (sysroot_lookup.find(sysroot) != sysroot_lookup.end()) { - return; - } - - // Otherwise, add all of its crates - for (auto crate : sysroot_crates) { - AddSysrootCrate(build_settings, crate, sysroot, sysroot_lookup[sysroot], - crate_list); - } -} - -void AddSysrootDependencyToCrate(Crate* crate, - const SysrootCrateIndexMap& sysroot, - std::string_view crate_name) { - if (const auto crate_idx = sysroot.find(crate_name); - crate_idx != sysroot.end()) { - crate->AddDependency(crate_idx->second, std::string(crate_name)); - } -} - void AddTarget(const BuildSettings* build_settings, const Target* target, TargetIndexMap& lookup, - SysrootIndexMap& sysroot_lookup, CrateList& crate_list) { if (lookup.find(target) != lookup.end()) { // If target is already in the lookup, we don't add it again. @@ -263,21 +173,11 @@ auto compiler_args = ExtractCompilerArgs(target); auto compiler_target = FindArgValue("--target", compiler_args); - - // Check what sysroot this target needs. Add it to the crate list if it - // hasn't already been added. - auto rust_tool = - target->toolchain()->GetToolForTargetFinalOutputAsRust(target); - auto current_sysroot = rust_tool->GetSysroot(); - if (current_sysroot != "" && sysroot_lookup.count(current_sysroot) == 0) { - AddSysroot(build_settings, current_sysroot, sysroot_lookup, crate_list); - } - auto crate_deps = GetRustDeps(target); // Add all dependencies of this crate, before this crate. for (const auto& dep : crate_deps) { - AddTarget(build_settings, dep, lookup, sysroot_lookup, crate_list); + AddTarget(build_settings, dep, lookup, crate_list); } // The index of a crate is its position (0-based) in the list of crates. @@ -314,21 +214,9 @@ crate.AddConfigItem(cfg); } - // Add the sysroot dependencies, if there is one. - if (current_sysroot != "") { - const auto& sysroot = sysroot_lookup[current_sysroot]; - AddSysrootDependencyToCrate(&crate, sysroot, "core"); - AddSysrootDependencyToCrate(&crate, sysroot, "alloc"); - AddSysrootDependencyToCrate(&crate, sysroot, "std"); - - // Proc macros have the proc_macro crate as a direct dependency - if (std::string_view(rust_tool->name()) == - std::string_view(RustTool::kRsToolMacro)) { - AddSysrootDependencyToCrate(&crate, sysroot, "proc_macro"); - } - } - // If it's a proc macro, record its output location so IDEs can invoke it. + auto rust_tool = + target->toolchain()->GetToolForTargetFinalOutputAsRust(target); if (std::string_view(rust_tool->name()) == std::string_view(RustTool::kRsToolMacro)) { auto outputs = target->computed_outputs(); @@ -359,19 +247,18 @@ void WriteCrates(const BuildSettings* build_settings, CrateList& crate_list, - SysrootIndexMap& sysroots, + std::optional<std::string>& sysroot, std::ostream& rust_project) { rust_project << "{" NEWLINE; - // If there is one, and only one, sysroot found, then that can be used to tell - // rust-analyzer where to find the sysroot (and associated tools like the + // If a sysroot was found, then that can be used to tell rust-analyzer where + // to find the sysroot (and associated tools like the // 'rust-analyzer-proc-macro-srv` proc-macro server that matches the abi used // by 'rustc' - if (sysroots.size() == 1) { - auto sysroot = sysroots.begin()->first; + if (sysroot.has_value()) { base::FilePath rebased_out_dir = build_settings->GetFullPath(build_settings->build_dir()); - auto sysroot_path = FilePathToUTF8(rebased_out_dir) + std::string(sysroot); + auto sysroot_path = FilePathToUTF8(rebased_out_dir) + sysroot.value(); rust_project << " \"sysroot\": \"" << sysroot_path << "\"," NEWLINE; } @@ -503,16 +390,25 @@ std::vector<const Target*>& all_targets, std::ostream& rust_project) { TargetIndexMap lookup; - SysrootIndexMap sysroot_lookup; CrateList crate_list; + std::optional<std::string> rust_sysroot; // All the crates defined in the project. for (const auto* target : all_targets) { if (!target->IsBinary() || !target->source_types_used().RustSourceUsed()) continue; - AddTarget(build_settings, target, lookup, sysroot_lookup, crate_list); + AddTarget(build_settings, target, lookup, crate_list); + + // If a sysroot hasn't been found, see if we can find one using this target. + if (!rust_sysroot.has_value()) { + auto rust_tool = + target->toolchain()->GetToolForTargetFinalOutputAsRust(target); + auto sysroot = rust_tool->GetSysroot(); + if (sysroot != "") + rust_sysroot = sysroot; + } } - WriteCrates(build_settings, crate_list, sysroot_lookup, rust_project); + WriteCrates(build_settings, crate_list, rust_sysroot, rust_project); }
diff --git a/src/gn/rust_project_writer_helpers.h b/src/gn/rust_project_writer_helpers.h index aba1388..31efd40 100644 --- a/src/gn/rust_project_writer_helpers.h +++ b/src/gn/rust_project_writer_helpers.h
@@ -125,26 +125,11 @@ using CrateList = std::vector<Crate>; -// Mapping of a sysroot crate (path) to it's index in the crates list. -using SysrootCrateIndexMap = std::unordered_map<std::string_view, CrateIndex>; - -// Mapping of a sysroot (path) to the mapping of each of the sysroot crates to -// their index in the crates list. -using SysrootIndexMap = - std::unordered_map<std::string_view, SysrootCrateIndexMap>; - -// Add all of the crates for a sysroot (path) to the rust_project ostream. -// Add the given sysroot to the project, if it hasn't already been added. -void AddSysroot(const BuildSettings* build_settings, - std::string_view sysroot, - SysrootIndexMap& sysroot_lookup, - CrateList& crate_list); - // Write the entire rust-project.json file contents into the given stream, based // on the the given crates list. void WriteCrates(const BuildSettings* build_settings, CrateList& crate_list, - SysrootIndexMap& sysroot_lookup, + std::optional<std::string>& sysroot, std::ostream& rust_project); // Assemble the compiler arguments for the given GN Target.
diff --git a/src/gn/rust_project_writer_helpers_unittest.cc b/src/gn/rust_project_writer_helpers_unittest.cc index df07c77..14d5c35 100644 --- a/src/gn/rust_project_writer_helpers_unittest.cc +++ b/src/gn/rust_project_writer_helpers_unittest.cc
@@ -26,7 +26,7 @@ TEST_F(RustProjectWriterHelper, WriteCrates) { TestWithScope setup; - SysrootIndexMap sysroot_lookup; + std::optional<std::string> sysroot; CrateList crates; Crate dep = Crate(SourceFile("/root/tortoise/lib.rs"), std::nullopt, 0, @@ -41,7 +41,7 @@ crates.push_back(target); std::ostringstream stream; - WriteCrates(setup.build_settings(), crates, sysroot_lookup, stream); + WriteCrates(setup.build_settings(), crates, sysroot, stream); std::string out = stream.str(); #if defined(OS_WIN) base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n"); @@ -98,13 +98,11 @@ TestWithScope setup; setup.build_settings()->SetRootPath(UTF8ToFilePath("/root")); - SysrootIndexMap sysroot_lookup; + std::optional<std::string> sysroot = "sysroot"; CrateList crates; - AddSysroot(setup.build_settings(), "sysroot", sysroot_lookup, crates); - std::ostringstream stream; - WriteCrates(setup.build_settings(), crates, sysroot_lookup, stream); + WriteCrates(setup.build_settings(), crates, sysroot, stream); std::string out = stream.str(); #if defined(OS_WIN) base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n"); @@ -114,189 +112,6 @@ "{\n" " \"sysroot\": \"/root/out/Debug/sysroot\",\n" " \"crates\": [\n" - " {\n" - " \"crate_id\": 0,\n" - " \"root_module\": " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/core/src/" - "lib.rs\",\n" - " \"label\": \"core\",\n" - " \"source\": {\n" - " \"include_dirs\": [\n" - " " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/core/src/\"\n" - " ],\n" - " \"exclude_dirs\": []\n" - " },\n" - " \"deps\": [\n" - " ],\n" - " \"edition\": \"2018\",\n" - " \"cfg\": [\n" - " \"debug_assertions\"\n" - " ]\n" - " },\n" - " {\n" - " \"crate_id\": 1,\n" - " \"root_module\": " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/alloc/src/" - "lib.rs\",\n" - " \"label\": \"alloc\",\n" - " \"source\": {\n" - " \"include_dirs\": [\n" - " " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/alloc/src/\"\n" - " ],\n" - " \"exclude_dirs\": []\n" - " },\n" - " \"deps\": [\n" - " {\n" - " \"crate\": 0,\n" - " \"name\": \"core\"\n" - " }\n" - " ],\n" - " \"edition\": \"2018\",\n" - " \"cfg\": [\n" - " \"debug_assertions\"\n" - " ]\n" - " },\n" - " {\n" - " \"crate_id\": 2,\n" - " \"root_module\": " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_abort/src/" - "lib.rs\",\n" - " \"label\": \"panic_abort\",\n" - " \"source\": {\n" - " \"include_dirs\": [\n" - " " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_abort/src/" - "\"\n" - " ],\n" - " \"exclude_dirs\": []\n" - " },\n" - " \"deps\": [\n" - " ],\n" - " \"edition\": \"2018\",\n" - " \"cfg\": [\n" - " \"debug_assertions\"\n" - " ]\n" - " },\n" - " {\n" - " \"crate_id\": 3,\n" - " \"root_module\": " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/unwind/src/" - "lib.rs\",\n" - " \"label\": \"unwind\",\n" - " \"source\": {\n" - " \"include_dirs\": [\n" - " " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/unwind/src/\"\n" - " ],\n" - " \"exclude_dirs\": []\n" - " },\n" - " \"deps\": [\n" - " ],\n" - " \"edition\": \"2018\",\n" - " \"cfg\": [\n" - " \"debug_assertions\"\n" - " ]\n" - " },\n" - " {\n" - " \"crate_id\": 4,\n" - " \"root_module\": " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/std/src/" - "lib.rs\",\n" - " \"label\": \"std\",\n" - " \"source\": {\n" - " \"include_dirs\": [\n" - " " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/std/src/\"\n" - " ],\n" - " \"exclude_dirs\": []\n" - " },\n" - " \"deps\": [\n" - " {\n" - " \"crate\": 1,\n" - " \"name\": \"alloc\"\n" - " },\n" - " {\n" - " \"crate\": 0,\n" - " \"name\": \"core\"\n" - " },\n" - " {\n" - " \"crate\": 2,\n" - " \"name\": \"panic_abort\"\n" - " },\n" - " {\n" - " \"crate\": 3,\n" - " \"name\": \"unwind\"\n" - " }\n" - " ],\n" - " \"edition\": \"2018\",\n" - " \"cfg\": [\n" - " \"debug_assertions\"\n" - " ]\n" - " },\n" - " {\n" - " \"crate_id\": 5,\n" - " \"root_module\": " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_unwind/src/" - "lib.rs\",\n" - " \"label\": \"panic_unwind\",\n" - " \"source\": {\n" - " \"include_dirs\": [\n" - " " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_unwind/src/" - "\"\n" - " ],\n" - " \"exclude_dirs\": []\n" - " },\n" - " \"deps\": [\n" - " ],\n" - " \"edition\": \"2018\",\n" - " \"cfg\": [\n" - " \"debug_assertions\"\n" - " ]\n" - " },\n" - " {\n" - " \"crate_id\": 6,\n" - " \"root_module\": " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/proc_macro/src/" - "lib.rs\",\n" - " \"label\": \"proc_macro\",\n" - " \"source\": {\n" - " \"include_dirs\": [\n" - " " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/proc_macro/src/" - "\"\n" - " ],\n" - " \"exclude_dirs\": []\n" - " },\n" - " \"deps\": [\n" - " ],\n" - " \"edition\": \"2018\",\n" - " \"cfg\": [\n" - " \"debug_assertions\"\n" - " ]\n" - " },\n" - " {\n" - " \"crate_id\": 7,\n" - " \"root_module\": " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/test/src/" - "lib.rs\",\n" - " \"label\": \"test\",\n" - " \"source\": {\n" - " \"include_dirs\": [\n" - " " - "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/test/src/\"\n" - " ],\n" - " \"exclude_dirs\": []\n" - " },\n" - " \"deps\": [\n" - " ],\n" - " \"edition\": \"2018\",\n" - " \"cfg\": [\n" - " \"debug_assertions\"\n" - " ]\n" - " }\n" " ]\n" "}\n";