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