rust-project: Represent source roots properly The current structure of a rust-project.json is documented here: https://rust-analyzer.github.io/manual.html#non-cargo-based-projects There are a couple of differences from what gn previously generated: * There is no longer a 'roots' section * Each crate has its own set of source includes and exclude directories. This difference has prevented rust-analyzer from correctly spotting and including Rust files pulled into a crate using the include! macro. With the current change, 'gen' dirs are included such that such generated files can be identified and correctly included by rust-analyzer. Bug: chromium/1293933 Change-Id: I108dd20114274dc0b2112aefa5990af6381b5466 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/13420 Reviewed-by: Brett Wilson <brettw@chromium.org> Commit-Queue: Tyler Mandry <tmandry@google.com>
diff --git a/src/gn/rust_project_writer.cc b/src/gn/rust_project_writer.cc index eea527c..8c73d57 100644 --- a/src/gn/rust_project_writer.cc +++ b/src/gn/rust_project_writer.cc
@@ -29,9 +29,6 @@ // Current structure of rust-project.json output file // // { -// "roots": [ -// "some/source/root" // each crate's source root -// ], // "crates": [ // { // "deps": [ @@ -40,6 +37,13 @@ // "name": "alloc" // extern name of dependency // }, // ], +// "source": [ +// "include_dirs": [ +// "some/source/root", +// "some/gen/dir", +// ], +// "exclude_dirs": [] +// }, // "edition": "2018", // edition of crate // "cfg": [ // "unix", // "atomic" value config options @@ -204,8 +208,8 @@ 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), crate_index, std::string(crate), "2018"); + Crate sysroot_crate = Crate(SourceFile(crate_path), std::nullopt, crate_index, + std::string(crate), "2018"); sysroot_crate.AddConfigItem("debug_assertions"); @@ -290,8 +294,10 @@ edition = FindArgValue("--edition", compiler_args); } - Crate crate = - Crate(crate_root, crate_id, crate_label, edition.value_or("2015")); + auto gen_dir = GetBuildDirForTargetAsOutputFile(target, BuildDirType::GEN); + + Crate crate = Crate(crate_root, gen_dir, crate_id, crate_label, + edition.value_or("2015")); crate.SetCompilerArgs(compiler_args); if (compiler_target.has_value()) @@ -353,24 +359,7 @@ void WriteCrates(const BuildSettings* build_settings, CrateList& crate_list, std::ostream& rust_project) { - // produce a de-duplicated set of source roots: - std::set<std::string> roots; - for (auto& crate : crate_list) { - roots.insert( - FilePathToUTF8(build_settings->GetFullPath(crate.root().GetDir()))); - } - rust_project << "{" NEWLINE; - rust_project << " \"roots\": ["; - bool first_root = true; - for (auto& root : roots) { - if (!first_root) - rust_project << ","; - first_root = false; - - rust_project << NEWLINE " \"" << root << "\""; - } - rust_project << NEWLINE " ]," NEWLINE; rust_project << " \"crates\": ["; bool first_crate = true; for (auto& crate : crate_list) { @@ -384,7 +373,25 @@ rust_project << NEWLINE << " {" NEWLINE << " \"crate_id\": " << crate.index() << "," NEWLINE << " \"root_module\": \"" << crate_module << "\"," NEWLINE - << " \"label\": \"" << crate.label() << "\"," NEWLINE; + << " \"label\": \"" << crate.label() << "\"," NEWLINE + << " \"source\": {" NEWLINE + << " \"include_dirs\": [" NEWLINE + << " \"" + << FilePathToUTF8( + build_settings->GetFullPath(crate.root().GetDir())) + << "\""; + auto gen_dir = crate.gen_dir(); + if (gen_dir.has_value()) { + auto gen_dir_path = FilePathToUTF8( + build_settings->GetFullPath(gen_dir->AsSourceDir(build_settings))); + rust_project << "," NEWLINE << " \"" << gen_dir_path + << "\"" NEWLINE; + } else { + rust_project << NEWLINE; + } + rust_project << " ]," NEWLINE + << " \"exclude_dirs\": []" NEWLINE + << " }," NEWLINE; auto compiler_target = crate.CompilerTarget(); if (compiler_target.has_value()) {
diff --git a/src/gn/rust_project_writer_helpers.h b/src/gn/rust_project_writer_helpers.h index 24b13d0..4ccf568 100644 --- a/src/gn/rust_project_writer_helpers.h +++ b/src/gn/rust_project_writer_helpers.h
@@ -35,10 +35,15 @@ class Crate { public: Crate(SourceFile root, + std::optional<OutputFile> gen_dir, CrateIndex index, std::string label, std::string edition) - : root_(root), index_(index), label_(label), edition_(edition) {} + : root_(root), + gen_dir_(gen_dir), + index_(index), + label_(label), + edition_(edition) {} ~Crate() = default; @@ -69,6 +74,9 @@ // Returns the root file for the crate. SourceFile& root() { return root_; } + // Returns the root file for the crate. + std::optional<OutputFile>& gen_dir() { return gen_dir_; } + // Returns the crate index. CrateIndex index() { return index_; }; @@ -103,6 +111,7 @@ private: SourceFile root_; + std::optional<OutputFile> gen_dir_; CrateIndex index_; std::string label_; std::string edition_;
diff --git a/src/gn/rust_project_writer_helpers_unittest.cc b/src/gn/rust_project_writer_helpers_unittest.cc index 7ff3b48..ffdfcd8 100644 --- a/src/gn/rust_project_writer_helpers_unittest.cc +++ b/src/gn/rust_project_writer_helpers_unittest.cc
@@ -27,10 +27,10 @@ TestWithScope setup; CrateList crates; - Crate dep = - Crate(SourceFile("/root/tortoise/lib.rs"), 0, "//tortoise:bar", "2015"); - Crate target = - Crate(SourceFile("/root/hare/lib.rs"), 1, "//hare:bar", "2015"); + Crate dep = Crate(SourceFile("/root/tortoise/lib.rs"), std::nullopt, 0, + "//tortoise:bar", "2015"); + Crate target = Crate(SourceFile("/root/hare/lib.rs"), + OutputFile("gendir/hare/"), 1, "//hare:bar", "2015"); target.AddDependency(0, "tortoise"); target.AddConfigItem("unix"); target.AddConfigItem("feature=\"test\""); @@ -46,15 +46,17 @@ #endif const char expected_json[] = "{\n" - " \"roots\": [\n" - " \"/root/hare/\",\n" - " \"/root/tortoise/\"\n" - " ],\n" " \"crates\": [\n" " {\n" " \"crate_id\": 0,\n" " \"root_module\": \"/root/tortoise/lib.rs\",\n" " \"label\": \"//tortoise:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"/root/tortoise/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"deps\": [\n" " ],\n" " \"edition\": \"2015\",\n" @@ -65,6 +67,13 @@ " \"crate_id\": 1,\n" " \"root_module\": \"/root/hare/lib.rs\",\n" " \"label\": \"//hare:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"/root/hare/\",\n" + " \"out/Debug/gendir/hare/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"deps\": [\n" " {\n" " \"crate\": 0,\n" @@ -101,21 +110,20 @@ const char expected_json[] = "{\n" - " \"roots\": [\n" - " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/alloc/src/\",\n" - " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/core/src/\",\n" - " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_abort/src/\",\n" - " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_unwind/src/\",\n" - " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/proc_macro/src/\",\n" - " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/std/src/\",\n" - " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/test/src/\",\n" - " \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/unwind/src/\"\n" - " ],\n" " \"crates\": [\n" " {\n" " \"crate_id\": 0,\n" - " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/core/src/lib.rs\",\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" @@ -125,8 +133,17 @@ " },\n" " {\n" " \"crate_id\": 1,\n" - " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/alloc/src/lib.rs\",\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" @@ -140,8 +157,18 @@ " },\n" " {\n" " \"crate_id\": 2,\n" - " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_abort/src/lib.rs\",\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" @@ -151,8 +178,17 @@ " },\n" " {\n" " \"crate_id\": 3,\n" - " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/unwind/src/lib.rs\",\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" @@ -162,8 +198,17 @@ " },\n" " {\n" " \"crate_id\": 4,\n" - " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/std/src/lib.rs\",\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" @@ -189,8 +234,18 @@ " },\n" " {\n" " \"crate_id\": 5,\n" - " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_unwind/src/lib.rs\",\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" @@ -200,8 +255,18 @@ " },\n" " {\n" " \"crate_id\": 6,\n" - " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/proc_macro/src/lib.rs\",\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" @@ -211,8 +276,17 @@ " },\n" " {\n" " \"crate_id\": 7,\n" - " \"root_module\": \"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/test/src/lib.rs\",\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"
diff --git a/src/gn/rust_project_writer_unittest.cc b/src/gn/rust_project_writer_unittest.cc index 2d4f0dc..e57baf9 100644 --- a/src/gn/rust_project_writer_unittest.cc +++ b/src/gn/rust_project_writer_unittest.cc
@@ -51,14 +51,18 @@ #endif const char expected_json[] = "{\n" - " \"roots\": [\n" - " \"path/foo/\"\n" - " ],\n" " \"crates\": [\n" " {\n" " \"crate_id\": 0,\n" " \"root_module\": \"path/foo/lib.rs\",\n" " \"label\": \"//foo:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"path/foo/\",\n" + " \"path/out/Debug/gen/foo/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"compiler_args\": [\"--cfg=feature=\\\"foo_enabled\\\"\"],\n" " \"deps\": [\n" " ],\n" @@ -111,15 +115,18 @@ #endif const char expected_json[] = "{\n" - " \"roots\": [\n" - " \"hare/\",\n" - " \"tortoise/\"\n" - " ],\n" " \"crates\": [\n" " {\n" " \"crate_id\": 0,\n" " \"root_module\": \"tortoise/lib.rs\",\n" " \"label\": \"//tortoise:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"tortoise/\",\n" + " \"out/Debug/gen/tortoise/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"deps\": [\n" " ],\n" " \"edition\": \"2015\",\n" @@ -132,6 +139,13 @@ " \"crate_id\": 1,\n" " \"root_module\": \"hare/lib.rs\",\n" " \"label\": \"//hare:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"hare/\",\n" + " \"out/Debug/gen/hare/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"deps\": [\n" " {\n" " \"crate\": 0,\n" @@ -197,16 +211,18 @@ #endif const char expected_json[] = "{\n" - " \"roots\": [\n" - " \"achilles/\",\n" - " \"hare/\",\n" - " \"tortoise/\"\n" - " ],\n" " \"crates\": [\n" " {\n" " \"crate_id\": 0,\n" " \"root_module\": \"tortoise/lib.rs\",\n" " \"label\": \"//tortoise:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"tortoise/\",\n" + " \"out/Debug/gen/tortoise/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"deps\": [\n" " ],\n" " \"edition\": \"2015\",\n" @@ -219,6 +235,13 @@ " \"crate_id\": 1,\n" " \"root_module\": \"achilles/lib.rs\",\n" " \"label\": \"//achilles:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"achilles/\",\n" + " \"out/Debug/gen/achilles/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"deps\": [\n" " ],\n" " \"edition\": \"2015\",\n" @@ -231,6 +254,13 @@ " \"crate_id\": 2,\n" " \"root_module\": \"hare/lib.rs\",\n" " \"label\": \"//hare:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"hare/\",\n" + " \"out/Debug/gen/hare/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"deps\": [\n" " {\n" " \"crate\": 0,\n" @@ -314,16 +344,18 @@ #endif const char expected_json[] = "{\n" - " \"roots\": [\n" - " \"hare/\",\n" - " \"tortoise/\",\n" - " \"tortoise/macro/\"\n" - " ],\n" " \"crates\": [\n" " {\n" " \"crate_id\": 0,\n" " \"root_module\": \"tortoise/lib.rs\",\n" " \"label\": \"//tortoise:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"tortoise/\",\n" + " \"out/Debug/gen/tortoise/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"deps\": [\n" " ],\n" " \"edition\": \"2015\",\n" @@ -336,6 +368,13 @@ " \"crate_id\": 1,\n" " \"root_module\": \"tortoise/macro/lib.rs\",\n" " \"label\": \"//tortoise:macro\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"tortoise/macro/\",\n" + " \"out/Debug/gen/tortoise/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"deps\": [\n" " ],\n" " \"edition\": \"2015\",\n" @@ -348,6 +387,13 @@ " \"crate_id\": 2,\n" " \"root_module\": \"hare/lib.rs\",\n" " \"label\": \"//hare:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"hare/\",\n" + " \"out/Debug/gen/hare/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"deps\": [\n" " {\n" " \"crate\": 0,\n" @@ -398,14 +444,18 @@ #endif const char expected_json[] = "{\n" - " \"roots\": [\n" - " \"path/foo/\"\n" - " ],\n" " \"crates\": [\n" " {\n" " \"crate_id\": 0,\n" " \"root_module\": \"path/foo/lib.rs\",\n" " \"label\": \"//foo:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"path/foo/\",\n" + " \"path/out/Debug/gen/foo/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"target\": \"x86-64_unknown\",\n" " \"compiler_args\": [\"--target\", \"x86-64_unknown\"],\n" " \"deps\": [\n" @@ -449,14 +499,18 @@ #endif const char expected_json[] = "{\n" - " \"roots\": [\n" - " \"path/foo/\"\n" - " ],\n" " \"crates\": [\n" " {\n" " \"crate_id\": 0,\n" " \"root_module\": \"path/foo/lib.rs\",\n" " \"label\": \"//foo:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"path/foo/\",\n" + " \"path/out/Debug/gen/foo/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"compiler_args\": [\"--edition=2018\"],\n" " \"deps\": [\n" " ],\n" @@ -500,14 +554,18 @@ #endif const char expected_json[] = "{\n" - " \"roots\": [\n" - " \"path/foo/\"\n" - " ],\n" " \"crates\": [\n" " {\n" " \"crate_id\": 0,\n" " \"root_module\": \"path/foo/lib.rs\",\n" " \"label\": \"//foo:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"path/foo/\",\n" + " \"path/out/Debug/gen/foo/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"compiler_args\": [\"--edition\", \"2018\"],\n" " \"deps\": [\n" " ],\n" @@ -552,14 +610,18 @@ #endif const char expected_json[] = "{\n" - " \"roots\": [\n" - " \"path/foo/\"\n" - " ],\n" " \"crates\": [\n" " {\n" " \"crate_id\": 0,\n" " \"root_module\": \"path/foo/lib.rs\",\n" " \"label\": \"//foo:bar\",\n" + " \"source\": {\n" + " \"include_dirs\": [\n" + " \"path/foo/\",\n" + " \"path/out/Debug/gen/foo/\"\n" + " ],\n" + " \"exclude_dirs\": []\n" + " },\n" " \"compiler_args\": [\"--cfg=feature=\\\"foo_enabled\\\"\"],\n" " \"deps\": [\n" " ],\n"