Support output_dir for Rust
This change implements support for output_dir expansion in Rust.
BUG=100
Change-Id: I79ffc677814f9f5d8e8eb7169c5ebb0ab4469c70
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/5740
Reviewed-by: Brett Wilson <brettw@google.com>
Commit-Queue: Petr Hosek <phosek@google.com>
diff --git a/tools/gn/c_substitution_type.cc b/tools/gn/c_substitution_type.cc
index 3054124..eec8c66 100644
--- a/tools/gn/c_substitution_type.cc
+++ b/tools/gn/c_substitution_type.cc
@@ -17,7 +17,7 @@
&CSubstitutionLinkerInputs, &CSubstitutionLinkerInputsNewline,
&CSubstitutionLdFlags, &CSubstitutionLibs,
- &CSubstitutionOutputDir, &CSubstitutionOutputExtension,
+ &CSubstitutionOutputExtension,
&CSubstitutionSoLibs,
&CSubstitutionArFlags,
@@ -41,7 +41,6 @@
"in_newline"};
const Substitution CSubstitutionLdFlags = {"{{ldflags}}", "ldflags"};
const Substitution CSubstitutionLibs = {"{{libs}}", "libs"};
-const Substitution CSubstitutionOutputDir = {"{{output_dir}}", "output_dir"};
const Substitution CSubstitutionOutputExtension = {"{{output_extension}}",
"output_extension"};
const Substitution CSubstitutionSoLibs = {"{{solibs}}", "solibs"};
@@ -65,22 +64,22 @@
}
bool IsValidLinkerSubstitution(const Substitution* type) {
- return IsValidToolSubstitution(type) || type == &CSubstitutionLinkerInputs ||
+ return IsValidToolSubstitution(type) || type == &SubstitutionOutputDir ||
+ type == &CSubstitutionLinkerInputs ||
type == &CSubstitutionLinkerInputsNewline ||
type == &CSubstitutionLdFlags || type == &CSubstitutionLibs ||
- type == &CSubstitutionOutputDir ||
type == &CSubstitutionOutputExtension || type == &CSubstitutionSoLibs;
}
bool IsValidLinkerOutputsSubstitution(const Substitution* type) {
// All valid compiler outputs plus the output extension.
return IsValidCompilerOutputsSubstitution(type) ||
- type == &CSubstitutionOutputDir || type == &CSubstitutionOutputExtension;
+ type == &SubstitutionOutputDir || type == &CSubstitutionOutputExtension;
}
bool IsValidALinkSubstitution(const Substitution* type) {
- return IsValidToolSubstitution(type) || type == &CSubstitutionLinkerInputs ||
+ return IsValidToolSubstitution(type) || type == &SubstitutionOutputDir ||
+ type == &CSubstitutionLinkerInputs ||
type == &CSubstitutionLinkerInputsNewline ||
- type == &CSubstitutionArFlags || type == &CSubstitutionOutputDir ||
- type == &CSubstitutionOutputExtension;
+ type == &CSubstitutionArFlags || type == &CSubstitutionOutputExtension;
}
diff --git a/tools/gn/c_substitution_type.h b/tools/gn/c_substitution_type.h
index eee5304..ed543f0 100644
--- a/tools/gn/c_substitution_type.h
+++ b/tools/gn/c_substitution_type.h
@@ -28,7 +28,6 @@
extern const Substitution CSubstitutionLinkerInputsNewline;
extern const Substitution CSubstitutionLdFlags;
extern const Substitution CSubstitutionLibs;
-extern const Substitution CSubstitutionOutputDir;
extern const Substitution CSubstitutionOutputExtension;
extern const Substitution CSubstitutionSoLibs;
diff --git a/tools/gn/ninja_c_binary_target_writer.cc b/tools/gn/ninja_c_binary_target_writer.cc
index f4590ad..04698b5 100644
--- a/tools/gn/ninja_c_binary_target_writer.cc
+++ b/tools/gn/ninja_c_binary_target_writer.cc
@@ -606,7 +606,7 @@
out_ << std::endl;
out_ << " output_dir = "
<< SubstitutionWriter::GetLinkerSubstitution(target_, tool_,
- &CSubstitutionOutputDir);
+ &SubstitutionOutputDir);
out_ << std::endl;
}
diff --git a/tools/gn/ninja_rust_binary_target_writer.cc b/tools/gn/ninja_rust_binary_target_writer.cc
index c39a207..142e542 100644
--- a/tools/gn/ninja_rust_binary_target_writer.cc
+++ b/tools/gn/ninja_rust_binary_target_writer.cc
@@ -81,6 +81,10 @@
}
WriteVar(kRustSubstitutionCrateType.ninja_name, crate_type, opts, out);
+ WriteVar(SubstitutionOutputDir.ninja_name,
+ SubstitutionWriter::GetLinkerSubstitution(target, tool,
+ &SubstitutionOutputDir),
+ opts, out);
if (!target->output_extension_set()) {
DCHECK(tool->AsRust());
WriteVar(kRustSubstitutionOutputExtension.ninja_name,
@@ -232,4 +236,4 @@
void NinjaRustBinaryTargetWriter::WriteEdition() {
DCHECK(!target_->rust_values().edition().empty());
out_ << " edition = " << target_->rust_values().edition() << std::endl;
-}
\ No newline at end of file
+}
diff --git a/tools/gn/ninja_rust_binary_target_writer_unittest.cc b/tools/gn/ninja_rust_binary_target_writer_unittest.cc
index 43bac89..9cac3e2 100644
--- a/tools/gn/ninja_rust_binary_target_writer_unittest.cc
+++ b/tools/gn/ninja_rust_binary_target_writer_unittest.cc
@@ -80,6 +80,7 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_dir = \n"
"rustc_output_extension = \n"
"rustflags =\n"
"rustenv =\n"
@@ -121,6 +122,7 @@
const char expected[] =
"crate_name = mylib\n"
"crate_type = rlib\n"
+ "output_dir = \n"
"rustc_output_extension = .rlib\n"
"rustc_output_prefix = lib\n"
"rustflags =\n"
@@ -172,6 +174,7 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_dir = \n"
"rustc_output_extension = \n"
"rustflags =\n"
"rustenv =\n"
@@ -229,6 +232,7 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_dir = \n"
"rustc_output_extension = \n"
"rustflags =\n"
"rustenv =\n"
@@ -294,6 +298,7 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_dir = \n"
"rustc_output_extension = \n"
"rustflags =\n"
"rustenv =\n"
@@ -309,4 +314,58 @@
std::string out_str = out.str();
EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
}
-}
\ No newline at end of file
+}
+
+TEST_F(NinjaRustBinaryTargetWriterTest, RustOutputExtensionAndDir) {
+ Err err;
+ TestWithScope setup;
+
+ Target source_set(setup.settings(), Label(SourceDir("//foo/"), "sources"));
+ source_set.set_output_type(Target::SOURCE_SET);
+ source_set.visibility().SetPublic();
+ source_set.sources().push_back(SourceFile("//foo/input1.rs"));
+ source_set.sources().push_back(SourceFile("//foo/input2.rs"));
+ source_set.source_types_used().Set(SourceFile::SOURCE_RS);
+ source_set.SetToolchain(setup.toolchain());
+ ASSERT_TRUE(source_set.OnResolved(&err));
+
+ Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
+ target.set_output_type(Target::EXECUTABLE);
+ target.visibility().SetPublic();
+ SourceFile main("//foo/main.rs");
+ target.sources().push_back(SourceFile("//foo/input3.rs"));
+ target.sources().push_back(main);
+ target.source_types_used().Set(SourceFile::SOURCE_RS);
+ target.set_output_extension(std::string("exe"));
+ target.set_output_dir(SourceDir("//out/Debug/foo/"));
+ target.rust_values().set_crate_root(main);
+ target.rust_values().crate_name() = "foo_bar";
+ target.rust_values().edition() = "2018";
+ target.private_deps().push_back(LabelTargetPair(&source_set));
+ target.SetToolchain(setup.toolchain());
+ ASSERT_TRUE(target.OnResolved(&err));
+
+ {
+ std::ostringstream out;
+ NinjaRustBinaryTargetWriter writer(&target, out);
+ writer.Run();
+
+ const char expected[] =
+ "crate_name = foo_bar\n"
+ "crate_type = bin\n"
+ "output_dir = foo\n"
+ "rustc_output_extension = .exe\n"
+ "rustflags =\n"
+ "rustenv =\n"
+ "root_out_dir = .\n"
+ "target_out_dir = obj/foo\n"
+ "target_output_name = bar\n"
+ "\n"
+ "build obj/foo/foo_bar.exe: rustc ../../foo/main.rs | ../../foo/input3.rs "
+ "../../foo/main.rs ../../foo/input1.rs ../../foo/input2.rs || "
+ "obj/foo/sources.stamp\n"
+ " edition = 2018\n";
+ std::string out_str = out.str();
+ EXPECT_EQ(expected, out_str) << out_str;
+ }
+}
diff --git a/tools/gn/rust_substitution_type.cc b/tools/gn/rust_substitution_type.cc
index 83ddbf5..c6b8e9e 100644
--- a/tools/gn/rust_substitution_type.cc
+++ b/tools/gn/rust_substitution_type.cc
@@ -35,6 +35,7 @@
bool IsValidRustSubstitution(const Substitution* type) {
return IsValidToolSubstitution(type) || IsValidSourceSubstitution(type) ||
+ type == &SubstitutionOutputDir ||
type == &kRustSubstitutionCrateName ||
type == &kRustSubstitutionCrateType ||
type == &kRustSubstitutionEdition ||
@@ -44,4 +45,4 @@
type == &kRustSubstitutionRustDeps ||
type == &kRustSubstitutionRustEnv ||
type == &kRustSubstitutionRustFlags;
-}
\ No newline at end of file
+}
diff --git a/tools/gn/substitution_type.cc b/tools/gn/substitution_type.cc
index 6972beb..2f6e23e 100644
--- a/tools/gn/substitution_type.cc
+++ b/tools/gn/substitution_type.cc
@@ -22,6 +22,7 @@
&SubstitutionLabelName,
&SubstitutionRootGenDir,
&SubstitutionRootOutDir,
+ &SubstitutionOutputDir,
&SubstitutionTargetGenDir,
&SubstitutionTargetOutDir,
&SubstitutionTargetOutputName,
@@ -73,6 +74,7 @@
"root_gen_dir"};
const Substitution SubstitutionRootOutDir = {"{{root_out_dir}}",
"root_out_dir"};
+const Substitution SubstitutionOutputDir = {"{{output_dir}}", "output_dir"};
const Substitution SubstitutionTargetGenDir = {"{{target_gen_dir}}",
"target_gen_dir"};
const Substitution SubstitutionTargetOutDir = {"{{target_out_dir}}",
diff --git a/tools/gn/substitution_type.h b/tools/gn/substitution_type.h
index 5bdbf90..45e890c 100644
--- a/tools/gn/substitution_type.h
+++ b/tools/gn/substitution_type.h
@@ -39,6 +39,7 @@
extern const Substitution SubstitutionLabelName;
extern const Substitution SubstitutionRootGenDir;
extern const Substitution SubstitutionRootOutDir;
+extern const Substitution SubstitutionOutputDir;
extern const Substitution SubstitutionTargetGenDir;
extern const Substitution SubstitutionTargetOutDir;
extern const Substitution SubstitutionTargetOutputName;
diff --git a/tools/gn/substitution_writer.cc b/tools/gn/substitution_writer.cc
index 8ce1105..41be9b4 100644
--- a/tools/gn/substitution_writer.cc
+++ b/tools/gn/substitution_writer.cc
@@ -547,7 +547,7 @@
return result;
// Fall-through to the linker-specific ones.
- if (type == &CSubstitutionOutputDir) {
+ if (type == &SubstitutionOutputDir) {
// Use the target's value if there is one (it will have no expansion
// patterns since it can directly use GN variables to compute whatever
// path it wants), or the tool's default (which will contain further