[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";