Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Unified Diff: tools/gn/target.cc

Issue 524623005: Add testonly flag to GN (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/gn/target.h ('k') | tools/gn/target_generator.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/gn/target.cc
diff --git a/tools/gn/target.cc b/tools/gn/target.cc
index f5bdd585cd09bdd5c97c28f4313b1c9e6c4f1985..74c98db3a1b789aba2856205726a218475c1e01c 100644
--- a/tools/gn/target.cc
+++ b/tools/gn/target.cc
@@ -39,12 +39,40 @@ void MergeAllDependentConfigsFrom(const Target* from_target,
}
}
+Err MakeTestOnlyError(const Target* from, const Target* to) {
+ return Err(from->defined_from(), "Test-only dependency not allowed.",
+ from->label().GetUserVisibleName(false) + "\n"
+ "which is NOT marked testonly can't depend on\n" +
+ to->label().GetUserVisibleName(false) + "\n"
+ "which is marked testonly. Only targets with \"testonly = true\"\n"
+ "can depend on other test-only targets.\n"
+ "\n"
+ "Either mark it test-only or don't do this dependency.");
+}
+
+// Inserts the given groups dependencies, starting at the given index of the
+// given vector. Returns the number of items inserted.
+size_t InsertGroupDeps(LabelTargetVector* vector,
+ size_t insert_at,
+ const Target* group) {
+ const LabelTargetVector& deps = group->deps();
+ vector->insert(vector->begin() + insert_at, deps.begin(), deps.end());
+
+ // Clear the origin of each of the insertions. This marks these dependencies
+ // as internally generated.
+ for (size_t i = insert_at; i < deps.size() + insert_at; i++)
+ (*vector)[i].origin = NULL;
+
+ return deps.size();
+}
+
} // namespace
Target::Target(const Settings* settings, const Label& label)
: Item(settings, label),
output_type_(UNKNOWN),
all_headers_public_(true),
+ testonly_(false),
hard_dep_(false),
toolchain_(NULL) {
}
@@ -86,22 +114,11 @@ const Target* Target::AsTarget() const {
return this;
}
-void Target::OnResolved() {
+bool Target::OnResolved(Err* err) {
DCHECK(output_type_ != UNKNOWN);
DCHECK(toolchain_) << "Toolchain should have been set before resolving.";
- // Convert any groups we depend on to just direct dependencies on that
- // group's deps. We insert the new deps immediately after the group so that
- // the ordering is preserved. We need to keep the original group so that any
- // flags, etc. that it specifies itself are applied to us.
- for (size_t i = 0; i < deps_.size(); i++) {
- const Target* dep = deps_[i].ptr;
- if (dep->output_type_ == GROUP) {
- // TODO(brettw) bug 403488 this should also handle datadeps.
- deps_.insert(deps_.begin() + i + 1, dep->deps_.begin(), dep->deps_.end());
- i += dep->deps_.size();
- }
- }
+ ExpandGroups();
// Copy our own dependent configs to the list of configs applying to us.
configs_.Append(all_dependent_configs_.begin(), all_dependent_configs_.end());
@@ -129,6 +146,13 @@ void Target::OnResolved() {
PullRecursiveHardDeps();
FillOutputFiles();
+
+ if (!CheckVisibility(err))
+ return false;
+ if (!CheckTestonly(err))
+ return false;
+
+ return true;
}
bool Target::IsLinkable() const {
@@ -182,6 +206,19 @@ bool Target::SetToolchain(const Toolchain* toolchain, Err* err) {
return false;
}
+void Target::ExpandGroups() {
+ // Convert any groups we depend on to just direct dependencies on that
+ // group's deps. We insert the new deps immediately after the group so that
+ // the ordering is preserved. We need to keep the original group so that any
+ // flags, etc. that it specifies itself are applied to us.
+ // TODO(brettw) bug 403488 this should also handle datadeps.
+ for (size_t i = 0; i < deps_.size(); i++) {
+ const Target* dep = deps_[i].ptr;
+ if (dep->output_type_ == GROUP)
+ i += InsertGroupDeps(&deps_, i + 1, dep);
+ }
+}
+
void Target::PullDependentTargetInfo() {
// Gather info from our dependents we need.
for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) {
@@ -305,3 +342,48 @@ void Target::FillOutputFiles() {
NOTREACHED();
}
}
+
+bool Target::CheckVisibility(Err* err) const {
+ // Only check visibility when the origin of the dependency is non-null. These
+ // are dependencies added by the GN files. Internally added dependencies
+ // (expanded groups) will have a null origin. We don't want to check
+ // visibility for these, since the point of a group would often be to
+ // forward visibility.
+ for (size_t i = 0; i < deps_.size(); i++) {
+ if (deps_[i].origin &&
+ !Visibility::CheckItemVisibility(this, deps_[i].ptr, err))
+ return false;
+ }
+
+ for (size_t i = 0; i < datadeps_.size(); i++) {
+ if (deps_[i].origin &&
+ !Visibility::CheckItemVisibility(this, datadeps_[i].ptr, err))
+ return false;
+ }
+
+ return true;
+}
+
+bool Target::CheckTestonly(Err* err) const {
+ // If there current target is marked testonly, it can include both testonly
+ // and non-testonly targets, so there's nothing to check.
+ if (testonly())
+ return true;
+
+ // Verify no deps have "testonly" set.
+ for (size_t i = 0; i < deps_.size(); i++) {
+ if (deps_[i].ptr->testonly()) {
+ *err = MakeTestOnlyError(this, deps_[i].ptr);
+ return false;
+ }
+ }
+
+ for (size_t i = 0; i < datadeps_.size(); i++) {
+ if (datadeps_[i].ptr->testonly()) {
+ *err = MakeTestOnlyError(this, datadeps_[i].ptr);
+ return false;
+ }
+ }
+
+ return true;
+}
« no previous file with comments | « tools/gn/target.h ('k') | tools/gn/target_generator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698