Add a function rust can use to create targets Bug: 528225104 Change-Id: Ie2ea8aeb37e12c35784a85867ff88ecc6a6a6964 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/25520 Reviewed-by: Takuto Ikuta <tikuta@google.com> Commit-Queue: Matt Stark <msta@google.com>
diff --git a/src/gn/ffi/target.cc b/src/gn/ffi/target.cc index e55f765..2bd3819 100644 --- a/src/gn/ffi/target.cc +++ b/src/gn/ffi/target.cc
@@ -10,6 +10,16 @@ #include "gn/label_ptr.h" #include "gn/source_dir.h" #include "gn/target.h" +#include "gn/target_generator.h" + +Target* create_target(Scope& scope, + rust::Str name, + rust::Str output_type, + Err& err) { + return TargetGenerator::GenerateTarget(&scope, nullptr, + std::string_view(name), + std::string_view(output_type), &err); +} void register_dependency(Target& target, rust::Str package,
diff --git a/src/gn/ffi/target.h b/src/gn/ffi/target.h index c55ac81..74cfa60 100644 --- a/src/gn/ffi/target.h +++ b/src/gn/ffi/target.h
@@ -7,8 +7,16 @@ #include "cxx.h" +class Err; +class Scope; class Target; +// Creates and generates a new target in the given scope. +Target* create_target(Scope& scope, + rust::Str name, + rust::Str output_type, + Err& err); + // Enforces that `target` cannot be resolved until the target for the label has // been resolved. void register_dependency(Target& target,
diff --git a/src/gn/starlark/crates/types/src/output_type.rs b/src/gn/starlark/crates/types/src/output_type.rs index abb5f20..efaa6ae 100644 --- a/src/gn/starlark/crates/types/src/output_type.rs +++ b/src/gn/starlark/crates/types/src/output_type.rs
@@ -25,6 +25,7 @@ GeneratedFile, RustLibrary, RustProcMacro, + Noop, } impl OutputType {
diff --git a/src/gn/target.cc b/src/gn/target.cc index a11a014..b0ebb60 100644 --- a/src/gn/target.cc +++ b/src/gn/target.cc
@@ -562,6 +562,8 @@ return functions::kRustLibrary; case RUST_PROC_MACRO: return functions::kRustProcMacro; + case NOOP: + return "noop"; default: return ""; }
diff --git a/src/gn/target.h b/src/gn/target.h index a4ff8fa..e5303ad 100644 --- a/src/gn/target.h +++ b/src/gn/target.h
@@ -54,6 +54,7 @@ GENERATED_FILE, RUST_LIBRARY, RUST_PROC_MACRO, + NOOP, }; enum DepsIterationType {
diff --git a/src/gn/target_generator.cc b/src/gn/target_generator.cc index 69cbaea..9ae82f9 100644 --- a/src/gn/target_generator.cc +++ b/src/gn/target_generator.cc
@@ -82,6 +82,8 @@ DoRun(); } +void TargetGenerator::DoRun() {} + // static void TargetGenerator::GenerateTarget(Scope* scope, const FunctionCallNode* function_call, @@ -95,11 +97,21 @@ return; } + GenerateTarget(scope, function_call, args[0].string_value(), output_type, + err); +} + +// static +Target* TargetGenerator::GenerateTarget(Scope* scope, + const FunctionCallNode* function_call, + std::string_view name, + std::string_view output_type, + Err* err) { // The location of the target is the directory name with no slash at the end. // FIXME(brettw) validate name. const Label& toolchain_label = ToolchainLabelForScope(scope); - Label label(scope->GetSourceDir(), args[0].string_value(), - toolchain_label.dir(), toolchain_label.name()); + Label label(scope->GetSourceDir(), name, toolchain_label.dir(), + toolchain_label.name()); if (g_scheduler->verbose_logging()) g_scheduler->Log("Defining target", label.GetUserVisibleName(true)); @@ -163,21 +175,33 @@ BinaryTargetGenerator generator(target.get(), scope, function_call, Target::RUST_PROC_MACRO, err); generator.Run(); + } else if (output_type == "noop") { + // This is for targets associated with some (but not all) starlark rules. + // Starlark rules support inheritance, and so no-op is used whenever a + // target does not inherit from a builtin rule. + + // Ensure that common attributes (eg. visibility) are set. + TargetGenerator generator(target.get(), scope, function_call, err); + generator.Run(); + target->set_output_type(Target::NOOP); } else { *err = Err(function_call, "Not a known target type", - "I am very confused by the target type \"" + output_type + "\""); + "I am very confused by the target type \"" + + std::string(output_type) + "\""); } if (err->has_error()) - return; + return nullptr; // Save this target for the file. Scope::ItemVector* collector = scope->GetItemCollector(); if (!collector) { *err = Err(function_call, "Can't define a target in this context."); - return; + return nullptr; } + Target* target_ptr = target.get(); collector->push_back(std::move(target)); + return target_ptr; } const BuildSettings* TargetGenerator::GetBuildSettings() const {
diff --git a/src/gn/target_generator.h b/src/gn/target_generator.h index 442e9a8..8923daf 100644 --- a/src/gn/target_generator.h +++ b/src/gn/target_generator.h
@@ -6,6 +6,7 @@ #define TOOLS_GN_TARGET_GENERATOR_H_ #include <string> +#include <string_view> #include <vector> #include "gn/label_ptr.h" @@ -16,6 +17,7 @@ class FunctionCallNode; class Scope; class SubstitutionPattern; +class Target; class Value; // Fills the variables in a Target object from a Scope (the result of a script @@ -40,9 +42,15 @@ const std::string& output_type, Err* err); + static Target* GenerateTarget(Scope* scope, + const FunctionCallNode* function_call, + std::string_view name, + std::string_view output_type, + Err* err); + protected: // Derived classes implement this to do type-specific generation. - virtual void DoRun() = 0; + virtual void DoRun(); const BuildSettings* GetBuildSettings() const;