[rust-project.json] List the Rust sysroot if there is one and only one
List the path to the sysroot using the new 'sysroot' field added by
rust-analyzer if there is one and only one sysroot defined for the
project.
This enables rust-analyzer to find the compiler and tools vendored with
the compiler, such a proc-macro server that matches the compiler's ABI.
Change-Id: I92146a4afbed001e44d7a1b824bad536eb297841
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/14360
Reviewed-by: Tyler Mandry <tmandry@google.com>
Commit-Queue: Tyler Mandry <tmandry@google.com>
Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/src/gn/rust_project_writer.cc b/src/gn/rust_project_writer.cc
index 8c73d57..0eb2a53 100644
--- a/src/gn/rust_project_writer.cc
+++ b/src/gn/rust_project_writer.cc
@@ -29,6 +29,7 @@
// Current structure of rust-project.json output file
//
// {
+// "sysroot": "path/to/rust/sysroot", // if there is only one sysroot found
// "crates": [
// {
// "deps": [
@@ -358,8 +359,22 @@
void WriteCrates(const BuildSettings* build_settings,
CrateList& crate_list,
+ SysrootIndexMap& sysroots,
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
+ // 'rust-analyzer-proc-macro-srv` proc-macro server that matches the abi used
+ // by 'rustc'
+ if (sysroots.size() == 1) {
+ auto sysroot = sysroots.begin()->first;
+ base::FilePath rebased_out_dir =
+ build_settings->GetFullPath(build_settings->build_dir());
+ auto sysroot_path = FilePathToUTF8(rebased_out_dir) + std::string(sysroot);
+ rust_project << " \"sysroot\": \"" << sysroot_path << "\"," NEWLINE;
+ }
+
rust_project << " \"crates\": [";
bool first_crate = true;
for (auto& crate : crate_list) {
@@ -499,5 +514,5 @@
AddTarget(build_settings, target, lookup, sysroot_lookup, crate_list);
}
- WriteCrates(build_settings, crate_list, rust_project);
+ WriteCrates(build_settings, crate_list, sysroot_lookup, rust_project);
}
diff --git a/src/gn/rust_project_writer_helpers.h b/src/gn/rust_project_writer_helpers.h
index 9aa7eba..aba1388 100644
--- a/src/gn/rust_project_writer_helpers.h
+++ b/src/gn/rust_project_writer_helpers.h
@@ -144,6 +144,7 @@
// on the the given crates list.
void WriteCrates(const BuildSettings* build_settings,
CrateList& crate_list,
+ SysrootIndexMap& sysroot_lookup,
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 ffdfcd8..df07c77 100644
--- a/src/gn/rust_project_writer_helpers_unittest.cc
+++ b/src/gn/rust_project_writer_helpers_unittest.cc
@@ -26,6 +26,8 @@
TEST_F(RustProjectWriterHelper, WriteCrates) {
TestWithScope setup;
+ SysrootIndexMap sysroot_lookup;
+
CrateList crates;
Crate dep = Crate(SourceFile("/root/tortoise/lib.rs"), std::nullopt, 0,
"//tortoise:bar", "2015");
@@ -39,7 +41,7 @@
crates.push_back(target);
std::ostringstream stream;
- WriteCrates(setup.build_settings(), crates, stream);
+ WriteCrates(setup.build_settings(), crates, sysroot_lookup, stream);
std::string out = stream.str();
#if defined(OS_WIN)
base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
@@ -102,7 +104,7 @@
AddSysroot(setup.build_settings(), "sysroot", sysroot_lookup, crates);
std::ostringstream stream;
- WriteCrates(setup.build_settings(), crates, stream);
+ WriteCrates(setup.build_settings(), crates, sysroot_lookup, stream);
std::string out = stream.str();
#if defined(OS_WIN)
base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
@@ -110,6 +112,7 @@
const char expected_json[] =
"{\n"
+ " \"sysroot\": \"/root/out/Debug/sysroot\",\n"
" \"crates\": [\n"
" {\n"
" \"crate_id\": 0,\n"