[metadata] Adding metadata vars to write_data target Change-Id: I87fa283e764549fd8f42d2c118e8489083a79fda Reviewed-on: https://gn-review.googlesource.com/c/3421 Commit-Queue: Julie Hockett <juliehockett@google.com> Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/tools/gn/command_desc.cc b/tools/gn/command_desc.cc index 36b14b6..a4b2c87 100644 --- a/tools/gn/command_desc.cc +++ b/tools/gn/command_desc.cc
@@ -288,6 +288,9 @@ {variables::kDeps, DepsHandler}, {variables::kLibs, DefaultHandler}, {variables::kLibDirs, DefaultHandler}, + {variables::kDataKeys, DefaultHandler}, + {variables::kRebase, DefaultHandler}, + {variables::kWalkKeys, DefaultHandler}, {variables::kWriteOutputConversion, DefaultHandler}}; } @@ -365,6 +368,9 @@ HandleProperty(variables::kDeps, handler_map, v, dict); HandleProperty(variables::kLibs, handler_map, v, dict); HandleProperty(variables::kLibDirs, handler_map, v, dict); + HandleProperty(variables::kDataKeys, handler_map, v, dict); + HandleProperty(variables::kRebase, handler_map, v, dict); + HandleProperty(variables::kWalkKeys, handler_map, v, dict); HandleProperty(variables::kWriteOutputConversion, handler_map, v, dict); #undef HandleProperty @@ -461,6 +467,7 @@ cflags_cc [--blame] check_includes configs [--tree] (see below) + data_keys defines [--blame] depfile deps [--all] [--tree] (see below) @@ -474,10 +481,12 @@ outputs public_configs public + rebase script sources testonly visibility + walk_keys runtime_deps Compute all runtime deps for the given target. This is a computed list
diff --git a/tools/gn/desc_builder.cc b/tools/gn/desc_builder.cc index a66a419..3bc7e86 100644 --- a/tools/gn/desc_builder.cc +++ b/tools/gn/desc_builder.cc
@@ -51,6 +51,9 @@ // "libs" : [ list of libraries ], // "lib_dirs" : [ list of library directories ] // "metadata" : [ dictionary of target metadata values ] +// "data_keys" : [ list of target data keys ] +// "walk_keys" : [ list of target walk keys ] +// "rebase" : true or false // "output_conversion" : "string for output conversion" // } // @@ -466,6 +469,22 @@ res->SetKey(variables::kWriteOutputConversion, std::move(ToBaseValue(target_->output_conversion()))); } + if (what(variables::kDataKeys)) { + base::ListValue keys; + for (const auto& k : target_->data_keys()) + keys.GetList().push_back(base::Value(k)); + res->SetKey(variables::kDataKeys, std::move(keys)); + } + if (what(variables::kRebase)) { + res->SetKey(variables::kRebase, + std::move(base::Value(target_->rebase()))); + } + if (what(variables::kWalkKeys)) { + base::ListValue keys; + for (const auto& k : target_->walk_keys()) + keys.GetList().push_back(base::Value(k)); + res->SetKey(variables::kWalkKeys, std::move(keys)); + } } if (what(variables::kDeps))
diff --git a/tools/gn/generated_file_target_generator.cc b/tools/gn/generated_file_target_generator.cc index 96a9f37..f953f38 100644 --- a/tools/gn/generated_file_target_generator.cc +++ b/tools/gn/generated_file_target_generator.cc
@@ -17,7 +17,10 @@ const FunctionCallNode* function_call, Target::OutputType type, Err* err) - : TargetGenerator(target, scope, function_call, err), output_type_(type) {} + : TargetGenerator(target, scope, function_call, err), + output_type_(type), + contents_defined_(false), + data_keys_defined_(false) {} GeneratedFileTargetGenerator::~GeneratedFileTargetGenerator() = default; @@ -34,13 +37,26 @@ return; } - if (!FillContents()) { - *err_ = Err(function_call_, "Contents should be set.", - "The generated_file target requires the \"contents\" variable " - "be set. See \"gn help generated_file\"."); + if (!FillContents()) + return; + if (!FillDataKeys()) + return; + + // One of data and data_keys should be defined. + if (!contents_defined_ && !data_keys_defined_) { + *err_ = Err( + function_call_, "Either contents or data_keys should be set.", + "The generated_file target requires either the \"contents\" variable " + "or the \"data_keys\" variable be set. See \"gn help " + "generated_file\"."); return; } + if (!FillRebase()) + return; + if (!FillWalkKeys()) + return; + if (!FillOutputConversion()) return; } @@ -48,8 +64,23 @@ bool GeneratedFileTargetGenerator::FillContents() { const Value* value = scope_->GetValue(variables::kWriteValueContents, true); if (!value) - return false; + return true; target_->set_contents(*value); + contents_defined_ = true; + return true; +} + +bool GeneratedFileTargetGenerator::IsMetadataCollectionTarget( + const base::StringPiece& variable, + const ParseNode* origin) { + if (contents_defined_) { + *err_ = + Err(origin, variable.as_string() + " won't be used.", + "\"contents\" is defined on this target, and so setting " + + variable.as_string() + + " will have no effect as no metdata collection will occur."); + return false; + } return true; } @@ -67,3 +98,61 @@ target_->set_output_conversion(*value); return true; } + +bool GeneratedFileTargetGenerator::FillRebase() { + const Value* value = scope_->GetValue(variables::kRebase, true); + if (!value) + return true; + if (!IsMetadataCollectionTarget(variables::kRebase, value->origin())) + return false; + if (!value->VerifyTypeIs(Value::BOOLEAN, err_)) + return false; + target_->set_rebase(value->boolean_value()); + return true; +} + +bool GeneratedFileTargetGenerator::FillDataKeys() { + const Value* value = scope_->GetValue(variables::kDataKeys, true); + if (!value) + return true; + if (!IsMetadataCollectionTarget(variables::kDataKeys, value->origin())) + return false; + if (!value->VerifyTypeIs(Value::LIST, err_)) + return false; + + for (const Value& v : value->list_value()) { + // Keys must be strings. + if (!v.VerifyTypeIs(Value::STRING, err_)) + return false; + target_->data_keys().push_back(v.string_value()); + } + + data_keys_defined_ = true; + return true; +} + +bool GeneratedFileTargetGenerator::FillWalkKeys() { + const Value* value = scope_->GetValue(variables::kWalkKeys, true); + // If we define this and contents, that's an error. + if (value && + !IsMetadataCollectionTarget(variables::kWalkKeys, value->origin())) + return false; + + // If we don't define it, we want the default value which is a list + // containing the empty string. + if (!value) { + target_->walk_keys().push_back(""); + return true; + } + + // Otherwise, pull and validate the specified value. + if (!value->VerifyTypeIs(Value::LIST, err_)) + return false; + for (const Value& v : value->list_value()) { + // Keys must be strings. + if (!v.VerifyTypeIs(Value::STRING, err_)) + return false; + target_->walk_keys().push_back(v.string_value()); + } + return true; +}
diff --git a/tools/gn/generated_file_target_generator.h b/tools/gn/generated_file_target_generator.h index 6db9fb1..fb2523d 100644 --- a/tools/gn/generated_file_target_generator.h +++ b/tools/gn/generated_file_target_generator.h
@@ -26,6 +26,20 @@ bool FillGeneratedFileOutput(); bool FillOutputConversion(); bool FillContents(); + bool FillDataKeys(); + bool FillWalkKeys(); + bool FillRebase(); + + // Returns false if `contents` is defined (i.e. if this target was provided + // with explicit contents to write). Returns false otherwise, indicating that + // it is okay to set metadata collection variables on this target. + // + // Should be called before FillContents(). + bool IsMetadataCollectionTarget(const base::StringPiece& variable, + const ParseNode* origin); + + bool contents_defined_; + bool data_keys_defined_; Target::OutputType output_type_;
diff --git a/tools/gn/misc/emacs/gn-mode.el b/tools/gn/misc/emacs/gn-mode.el index 872bfd1..aa33133 100644 --- a/tools/gn/misc/emacs/gn-mode.el +++ b/tools/gn/misc/emacs/gn-mode.el
@@ -93,7 +93,7 @@ "precompiled_header_type" "precompiled_source" "product_type" "public" "public_configs" "public_deps" "response_file_contents" "script" "sources" "testonly" "visibility" "write_runtime_deps" "bundle_contents_dir" - "contents" "output_conversion")) + "contents" "output_conversion" "rebase" "data_keys" "walk_keys")) (defconst gn-font-lock-keywords `((,(regexp-opt gn-font-lock-reserved-keywords 'words) .
diff --git a/tools/gn/misc/tm/GN.tmLanguage b/tools/gn/misc/tm/GN.tmLanguage index 1d48889..5cccf4b 100644 --- a/tools/gn/misc/tm/GN.tmLanguage +++ b/tools/gn/misc/tm/GN.tmLanguage
@@ -89,7 +89,7 @@ <key>comment</key> <string>target variables</string> <key>match</key> - <string>\b(?:all_dependent_configs|allow_circular_includes_from|args|asmflags|cflags|cflags_c|cflags_cc|cflags_objc|cflags_objcc|check_includes|complete_static_lib|configs|data|data_deps|defines|depfile|deps|include_dirs|inputs|ldflags|lib_dirs|libs|output_extension|output_name|outputs|public|public_configs|public_deps|script|sources|testonly|visibility|contents|output_conversion)\b</string> + <string>\b(?:all_dependent_configs|allow_circular_includes_from|args|asmflags|cflags|cflags_c|cflags_cc|cflags_objc|cflags_objcc|check_includes|complete_static_lib|configs|data|data_deps|defines|depfile|deps|include_dirs|inputs|ldflags|lib_dirs|libs|output_extension|output_name|outputs|public|public_configs|public_deps|script|sources|testonly|visibility|contents|output_conversion|rebase|data_keys|walk_keys)\b</string> <key>name</key> <string>entity.other.attribute-name.gn</string> </dict>
diff --git a/tools/gn/misc/vim/syntax/gn.vim b/tools/gn/misc/vim/syntax/gn.vim index a50f550..9d5b060 100644 --- a/tools/gn/misc/vim/syntax/gn.vim +++ b/tools/gn/misc/vim/syntax/gn.vim
@@ -48,7 +48,8 @@ syn keyword gnVariable include_dirs inputs ldflags lib_dirs libs syn keyword gnVariable output_extension output_name outputs public syn keyword gnVariable public_configs public_deps scripte sources testonly -syn keyword gnVariable visibility contents output_conversion +syn keyword gnVariable visibility contents output_conversion rebase +syn keyword gnVariable data_keys walk_keys hi def link gnVariable Keyword " Strings
diff --git a/tools/gn/target.cc b/tools/gn/target.cc index 560f6d0..89810c6 100644 --- a/tools/gn/target.cc +++ b/tools/gn/target.cc
@@ -287,7 +287,8 @@ check_includes_(true), complete_static_lib_(false), testonly_(false), - toolchain_(nullptr) {} + toolchain_(nullptr), + rebase_(false) {} Target::~Target() = default;
diff --git a/tools/gn/target.h b/tools/gn/target.h index 91553f6..e75b97a 100644 --- a/tools/gn/target.h +++ b/tools/gn/target.h
@@ -167,6 +167,14 @@ const Value& output_conversion() const { return output_conversion_; } void set_output_conversion(const Value& value) { output_conversion_ = value; } + // Metadata collection methods for WriteData targets. + bool rebase() const { return rebase_; } + void set_rebase(bool value) { rebase_ = value; } + const std::vector<std::string>& data_keys() const { return data_keys_; } + std::vector<std::string>& data_keys() { return data_keys_; } + const std::vector<std::string>& walk_keys() const { return walk_keys_; } + std::vector<std::string>& walk_keys() { return walk_keys_; } + bool testonly() const { return testonly_; } void set_testonly(bool value) { testonly_ = value; } @@ -413,10 +421,15 @@ Metadata metadata_; - // GenerateFile values. + // GeneratedFile values. Value output_conversion_; Value contents_; // Value::NONE if metadata collection should occur. + // GeneratedFile as metadata collection values. + bool rebase_; + std::vector<std::string> data_keys_; + std::vector<std::string> walk_keys_; + DISALLOW_COPY_AND_ASSIGN(Target); };
diff --git a/tools/gn/variables.cc b/tools/gn/variables.cc index 931261d..7723636 100644 --- a/tools/gn/variables.cc +++ b/tools/gn/variables.cc
@@ -1000,6 +1000,19 @@ } )"; +const char kDataKeys[] = "data_keys"; +const char kDataKeys_HelpShort[] = + "data_keys: [string list] Keys from which to collect metadata."; +const char kDataKeys_Help[] = + R"(data_keys: Keys from which to collect metadata. + + These keys are used to identify metadata to collect. If a walked target + defines this key in its metadata, its value will be appended to the resulting + collection. + + See "gn help generated_file". +)"; + const char kDefines[] = "defines"; const char kDefines_HelpShort[] = "defines: [string list] C preprocessor defines."; @@ -1822,6 +1835,26 @@ } )"; +const char kRebase[] = "rebase"; +const char kRebase_HelpShort[] = + "rebase: [boolean] Rebase collected metadata as files."; +const char kRebase_Help[] = + R"(rebase: Rebase collected metadata as files. + + A boolean that triggers a rebase of collected metadata strings based on their + declared file. Defaults to false. + + Metadata generally declares files as strings relative to the local build file. + However, this data is often used in other contexts, and so setting this flag + will force the metadata collection to be rebased according to the local build + file's location and thus allow the filename to be used anywhere. + + Setting this flag will raise an error if any target's specified metadata is + not a string value. + + See also "gn help generated_file". +)"; + const char kResponseFileContents[] = "response_file_contents"; const char kResponseFileContents_HelpShort[] = "response_file_contents: [string list] Contents of .rsp file for actions."; @@ -2009,6 +2042,25 @@ visibility = [ "./*", "//bar/*" ] )"; +const char kWalkKeys[] = "walk_keys"; +const char kWalkKeys_HelpShort[] = + "walk_keys: [string list] Key(s) for managing the metadata collection " + "walk."; +const char kWalkKeys_Help[] = + R"(walk_keys: Key(s) for managing the metadata collection walk. + + Defaults to []. + + These keys are used to control the next step in a collection walk, acting as + barriers. If a specified key is defined in a target's metadata, the walk will + use the targets listed in that value to determine which targets are walked. + + If no walk_keys are specified for a generated_file target (i.e. "[]"), the + walk will touch all deps and data_deps of the specified target recursively. + + See "gn help generated_file". +)"; + const char kWriteValueContents[] = "contents"; const char kWriteValueContents_HelpShort[] = "contents: Contents to write to file."; @@ -2128,6 +2180,7 @@ INSERT_VARIABLE(Configs) INSERT_VARIABLE(Data) INSERT_VARIABLE(DataDeps) + INSERT_VARIABLE(DataKeys) INSERT_VARIABLE(Defines) INSERT_VARIABLE(Depfile) INSERT_VARIABLE(Deps) @@ -2152,12 +2205,14 @@ INSERT_VARIABLE(Public) INSERT_VARIABLE(PublicConfigs) INSERT_VARIABLE(PublicDeps) + INSERT_VARIABLE(Rebase) INSERT_VARIABLE(ResponseFileContents) INSERT_VARIABLE(Script) INSERT_VARIABLE(Sources) INSERT_VARIABLE(XcodeTestApplicationName) INSERT_VARIABLE(Testonly) INSERT_VARIABLE(Visibility) + INSERT_VARIABLE(WalkKeys) INSERT_VARIABLE(WriteOutputConversion) INSERT_VARIABLE(WriteValueContents) INSERT_VARIABLE(WriteRuntimeDeps)
diff --git a/tools/gn/variables.h b/tools/gn/variables.h index eb0190a..0ef15b8 100644 --- a/tools/gn/variables.h +++ b/tools/gn/variables.h
@@ -183,6 +183,10 @@ extern const char kDataDeps_HelpShort[]; extern const char kDataDeps_Help[]; +extern const char kDataKeys[]; +extern const char kDataKeys_HelpShort[]; +extern const char kDataKeys_Help[]; + extern const char kDefines[]; extern const char kDefines_HelpShort[]; extern const char kDefines_Help[]; @@ -279,6 +283,10 @@ extern const char kPublicDeps_HelpShort[]; extern const char kPublicDeps_Help[]; +extern const char kRebase[]; +extern const char kRebase_HelpShort[]; +extern const char kRebase_Help[]; + extern const char kResponseFileContents[]; extern const char kResponseFileContents_HelpShort[]; extern const char kResponseFileContents_Help[]; @@ -303,6 +311,10 @@ extern const char kVisibility_HelpShort[]; extern const char kVisibility_Help[]; +extern const char kWalkKeys[]; +extern const char kWalkKeys_HelpShort[]; +extern const char kWalkKeys_Help[]; + extern const char kWriteValueContents[]; extern const char kWriteValueContents_HelpShort[]; extern const char kWriteValueContents_Help[];