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_manager.cc

Issue 21114002: Add initial prototype for the GN meta-buildsystem. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add owners and readme Created 7 years, 5 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_manager.h ('k') | tools/gn/target_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/gn/target_manager.cc
diff --git a/tools/gn/target_manager.cc b/tools/gn/target_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ece9f08583c6f6c7118cb25190f7a2d1b5d85e3d
--- /dev/null
+++ b/tools/gn/target_manager.cc
@@ -0,0 +1,134 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tools/gn/target_manager.h"
+
+#include <deque>
+
+#include "base/bind.h"
+#include "base/strings/string_piece.h"
+#include "tools/gn/build_settings.h"
+#include "tools/gn/err.h"
+#include "tools/gn/filesystem_utils.h"
+#include "tools/gn/item_node.h"
+#include "tools/gn/scheduler.h"
+#include "tools/gn/toolchain_manager.h"
+#include "tools/gn/value.h"
+
+TargetManager::TargetManager(const BuildSettings* build_settings)
+ : build_settings_(build_settings) {
+}
+
+TargetManager::~TargetManager() {
+}
+
+Target* TargetManager::GetTarget(const Label& label,
+ const LocationRange& specified_from_here,
+ Target* dep_from,
+ Err* err) {
+ DCHECK(!label.is_null());
+ DCHECK(!label.toolchain_dir().value().empty());
+ DCHECK(!label.toolchain_name().empty());
+
+ base::AutoLock lock(build_settings_->item_tree().lock());
+
+ ItemNode* target_node =
+ build_settings_->item_tree().GetExistingNodeLocked(label);
+ Target* target = NULL;
+ if (!target_node) {
+ // First time we've seen this, may need to load the file.
+
+ // Compute the settings. The common case is that we have a dep_from and
+ // the toolchains match, so we can use the settings from there rather than
+ // querying the toolchain manager (which requires locking, etc.).
+ const Settings* settings;
+ if (dep_from && dep_from->label().ToolchainsEqual(label)) {
+ settings = dep_from->settings();
+ } else {
+ settings =
+ build_settings_->toolchain_manager().GetSettingsForToolchainLocked(
+ specified_from_here, label.GetToolchainLabel(), err);
+ if (!settings)
+ return NULL;
+ }
+
+ target = new Target(settings, label);
+ target_node = new ItemNode(target);
+ target_node->set_originally_referenced_from_here(specified_from_here);
+ build_settings_->item_tree().AddNodeLocked(target_node);
+
+ // We're generating a node when there is no referencing one.
+ if (!dep_from)
+ target_node->set_generated_from_here(specified_from_here);
+
+ // Only schedule loading the given target if somebody is depending on it
+ // (and we optimize by not re-asking it to run the current file).
+ // Otherwise, we're probably generating it right now.
+ if (dep_from && dep_from->label().dir() != label.dir()) {
+ if (!ScheduleInvocationLocked(specified_from_here, label, err))
+ return NULL;
+ }
+ } else if ((target = target_node->item()->AsTarget())) {
+ // Previously saw this item as a target.
+
+ // If we have no dep_from, we're generating it.
+ if (!dep_from) {
+ // In this case, it had better not already be generated.
+ if (target_node->state() != ItemNode::REFERENCED) {
+ *err = Err(specified_from_here,
+ "Duplicate target.",
+ "\"" + label.GetUserVisibleName(true) +
+ "\" being defined here.");
+ err->AppendSubErr(Err(target_node->generated_from_here(),
+ "Originally defined here."));
+ return NULL;
+ } else {
+ target_node->set_generated_from_here(specified_from_here);
+ }
+ }
+ } else {
+ // Error, we previously saw this thing as a non-target.
+ *err = Err(specified_from_here, "Not previously a target.",
+ "The target being declared here was previously seen referenced as a\n"
+ "non-target (like a config)");
+ err->AppendSubErr(Err(target_node->originally_referenced_from_here(),
+ "Originally referenced from here."));
+ return NULL;
+ }
+
+ // Keep a record of the guy asking us for this dependency. We know if
+ // somebody is adding a dependency, that guy it himself not resolved.
+ if (dep_from && target_node->state() != ItemNode::RESOLVED) {
+ build_settings_->item_tree().GetExistingNodeLocked(
+ dep_from->label())->AddDependency(target_node);
+ }
+
+ return target;
+}
+
+void TargetManager::TargetGenerationComplete(const Label& label) {
+ base::AutoLock lock(build_settings_->item_tree().lock());
+ build_settings_->item_tree().MarkItemGeneratedLocked(label);
+}
+
+void TargetManager::GetAllTargets(
+ std::vector<const Target*>* all_targets) const {
+ base::AutoLock lock(build_settings_->item_tree().lock());
+
+ std::vector<const Item*> all_items;
+ build_settings_->item_tree().GetAllItemsLocked(&all_items);
+ for (size_t i = 0; i < all_items.size(); i++) {
+ const Target* t = all_items[i]->AsTarget();
+ if (t)
+ all_targets->push_back(t);
+ }
+}
+
+bool TargetManager::ScheduleInvocationLocked(
+ const LocationRange& specified_from_here,
+ const Label& label,
+ Err* err) {
+ return build_settings_->toolchain_manager().ScheduleInvocationLocked(
+ specified_from_here, label.GetToolchainLabel(), label.dir(), err);
+}
« no previous file with comments | « tools/gn/target_manager.h ('k') | tools/gn/target_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698