1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "tools/gn/config.h" 6 7#include "tools/gn/err.h" 8#include "tools/gn/input_file_manager.h" 9#include "tools/gn/item_node.h" 10#include "tools/gn/item_tree.h" 11#include "tools/gn/scheduler.h" 12 13Config::Config(const Label& label) : Item(label) { 14} 15 16Config::~Config() { 17} 18 19Config* Config::AsConfig() { 20 return this; 21} 22 23const Config* Config::AsConfig() const { 24 return this; 25} 26 27// static 28Config* Config::GetConfig(const Settings* settings, 29 const LocationRange& specified_from_here, 30 const Label& label, 31 Item* dep_from, 32 Err* err) { 33 DCHECK(!label.is_null()); 34 35 ItemTree* tree = &settings->build_settings()->item_tree(); 36 base::AutoLock lock(tree->lock()); 37 38 ItemNode* node = tree->GetExistingNodeLocked(label); 39 Config* config = NULL; 40 if (!node) { 41 config = new Config(label); 42 node = new ItemNode(config); 43 tree->AddNodeLocked(node); 44 45 // Only schedule loading the given target if somebody is depending on it 46 // (and we optimize by not re-asking it to run the current file). 47 // Otherwise, we're probably generating it right now. 48 if (dep_from && dep_from->label().dir() != label.dir()) { 49 settings->build_settings()->toolchain_manager().ScheduleInvocationLocked( 50 specified_from_here, label.GetToolchainLabel(), label.dir(), 51 err); 52 } 53 } else if ((config = node->item()->AsConfig())) { 54 // Previously saw this item as a config. 55 56 // If we have no dep_from, we're generating it. In this case, it had better 57 // not already be generated. 58 if (!dep_from && node->state() != ItemNode::REFERENCED) { 59 *err = Err(specified_from_here, "Duplicate config definition.", 60 "You already told me about a config with this name."); 61 return NULL; 62 } 63 } else { 64 // Previously saw this thing as a non-config. 65 *err = Err(specified_from_here, 66 "Config name already used.", 67 "Previously you specified a " + 68 node->item()->GetItemTypeName() + " with this name instead."); 69 return NULL; 70 } 71 72 // Keep a record of the guy asking us for this dependency. We know if 73 // somebody is adding a dependency, that guy it himself not resolved. 74 if (dep_from) { 75 if (!tree->GetExistingNodeLocked(dep_from->label())->AddDependency( 76 settings->build_settings(), specified_from_here, node, err)) 77 return NULL; 78 } 79 return config; 80} 81