Export Rust information in JSON IDE format
Adds test for rust library JSON output
Change-Id: I6ea3612260bac7b14d53fa660803fcbae5bcb7b6
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/7380
Commit-Queue: Petr Hosek <phosek@google.com>
Reviewed-by: Petr Hosek <phosek@google.com>
diff --git a/src/gn/desc_builder.cc b/src/gn/desc_builder.cc
index 4e8f690..f2a57e4 100644
--- a/src/gn/desc_builder.cc
+++ b/src/gn/desc_builder.cc
@@ -53,6 +53,8 @@
// "metadata" : [ dictionary of target metadata values ]
// "data_keys" : [ list of target data keys ]
// "walk_keys" : [ list of target walk keys ]
+// "crate_root" : "root file of a Rust target"
+// "crate_name" : "name of a Rust target"
// "rebase" : true or false
// "output_conversion" : "string for output conversion"
// "response_file_contents": [ list of response file contents entries ]
@@ -317,6 +319,13 @@
target_->label().GetToolchainLabel().GetUserVisibleName(false)));
}
+ if (target_->source_types_used().RustSourceUsed()) {
+ res->SetWithoutPathExpansion(
+ "crate_root", RenderValue(target_->rust_values().crate_root()));
+ res->SetKey("crate_name",
+ base::Value(target_->rust_values().crate_name()));
+ }
+
// General target meta variables.
if (what(variables::kMetadata)) {
diff --git a/src/gn/json_project_writer.h b/src/gn/json_project_writer.h
index 72780ee..ee2e7b9 100644
--- a/src/gn/json_project_writer.h
+++ b/src/gn/json_project_writer.h
@@ -25,6 +25,7 @@
private:
FRIEND_TEST_ALL_PREFIXES(JSONProjectWriter, ActionWithResponseFile);
FRIEND_TEST_ALL_PREFIXES(JSONProjectWriter, ForEachWithResponseFile);
+ FRIEND_TEST_ALL_PREFIXES(JSONProjectWriter, RustTarget);
static std::string RenderJSON(const BuildSettings* build_settings,
std::vector<const Target*>& all_targets);
diff --git a/src/gn/json_project_writer_unittest.cc b/src/gn/json_project_writer_unittest.cc
index f82bc0d..709d7c1 100644
--- a/src/gn/json_project_writer_unittest.cc
+++ b/src/gn/json_project_writer_unittest.cc
@@ -72,6 +72,61 @@
EXPECT_EQ(expected_json, out);
}
+TEST(JSONProjectWriter, RustTarget) {
+ Err err;
+ TestWithScope setup;
+
+ Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
+ target.set_output_type(Target::RUST_LIBRARY);
+ target.visibility().SetPublic();
+ SourceFile lib("//foo/lib.rs");
+ target.sources().push_back(lib);
+ target.source_types_used().Set(SourceFile::SOURCE_RS);
+ target.rust_values().set_crate_root(lib);
+ target.rust_values().crate_name() = "foo";
+ target.SetToolchain(setup.toolchain());
+ ASSERT_TRUE(target.OnResolved(&err));
+
+ std::vector<const Target*> targets;
+ targets.push_back(&target);
+ std::string out =
+ JSONProjectWriter::RenderJSON(setup.build_settings(), targets);
+#if defined(OS_WIN)
+ base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
+#endif
+ const char expected_json[] =
+ "{\n"
+ " \"build_settings\": {\n"
+ " \"build_dir\": \"//out/Debug/\",\n"
+ " \"default_toolchain\": \"//toolchain:default\",\n"
+ " \"root_path\": \"\"\n"
+ " },\n"
+ " \"targets\": {\n"
+ " \"//foo:bar()\": {\n"
+ " \"allow_circular_includes_from\": [ ],\n"
+ " \"check_includes\": true,\n"
+ " \"crate_name\": \"foo\",\n"
+ " \"crate_root\": \"//foo/lib.rs\",\n"
+ " \"deps\": [ ],\n"
+ " \"externs\": {\n"
+ "\n"
+ " },\n"
+ " \"metadata\": {\n"
+ "\n"
+ " },\n"
+ " \"outputs\": [ \"//out/Debug/obj/foo/libbar.rlib\" ],\n"
+ " \"public\": \"*\",\n"
+ " \"sources\": [ \"//foo/lib.rs\" ],\n"
+ " \"testonly\": false,\n"
+ " \"toolchain\": \"\",\n"
+ " \"type\": \"rust_library\",\n"
+ " \"visibility\": [ \"*\" ]\n"
+ " }\n"
+ " }\n"
+ "}\n";
+ EXPECT_EQ(expected_json, out);
+}
+
TEST(JSONProjectWriter, ForEachWithResponseFile) {
Err err;
TestWithScope setup;
diff --git a/src/gn/substitution_writer.cc b/src/gn/substitution_writer.cc
index 6674c9b..199faa3 100644
--- a/src/gn/substitution_writer.cc
+++ b/src/gn/substitution_writer.cc
@@ -381,6 +381,8 @@
NOTREACHED() << "Cannot use substitution " << type->name
<< " without target";
return std::string();
+ } else if (IsValidRustSubstitution(type)) {
+ to_rebase = source.value();
} else {
NOTREACHED() << "Unsupported substitution for this function: "
<< type->name;
diff --git a/src/gn/target.cc b/src/gn/target.cc
index 8721f1a..6df5ede 100644
--- a/src/gn/target.cc
+++ b/src/gn/target.cc
@@ -501,6 +501,11 @@
return true;
}
+ // Rust generates on a module level, not source.
+ if (file_type == SourceFile::SOURCE_RS) {
+ return false;
+ }
+
*computed_tool_type = Tool::GetToolTypeForSourceType(file_type);
if (*computed_tool_type == Tool::kToolNone)
return false; // No tool for this file (it's a header file or something).