[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[];