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