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;