Provide separate Rust tools for different output types
This introduces a set of new tools corresponding to different Rust
output types/crate types: cdylib, dylib, proc_macro, rlib and staticlib.
This enables using different setting for different output types, e.g.
Rust and static libraris should typically go into different output dirs
akin to their C counterparts. On the other hand, executables and dynamic
libraries might need additional post-processing such as stripping. This
wasn't possible with a single tool because there's no way conditionalize
the logic used by the tool.
Change-Id: I2dc2ad927a2a0f55b995abbf269bb7fcd0037c49
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/6220
Commit-Queue: Petr Hosek <phosek@google.com>
Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/docs/reference.md b/docs/reference.md
index c9dba3d..c4dda86 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -2041,8 +2041,9 @@
the current scope is not (since the overrides haven't been applied yet).
2. At the end of executing the block, any variables set within that scope
- are saved globally as build arguments, with their current values being
- saved as the "default value" for that argument.
+ are saved, with the values specified in the block used as the "default value"
+ for that argument. Once saved, these variables are available for override
+ via args.gn.
3. User-defined overrides are applied. Anything set in "gn args" now
overrides any default values. The resulting set of variables is promoted
@@ -3175,7 +3176,12 @@
"compile_xcassets": [iOS, macOS] Tool to compile asset catalogs.
Rust tools:
- "rustc": Rust compiler and linker
+ "rust_bin": Tool for compiling Rust binaries
+ "rust_cdylib": Tool for compiling C-compatible dynamic libraries.
+ "rust_dylib": Tool for compiling Rust dynamic libraries.
+ "rust_macro": Tool for compiling Rust procedural macros.
+ "rust_rlib": Tool for compiling Rust libraries.
+ "rust_staticlib": Tool for compiling Rust static libraries.
```
#### **Tool variables**
@@ -3592,13 +3598,6 @@
Expands to the list of --extern flags needed to include addition Rust
libraries in this target. Includes any specified renamed dependencies.
- {{rustc_output_extension}}
- Expands to the output extension for this target's crate type.
-
- {{rustc_output_prefix}}
- Expands to the prefix for shared and static libraries. This should
- generally be "lib". Empty for executable targets.
-
{{rustdeps}}
Expands to the list of -Ldependency=<path> strings needed to compile
this target.
diff --git a/tools/gn/c_substitution_type.cc b/tools/gn/c_substitution_type.cc
index eec8c66..98cd139 100644
--- a/tools/gn/c_substitution_type.cc
+++ b/tools/gn/c_substitution_type.cc
@@ -17,7 +17,6 @@
&CSubstitutionLinkerInputs, &CSubstitutionLinkerInputsNewline,
&CSubstitutionLdFlags, &CSubstitutionLibs,
- &CSubstitutionOutputExtension,
&CSubstitutionSoLibs,
&CSubstitutionArFlags,
@@ -41,8 +40,6 @@
"in_newline"};
const Substitution CSubstitutionLdFlags = {"{{ldflags}}", "ldflags"};
const Substitution CSubstitutionLibs = {"{{libs}}", "libs"};
-const Substitution CSubstitutionOutputExtension = {"{{output_extension}}",
- "output_extension"};
const Substitution CSubstitutionSoLibs = {"{{solibs}}", "solibs"};
// Valid for alink only.
@@ -64,22 +61,27 @@
}
bool IsValidLinkerSubstitution(const Substitution* type) {
- return IsValidToolSubstitution(type) || type == &SubstitutionOutputDir ||
+ return IsValidToolSubstitution(type) ||
+ type == &SubstitutionOutputDir ||
+ type == &SubstitutionOutputExtension ||
type == &CSubstitutionLinkerInputs ||
type == &CSubstitutionLinkerInputsNewline ||
- type == &CSubstitutionLdFlags || type == &CSubstitutionLibs ||
- type == &CSubstitutionOutputExtension || type == &CSubstitutionSoLibs;
+ type == &CSubstitutionLdFlags ||
+ type == &CSubstitutionLibs ||
+ type == &CSubstitutionSoLibs;
}
bool IsValidLinkerOutputsSubstitution(const Substitution* type) {
// All valid compiler outputs plus the output extension.
return IsValidCompilerOutputsSubstitution(type) ||
- type == &SubstitutionOutputDir || type == &CSubstitutionOutputExtension;
+ type == &SubstitutionOutputDir || type == &SubstitutionOutputExtension;
}
bool IsValidALinkSubstitution(const Substitution* type) {
- return IsValidToolSubstitution(type) || type == &SubstitutionOutputDir ||
+ return IsValidToolSubstitution(type) ||
+ type == &SubstitutionOutputDir ||
+ type == &SubstitutionOutputExtension ||
type == &CSubstitutionLinkerInputs ||
type == &CSubstitutionLinkerInputsNewline ||
- type == &CSubstitutionArFlags || type == &CSubstitutionOutputExtension;
+ type == &CSubstitutionArFlags;
}
diff --git a/tools/gn/c_substitution_type.h b/tools/gn/c_substitution_type.h
index ed543f0..f4801ea 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 CSubstitutionOutputExtension;
extern const Substitution CSubstitutionSoLibs;
// Valid for alink only.
diff --git a/tools/gn/function_toolchain.cc b/tools/gn/function_toolchain.cc
index cb68612..c8e85de 100644
--- a/tools/gn/function_toolchain.cc
+++ b/tools/gn/function_toolchain.cc
@@ -300,7 +300,12 @@
"compile_xcassets": [iOS, macOS] Tool to compile asset catalogs.
Rust tools:
- "rustc": Rust compiler and linker
+ "rust_bin": Tool for compiling Rust binaries
+ "rust_cdylib": Tool for compiling C-compatible dynamic libraries.
+ "rust_dylib": Tool for compiling Rust dynamic libraries.
+ "rust_macro": Tool for compiling Rust procedural macros.
+ "rust_rlib": Tool for compiling Rust libraries.
+ "rust_staticlib": Tool for compiling Rust static libraries.
Tool variables
@@ -715,13 +720,6 @@
Expands to the list of --extern flags needed to include addition Rust
libraries in this target. Includes any specified renamed dependencies.
- {{rustc_output_extension}}
- Expands to the output extension for this target's crate type.
-
- {{rustc_output_prefix}}
- Expands to the prefix for shared and static libraries. This should
- generally be "lib". Empty for executable targets.
-
{{rustdeps}}
Expands to the list of -Ldependency=<path> strings needed to compile
this target.
diff --git a/tools/gn/function_toolchain_unittest.cc b/tools/gn/function_toolchain_unittest.cc
index baf2e26..a10f729 100644
--- a/tools/gn/function_toolchain_unittest.cc
+++ b/tools/gn/function_toolchain_unittest.cc
@@ -67,7 +67,7 @@
{
TestParseInput input(
R"(toolchain("rust") {
- tool("rustc") {
+ tool("rust_bin") {
command = "{{rustenv}} rustc --crate-name {{crate_name}} --crate-type bin {{rustflags}} -o {{output}} {{externs}} {{source}}"
description = "RUST {{output}}"
}
@@ -83,7 +83,7 @@
const Toolchain* toolchain = setup.items()[0]->AsToolchain();
ASSERT_TRUE(toolchain);
- const Tool* rust = toolchain->GetTool(RustTool::kRsToolRustc);
+ const Tool* rust = toolchain->GetTool(RustTool::kRsToolBin);
ASSERT_TRUE(rust);
ASSERT_EQ(rust->command().AsString(),
"{{rustenv}} rustc --crate-name {{crate_name}} --crate-type bin "
@@ -116,4 +116,4 @@
const Tool* link = toolchain->GetTool(CTool::kCToolCxx);
ASSERT_TRUE(link);
EXPECT_EQ("/usr/goma/gomacc", link->command_launcher());
-}
\ No newline at end of file
+}
diff --git a/tools/gn/ninja_c_binary_target_writer.cc b/tools/gn/ninja_c_binary_target_writer.cc
index a777cbf..f71eebb 100644
--- a/tools/gn/ninja_c_binary_target_writer.cc
+++ b/tools/gn/ninja_c_binary_target_writer.cc
@@ -548,7 +548,7 @@
void NinjaCBinaryTargetWriter::WriteOutputSubstitutions() {
out_ << " output_extension = "
<< SubstitutionWriter::GetLinkerSubstitution(
- target_, tool_, &CSubstitutionOutputExtension);
+ target_, tool_, &SubstitutionOutputExtension);
out_ << std::endl;
out_ << " output_dir = "
<< SubstitutionWriter::GetLinkerSubstitution(target_, tool_,
diff --git a/tools/gn/ninja_c_binary_target_writer_unittest.cc b/tools/gn/ninja_c_binary_target_writer_unittest.cc
index 874616f..74a4f32 100644
--- a/tools/gn/ninja_c_binary_target_writer_unittest.cc
+++ b/tools/gn/ninja_c_binary_target_writer_unittest.cc
@@ -1227,7 +1227,7 @@
"\n"
"build obj/bar/bar.bar.o: cxx ../../bar/bar.cc\n"
"\n"
- "build ./bar: link obj/bar/bar.bar.o obj/foo/foo.a\n"
+ "build ./bar: link obj/bar/bar.bar.o obj/foo/libfoo.a\n"
" ldflags =\n"
" libs =\n"
" output_extension = \n"
@@ -1285,7 +1285,7 @@
"\n"
"build obj/bar/bar.bar.o: cxx ../../bar/bar.cc\n"
"\n"
- "build ./bar: link obj/bar/bar.bar.o obj/foo/foo.a\n"
+ "build ./bar: link obj/bar/bar.bar.o obj/foo/libfoo.a\n"
" ldflags =\n"
" libs =\n"
" output_extension = \n"
@@ -1344,7 +1344,7 @@
"\n"
"build obj/bar/bar.bar.o: cxx ../../bar/bar.cc\n"
"\n"
- "build ./bar: link obj/bar/bar.bar.o obj/foo/foo.a\n"
+ "build ./bar: link obj/bar/bar.bar.o obj/foo/libfoo.a\n"
" ldflags =\n"
" libs =\n"
" output_extension = \n"
diff --git a/tools/gn/ninja_rust_binary_target_writer.cc b/tools/gn/ninja_rust_binary_target_writer.cc
index cd81b43..51e585d 100644
--- a/tools/gn/ninja_rust_binary_target_writer.cc
+++ b/tools/gn/ninja_rust_binary_target_writer.cc
@@ -83,26 +83,14 @@
}
WriteVar(kRustSubstitutionCrateType.ninja_name, crate_type, opts, out);
+ WriteVar(SubstitutionOutputExtension.ninja_name,
+ SubstitutionWriter::GetLinkerSubstitution(target, tool,
+ &SubstitutionOutputExtension),
+ 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,
- tool->AsRust()->rustc_output_extension(
- target->output_type(), target->rust_values().crate_type()),
- opts, out);
- } else if (target->output_extension().empty()) {
- WriteVar(kRustSubstitutionOutputExtension.ninja_name, "", opts, out);
- } else {
- WriteVar(kRustSubstitutionOutputExtension.ninja_name,
- std::string(".") + target->output_extension(), opts, out);
- }
-
- if (target->output_type() == Target::RUST_LIBRARY ||
- target->output_type() == Target::SHARED_LIBRARY)
- WriteVar(kRustSubstitutionOutputPrefix.ninja_name, "lib", opts, out);
}
} // namespace
@@ -183,11 +171,11 @@
WriteCrateVars(target_, tool_, opts, out_);
WriteOneFlag(target_, &kRustSubstitutionRustFlags, false,
- RustTool::kRsToolRustc, &ConfigValues::rustflags, opts,
+ Tool::kToolNone, &ConfigValues::rustflags, opts,
path_output_, out_);
WriteOneFlag(target_, &kRustSubstitutionRustEnv, false,
- RustTool::kRsToolRustc, &ConfigValues::rustenv, opts,
+ Tool::kToolNone, &ConfigValues::rustenv, opts,
path_output_, out_);
WriteSharedVars(subst);
diff --git a/tools/gn/ninja_rust_binary_target_writer_unittest.cc b/tools/gn/ninja_rust_binary_target_writer_unittest.cc
index ed2e547..4eb7eea 100644
--- a/tools/gn/ninja_rust_binary_target_writer_unittest.cc
+++ b/tools/gn/ninja_rust_binary_target_writer_unittest.cc
@@ -80,15 +80,15 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_extension = \n"
"output_dir = \n"
- "rustc_output_extension = \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: rustc ../../foo/main.rs | ../../foo/input3.rs "
+ "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/input3.rs "
"../../foo/main.rs ../../foo/input1.rs ../../foo/input2.rs || "
"obj/foo/sources.stamp\n"
" rustdeps =\n";
@@ -121,20 +121,19 @@
const char expected[] =
"crate_name = mylib\n"
"crate_type = rlib\n"
+ "output_extension = .rlib\n"
"output_dir = \n"
- "rustc_output_extension = .rlib\n"
- "rustc_output_prefix = lib\n"
"rustflags =\n"
"rustenv =\n"
"root_out_dir = .\n"
"target_out_dir = obj/bar\n"
- "target_output_name = mylib\n"
+ "target_output_name = libmylib\n"
"\n"
- "build obj/bar/libmylib.rlib: rustc ../../bar/lib.rs | "
+ "build obj/bar/libmylib.rlib: rust_rlib ../../bar/lib.rs | "
"../../bar/mylib.rs ../../bar/lib.rs\n"
" rustdeps =\n";
std::string out_str = out.str();
- EXPECT_EQ(expected, out_str) << out_str;
+ EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
}
Target another_rlib(setup.settings(), Label(SourceDir("//foo/"), "direct"));
@@ -171,15 +170,15 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_extension = \n"
"output_dir = \n"
- "rustc_output_extension = \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: rustc ../../foo/main.rs | ../../foo/source.rs "
+ "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
"../../foo/main.rs obj/foo/libdirect.rlib obj/bar/libmylib.rlib\n"
" externs = --extern direct=obj/foo/libdirect.rlib --extern "
"mylib=obj/bar/libmylib.rlib\n"
@@ -227,15 +226,15 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_extension = \n"
"output_dir = \n"
- "rustc_output_extension = \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: rustc ../../foo/main.rs | ../../foo/source.rs "
+ "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
"../../foo/main.rs obj/foo/libdirect.rlib\n"
" externs = --extern direct_renamed=obj/foo/libdirect.rlib\n"
" rustdeps = -Ldependency=obj/foo\n";
@@ -290,15 +289,15 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_extension = \n"
"output_dir = \n"
- "rustc_output_extension = \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: rustc ../../foo/main.rs | ../../foo/source.rs "
+ "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
"../../foo/main.rs obj/bar/libmylib.rlib obj/foo/libstatic.a\n"
" externs = --extern mylib=obj/bar/libmylib.rlib\n"
" rustdeps = -Ldependency=obj/bar -Lnative=obj/foo -lstatic\n";
@@ -326,15 +325,15 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_extension = \n"
"output_dir = \n"
- "rustc_output_extension = \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: rustc ../../foo/main.rs | ../../foo/source.rs "
+ "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
"../../foo/main.rs obj/foo/libstatic.a\n"
" rustdeps = -Lnative=obj/foo -lstatic\n";
std::string out_str = out.str();
@@ -378,15 +377,15 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_extension = .exe\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 "
+ "build ./foo_bar.exe: rust_bin ../../foo/main.rs | ../../foo/input3.rs "
"../../foo/main.rs ../../foo/input1.rs ../../foo/input2.rs || "
"obj/foo/sources.stamp\n"
" rustdeps =\n";
@@ -422,15 +421,15 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_extension = \n"
"output_dir = foo\n"
- "rustc_output_extension = \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: rustc ../../foo/main.rs | ../../foo/input.rs "
+ "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/input.rs "
"../../foo/main.rs\n"
" rustdeps = -Lnative=../../baz -lquux\n";
std::string out_str = out.str();
@@ -463,19 +462,19 @@
const char expected[] =
"crate_name = mymacro\n"
"crate_type = proc-macro\n"
+ "output_extension = .so\n"
"output_dir = \n"
- "rustc_output_extension = .so\n"
"rustflags =\n"
"rustenv =\n"
"root_out_dir = .\n"
"target_out_dir = obj/bar\n"
- "target_output_name = mymacro\n"
+ "target_output_name = libmymacro\n"
"\n"
- "build obj/bar/libmymacro.so: rustc ../../bar/lib.rs | "
+ "build obj/bar/libmymacro.so: rust_macro ../../bar/lib.rs | "
"../../bar/mylib.rs ../../bar/lib.rs\n"
" rustdeps =\n";
std::string out_str = out.str();
- EXPECT_EQ(expected, out_str) << out_str;
+ EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
}
Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
@@ -499,15 +498,15 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_extension = \n"
"output_dir = \n"
- "rustc_output_extension = \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: rustc ../../foo/main.rs | ../../foo/source.rs "
+ "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
"../../foo/main.rs || obj/bar/libmymacro.so\n"
" externs = --extern mymacro=obj/bar/libmymacro.so\n"
" rustdeps = -Ldependency=obj/bar\n";
@@ -540,20 +539,19 @@
const char expected[] =
"crate_name = mylib\n"
"crate_type = rlib\n"
+ "output_extension = .rlib\n"
"output_dir = \n"
- "rustc_output_extension = .rlib\n"
- "rustc_output_prefix = lib\n"
"rustflags =\n"
"rustenv =\n"
"root_out_dir = .\n"
"target_out_dir = obj/bar\n"
- "target_output_name = mylib\n"
+ "target_output_name = libmylib\n"
"\n"
- "build obj/bar/libmylib.rlib: rustc ../../bar/lib.rs | "
+ "build obj/bar/libmylib.rlib: rust_rlib ../../bar/lib.rs | "
"../../bar/mylib.rs ../../bar/lib.rs\n"
" rustdeps =\n";
std::string out_str = out.str();
- EXPECT_EQ(expected, out_str) << out_str;
+ EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
}
Target group(setup.settings(), Label(SourceDir("//baz/"), "group"));
@@ -584,15 +582,15 @@
const char expected[] =
"crate_name = foo_bar\n"
"crate_type = bin\n"
+ "output_extension = \n"
"output_dir = \n"
- "rustc_output_extension = \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: rustc ../../foo/main.rs | ../../foo/source.rs "
+ "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
"../../foo/main.rs obj/bar/libmylib.rlib || obj/baz/group.stamp\n"
" externs = --extern mylib=obj/bar/libmylib.rlib\n"
" rustdeps = -Ldependency=obj/bar\n";
diff --git a/tools/gn/rust_substitution_type.cc b/tools/gn/rust_substitution_type.cc
index 8881772..6ce29f0 100644
--- a/tools/gn/rust_substitution_type.cc
+++ b/tools/gn/rust_substitution_type.cc
@@ -12,7 +12,6 @@
const SubstitutionTypes RustSubstitutions = {
&kRustSubstitutionCrateName, &kRustSubstitutionCrateType,
- &kRustSubstitutionOutputExtension, &kRustSubstitutionOutputPrefix,
&kRustSubstitutionRustDeps, &kRustSubstitutionRustFlags,
&kRustSubstitutionRustEnv, &kRustSubstitutionExterns,
};
@@ -23,10 +22,6 @@
const Substitution kRustSubstitutionCrateType = {"{{crate_type}}",
"crate_type"};
const Substitution kRustSubstitutionExterns = {"{{externs}}", "externs"};
-const Substitution kRustSubstitutionOutputExtension = {
- "{{rustc_output_extension}}", "rustc_output_extension"};
-const Substitution kRustSubstitutionOutputPrefix = {"{{rustc_output_prefix}}",
- "rustc_output_prefix"};
const Substitution kRustSubstitutionRustDeps = {"{{rustdeps}}", "rustdeps"};
const Substitution kRustSubstitutionRustEnv = {"{{rustenv}}", "rustenv"};
const Substitution kRustSubstitutionRustFlags = {"{{rustflags}}", "rustflags"};
@@ -34,11 +29,10 @@
bool IsValidRustSubstitution(const Substitution* type) {
return IsValidToolSubstitution(type) || IsValidSourceSubstitution(type) ||
type == &SubstitutionOutputDir ||
+ type == &SubstitutionOutputExtension ||
type == &kRustSubstitutionCrateName ||
type == &kRustSubstitutionCrateType ||
type == &kRustSubstitutionExterns ||
- type == &kRustSubstitutionOutputExtension ||
- type == &kRustSubstitutionOutputPrefix ||
type == &kRustSubstitutionRustDeps ||
type == &kRustSubstitutionRustEnv ||
type == &kRustSubstitutionRustFlags;
diff --git a/tools/gn/rust_substitution_type.h b/tools/gn/rust_substitution_type.h
index e9a78c4..85fc20c 100644
--- a/tools/gn/rust_substitution_type.h
+++ b/tools/gn/rust_substitution_type.h
@@ -17,8 +17,6 @@
extern const Substitution kRustSubstitutionCrateName;
extern const Substitution kRustSubstitutionCrateType;
extern const Substitution kRustSubstitutionExterns;
-extern const Substitution kRustSubstitutionOutputExtension;
-extern const Substitution kRustSubstitutionOutputPrefix;
extern const Substitution kRustSubstitutionRustDeps;
extern const Substitution kRustSubstitutionRustEnv;
extern const Substitution kRustSubstitutionRustFlags;
diff --git a/tools/gn/rust_tool.cc b/tools/gn/rust_tool.cc
index 563b20b..adf3c94 100644
--- a/tools/gn/rust_tool.cc
+++ b/tools/gn/rust_tool.cc
@@ -7,9 +7,14 @@
#include "tools/gn/rust_substitution_type.h"
#include "tools/gn/target.h"
-const char* RustTool::kRsToolRustc = "rustc";
+const char* RustTool::kRsToolBin = "rust_bin";
+const char* RustTool::kRsToolCDylib = "rust_cdylib";
+const char* RustTool::kRsToolDylib = "rust_dylib";
+const char* RustTool::kRsToolMacro = "rust_macro";
+const char* RustTool::kRsToolRlib = "rust_rlib";
+const char* RustTool::kRsToolStaticlib = "rust_staticlib";
-RustTool::RustTool(const char* n) : Tool(n), rlib_output_extension_(".rlib") {
+RustTool::RustTool(const char* n) : Tool(n) {
CHECK(ValidateName(n));
// TODO: should these be settable in toolchain definition?
set_framework_switch("-lframework=");
@@ -28,7 +33,9 @@
}
bool RustTool::ValidateName(const char* name) const {
- return name_ == kRsToolRustc;
+ return name == kRsToolBin || name == kRsToolCDylib ||
+ name == kRsToolDylib || name == kRsToolMacro ||
+ name == kRsToolRlib || name == kRsToolStaticlib;
}
void RustTool::SetComplete() {
@@ -50,28 +57,6 @@
return true;
}
-bool RustTool::ReadOutputExtensions(Scope* scope, Err* err) {
- if (!SetOutputExtension(scope->GetValue("exe_output_extension", true),
- &exe_output_extension_, err))
- return false;
- if (!SetOutputExtension(scope->GetValue("rlib_output_extension", true),
- &rlib_output_extension_, err))
- return false;
- if (!SetOutputExtension(scope->GetValue("dylib_output_extension", true),
- &dylib_output_extension_, err))
- return false;
- if (!SetOutputExtension(scope->GetValue("cdylib_output_extension", true),
- &cdylib_output_extension_, err))
- return false;
- if (!SetOutputExtension(scope->GetValue("staticlib_output_extension", true),
- &staticlib_output_extension_, err))
- return false;
- if (!SetOutputExtension(scope->GetValue("proc_macro_output_extension", true),
- &proc_macro_output_extension_, err))
- return false;
- return true;
-}
-
bool RustTool::ReadOutputsPatternList(Scope* scope,
const char* var,
SubstitutionList* field,
@@ -112,10 +97,6 @@
return false;
}
- if (!ReadOutputExtensions(scope, err)) {
- return false;
- }
-
// All Rust tools should have outputs.
if (!ReadOutputsPatternList(scope, "outputs", &outputs_, err)) {
return false;
@@ -124,37 +105,10 @@
}
bool RustTool::ValidateSubstitution(const Substitution* sub_type) const {
- if (name_ == kRsToolRustc)
+ if (name_ == kRsToolBin || name_ == kRsToolCDylib ||
+ name_ == kRsToolDylib || name_ == kRsToolMacro ||
+ name_ == kRsToolRlib || name_ == kRsToolStaticlib)
return IsValidRustSubstitution(sub_type);
NOTREACHED();
return false;
}
-
-const std::string& RustTool::rustc_output_extension(
- Target::OutputType type,
- const RustValues::CrateType crate_type) const {
- switch (crate_type) {
- case RustValues::CRATE_AUTO: {
- switch (type) {
- case Target::EXECUTABLE:
- return exe_output_extension_;
- case Target::STATIC_LIBRARY:
- return staticlib_output_extension_;
- case Target::RUST_LIBRARY:
- return rlib_output_extension_;
- default:
- NOTREACHED();
- return exe_output_extension_;
- }
- }
- case RustValues::CRATE_DYLIB:
- return dylib_output_extension_;
- case RustValues::CRATE_CDYLIB:
- return cdylib_output_extension_;
- case RustValues::CRATE_PROC_MACRO:
- return proc_macro_output_extension_;
- default:
- NOTREACHED();
- return exe_output_extension_;
- }
-}
diff --git a/tools/gn/rust_tool.h b/tools/gn/rust_tool.h
index 682f74a..46ec801 100644
--- a/tools/gn/rust_tool.h
+++ b/tools/gn/rust_tool.h
@@ -21,7 +21,12 @@
class RustTool : public Tool {
public:
// Rust tools
- static const char* kRsToolRustc;
+ static const char* kRsToolBin;
+ static const char* kRsToolCDylib;
+ static const char* kRsToolDylib;
+ static const char* kRsToolMacro;
+ static const char* kRsToolRlib;
+ static const char* kRsToolStaticlib;
explicit RustTool(const char* n);
~RustTool();
@@ -36,62 +41,13 @@
RustTool* AsRust() override;
const RustTool* AsRust() const override;
- void set_exe_output_extension(std::string ext) {
- DCHECK(!complete_);
- DCHECK(ext.empty() || ext[0] == '.');
- exe_output_extension_ = std::move(ext);
- }
-
- void set_rlib_output_extension(std::string ext) {
- DCHECK(!complete_);
- DCHECK(ext.empty() || ext[0] == '.');
- rlib_output_extension_ = std::move(ext);
- }
-
- void set_dylib_output_extension(std::string ext) {
- DCHECK(!complete_);
- DCHECK(ext.empty() || ext[0] == '.');
- dylib_output_extension_ = std::move(ext);
- }
-
- void set_cdylib_output_extension(std::string ext) {
- DCHECK(!complete_);
- DCHECK(ext.empty() || ext[0] == '.');
- cdylib_output_extension_ = std::move(ext);
- }
-
- void set_staticlib_output_extension(std::string ext) {
- DCHECK(!complete_);
- DCHECK(ext.empty() || ext[0] == '.');
- staticlib_output_extension_ = std::move(ext);
- }
-
- void set_proc_macro_output_extension(std::string ext) {
- DCHECK(!complete_);
- DCHECK(ext.empty() || ext[0] == '.');
- proc_macro_output_extension_ = std::move(ext);
- }
-
- // Will include a leading "." if nonempty.
- const std::string& rustc_output_extension(
- Target::OutputType type,
- const RustValues::CrateType crate_type) const;
-
private:
bool SetOutputExtension(const Value* value, std::string* var, Err* err);
- bool ReadOutputExtensions(Scope* scope, Err* err);
bool ReadOutputsPatternList(Scope* scope,
const char* var,
SubstitutionList* field,
Err* err);
- std::string exe_output_extension_;
- std::string rlib_output_extension_;
- std::string dylib_output_extension_;
- std::string cdylib_output_extension_;
- std::string staticlib_output_extension_;
- std::string proc_macro_output_extension_;
-
DISALLOW_COPY_AND_ASSIGN(RustTool);
};
diff --git a/tools/gn/substitution_type.cc b/tools/gn/substitution_type.cc
index 2f6e23e..4a5f338 100644
--- a/tools/gn/substitution_type.cc
+++ b/tools/gn/substitution_type.cc
@@ -23,6 +23,7 @@
&SubstitutionRootGenDir,
&SubstitutionRootOutDir,
&SubstitutionOutputDir,
+ &SubstitutionOutputExtension,
&SubstitutionTargetGenDir,
&SubstitutionTargetOutDir,
&SubstitutionTargetOutputName,
@@ -75,6 +76,8 @@
const Substitution SubstitutionRootOutDir = {"{{root_out_dir}}",
"root_out_dir"};
const Substitution SubstitutionOutputDir = {"{{output_dir}}", "output_dir"};
+const Substitution SubstitutionOutputExtension = {"{{output_extension}}",
+ "output_extension"};
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 45e890c..5be6e0d 100644
--- a/tools/gn/substitution_type.h
+++ b/tools/gn/substitution_type.h
@@ -40,6 +40,7 @@
extern const Substitution SubstitutionRootGenDir;
extern const Substitution SubstitutionRootOutDir;
extern const Substitution SubstitutionOutputDir;
+extern const Substitution SubstitutionOutputExtension;
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 8b884c6..99eaaf8 100644
--- a/tools/gn/substitution_writer.cc
+++ b/tools/gn/substitution_writer.cc
@@ -562,7 +562,7 @@
target->settings()->build_settings()->build_dir()),
&result);
return result;
- } else if (type == &CSubstitutionOutputExtension) {
+ } else if (type == &SubstitutionOutputExtension) {
// Use the extension provided on the target if specified, otherwise
// fall back on the default. Note that the target's output extension
// does not include the dot but the tool's does.
@@ -574,23 +574,6 @@
} else if (type == &kRustSubstitutionCrateName) {
// Only include the toolchain for non-default toolchains.
return target->rust_values().crate_name();
- } else if (type == &kRustSubstitutionOutputPrefix) {
- // Rustc expects specific output prefixes, so make sure we provide it if
- // necessary.
- if (target->output_type() == Target::RUST_LIBRARY ||
- target->output_type() == Target::SHARED_LIBRARY ||
- target->output_type() == Target::LOADABLE_MODULE)
- return "lib";
- return "";
- } else if (type == &kRustSubstitutionOutputExtension) {
- if (!target->output_extension_set()) {
- DCHECK(tool->AsRust());
- return tool->AsRust()->rustc_output_extension(
- target->output_type(), target->rust_values().crate_type());
- }
- if (target->output_extension().empty())
- return std::string(); // Explicitly set to no extension.
- return std::string(".") + target->output_extension();
} else {
NOTREACHED();
return std::string();
diff --git a/tools/gn/substitution_writer_unittest.cc b/tools/gn/substitution_writer_unittest.cc
index bea8fec..0dea906 100644
--- a/tools/gn/substitution_writer_unittest.cc
+++ b/tools/gn/substitution_writer_unittest.cc
@@ -253,7 +253,7 @@
// The compiler substitution is just target + OUTPUT_EXTENSION combined. So
// test one target one plus the output extension.
EXPECT_EQ(".so", SubstitutionWriter::GetLinkerSubstitution(
- &target, tool, &CSubstitutionOutputExtension));
+ &target, tool, &SubstitutionOutputExtension));
EXPECT_EQ("gen/foo/bar", SubstitutionWriter::GetLinkerSubstitution(
&target, tool, &SubstitutionTargetGenDir));
@@ -270,10 +270,10 @@
// Output extensions can be overridden.
target.set_output_extension("extension");
EXPECT_EQ(".extension", SubstitutionWriter::GetLinkerSubstitution(
- &target, tool, &CSubstitutionOutputExtension));
+ &target, tool, &SubstitutionOutputExtension));
target.set_output_extension("");
EXPECT_EQ("", SubstitutionWriter::GetLinkerSubstitution(
- &target, tool, &CSubstitutionOutputExtension));
+ &target, tool, &SubstitutionOutputExtension));
// Output directory is tested in a separate test below.
}
diff --git a/tools/gn/target.cc b/tools/gn/target.cc
index 5b3d603..db7a1be 100644
--- a/tools/gn/target.cc
+++ b/tools/gn/target.cc
@@ -311,6 +311,8 @@
return functions::kCreateBundle;
case GENERATED_FILE:
return functions::kGeneratedFile;
+ case RUST_LIBRARY:
+ return functions::kRustLibrary;
default:
return "";
}
diff --git a/tools/gn/test_with_scope.cc b/tools/gn/test_with_scope.cc
index 1b9f9f4..477f35d 100644
--- a/tools/gn/test_with_scope.cc
+++ b/tools/gn/test_with_scope.cc
@@ -195,23 +195,81 @@
toolchain->SetTool(std::move(compile_xcassets_tool));
// RUST
- std::unique_ptr<Tool> rustc_tool = Tool::CreateTool(RustTool::kRsToolRustc);
+ std::unique_ptr<Tool> rustc_tool = Tool::CreateTool(RustTool::kRsToolBin);
SetCommandForTool(
"{{rustenv}} rustc --crate-name {{crate_name}} {{source}} "
- "--crate-type {{crate_type}} {{rustflags}} -o "
- "{{target_out_dir}}/"
- "{{rustc_output_prefix}}{{crate_name}}{{rustc_output_extension}} "
+ "--crate-type {{crate_type}} {{rustflags}} -o {{output}} "
"{{rustdeps}} {{externs}}",
rustc_tool.get());
- rustc_tool->AsRust()->set_dylib_output_extension(".so");
- rustc_tool->AsRust()->set_cdylib_output_extension(".so");
- rustc_tool->AsRust()->set_staticlib_output_extension(".a");
- rustc_tool->AsRust()->set_proc_macro_output_extension(".so");
- rustc_tool->AsRust()->set_outputs(SubstitutionList::MakeForTest(
- "{{target_out_dir}}/"
- "{{rustc_output_prefix}}{{crate_name}}{{rustc_output_extension}}"));
+ rustc_tool->set_outputs(SubstitutionList::MakeForTest(
+ "{{root_out_dir}}/{{crate_name}}{{output_extension}}"));
toolchain->SetTool(std::move(rustc_tool));
+ // CDYLIB
+ std::unique_ptr<Tool> cdylib_tool = Tool::CreateTool(RustTool::kRsToolCDylib);
+ SetCommandForTool(
+ "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} "
+ "--crate-type {{crate_type}} {{rustflags}} -o {{output}} "
+ "{{rustdeps}} {{externs}}",
+ cdylib_tool.get());
+ cdylib_tool->set_output_prefix("lib");
+ cdylib_tool->set_default_output_extension(".so");
+ cdylib_tool->set_outputs(SubstitutionList::MakeForTest(
+ "{{root_output_dir}}/{{target_output_name}}{{output_extension}}"));
+ toolchain->SetTool(std::move(cdylib_tool));
+
+ // DYLIB
+ std::unique_ptr<Tool> dylib_tool = Tool::CreateTool(RustTool::kRsToolDylib);
+ SetCommandForTool(
+ "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} "
+ "--crate-type {{crate_type}} {{rustflags}} -o {{output}} "
+ "{{rustdeps}} {{externs}}",
+ dylib_tool.get());
+ dylib_tool->set_output_prefix("lib");
+ dylib_tool->set_default_output_extension(".so");
+ dylib_tool->set_outputs(SubstitutionList::MakeForTest(
+ "{{root_output_dir}}/{{target_output_name}}{{output_extension}}"));
+ toolchain->SetTool(std::move(dylib_tool));
+
+ // PROC_MACRO
+ std::unique_ptr<Tool> proc_macro_tool = Tool::CreateTool(RustTool::kRsToolMacro);
+ SetCommandForTool(
+ "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} "
+ "--crate-type {{crate_type}} {{rustflags}} -o {{output}} "
+ "{{rustdeps}} {{externs}}",
+ proc_macro_tool.get());
+ proc_macro_tool->set_output_prefix("lib");
+ proc_macro_tool->set_default_output_extension(".so");
+ proc_macro_tool->set_outputs(SubstitutionList::MakeForTest(
+ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}"));
+ toolchain->SetTool(std::move(proc_macro_tool));
+
+ // RLIB
+ std::unique_ptr<Tool> rlib_tool = Tool::CreateTool(RustTool::kRsToolRlib);
+ SetCommandForTool(
+ "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} "
+ "--crate-type {{crate_type}} {{rustflags}} -o {{output}} "
+ "{{rustdeps}} {{externs}}",
+ rlib_tool.get());
+ rlib_tool->set_output_prefix("lib");
+ rlib_tool->set_default_output_extension(".rlib");
+ rlib_tool->set_outputs(SubstitutionList::MakeForTest(
+ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}"));
+ toolchain->SetTool(std::move(rlib_tool));
+
+ // STATICLIB
+ std::unique_ptr<Tool> staticlib_tool = Tool::CreateTool(RustTool::kRsToolStaticlib);
+ SetCommandForTool(
+ "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} "
+ "--crate-type {{crate_type}} {{rustflags}} -o {{output}} "
+ "{{rustdeps}} {{externs}}",
+ staticlib_tool.get());
+ staticlib_tool->set_output_prefix("lib");
+ staticlib_tool->set_default_output_extension(".a");
+ staticlib_tool->set_outputs(SubstitutionList::MakeForTest(
+ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}"));
+ toolchain->SetTool(std::move(staticlib_tool));
+
toolchain->ToolchainSetupComplete();
}
diff --git a/tools/gn/tool.cc b/tools/gn/tool.cc
index d67933e..43f6fbd 100644
--- a/tools/gn/tool.cc
+++ b/tools/gn/tool.cc
@@ -274,8 +274,18 @@
GeneralTool::kGeneralToolCompileXCAssets);
// Rust tool
- else if (name == RustTool::kRsToolRustc)
- return std::make_unique<RustTool>(RustTool::kRsToolRustc);
+ else if (name == RustTool::kRsToolBin)
+ return std::make_unique<RustTool>(RustTool::kRsToolBin);
+ else if (name == RustTool::kRsToolCDylib)
+ return std::make_unique<RustTool>(RustTool::kRsToolCDylib);
+ else if (name == RustTool::kRsToolDylib)
+ return std::make_unique<RustTool>(RustTool::kRsToolDylib);
+ else if (name == RustTool::kRsToolMacro)
+ return std::make_unique<RustTool>(RustTool::kRsToolMacro);
+ else if (name == RustTool::kRsToolRlib)
+ return std::make_unique<RustTool>(RustTool::kRsToolRlib);
+ else if (name == RustTool::kRsToolStaticlib)
+ return std::make_unique<RustTool>(RustTool::kRsToolStaticlib);
return nullptr;
}
@@ -297,7 +307,7 @@
case SourceFile::SOURCE_RC:
return CTool::kCToolRc;
case SourceFile::SOURCE_RS:
- return RustTool::kRsToolRustc;
+ return RustTool::kRsToolBin;
case SourceFile::SOURCE_UNKNOWN:
case SourceFile::SOURCE_H:
case SourceFile::SOURCE_O:
@@ -315,8 +325,39 @@
// The contents of this list might be suprising (i.e. stamp tool for copy
// rules). See the header for why.
// TODO(crbug.com/gn/39): Don't emit stamp files for single-output targets.
- if (target->source_types_used().RustSourceUsed())
- return RustTool::kRsToolRustc;
+ if (target->source_types_used().RustSourceUsed()) {
+ switch (target->rust_values().crate_type()) {
+ case RustValues::CRATE_AUTO: {
+ switch (target->output_type()) {
+ case Target::EXECUTABLE:
+ return RustTool::kRsToolBin;
+ case Target::SHARED_LIBRARY:
+ return RustTool::kRsToolDylib;
+ case Target::STATIC_LIBRARY:
+ return RustTool::kRsToolStaticlib;
+ case Target::RUST_LIBRARY:
+ return RustTool::kRsToolRlib;
+ default:
+ break;
+ }
+ break;
+ }
+ case RustValues::CRATE_BIN:
+ return RustTool::kRsToolBin;
+ case RustValues::CRATE_CDYLIB:
+ return RustTool::kRsToolCDylib;
+ case RustValues::CRATE_DYLIB:
+ return RustTool::kRsToolDylib;
+ case RustValues::CRATE_PROC_MACRO:
+ return RustTool::kRsToolMacro;
+ case RustValues::CRATE_RLIB:
+ return RustTool::kRsToolRlib;
+ case RustValues::CRATE_STATICLIB:
+ return RustTool::kRsToolStaticlib;
+ default:
+ NOTREACHED();
+ }
+ }
switch (target->output_type()) {
case Target::GROUP:
return GeneralTool::kGeneralToolStamp;