summaryrefslogtreecommitdiffstats
path: root/tools/gn/config.cc
blob: 1175d7f3c8bf66e528969893e45e9a07850b8a53 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// 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/config.h"

#include "tools/gn/err.h"
#include "tools/gn/input_file_manager.h"
#include "tools/gn/item_node.h"
#include "tools/gn/item_tree.h"
#include "tools/gn/scheduler.h"

Config::Config(const Label& label) : Item(label) {
}

Config::~Config() {
}

Config* Config::AsConfig() {
  return this;
}

const Config* Config::AsConfig() const {
  return this;
}

// static
Config* Config::GetConfig(const Settings* settings,
                          const LocationRange& specified_from_here,
                          const Label& label,
                          Item* dep_from,
                          Err* err) {
  DCHECK(!label.is_null());

  ItemTree* tree = &settings->build_settings()->item_tree();
  base::AutoLock lock(tree->lock());

  ItemNode* node = tree->GetExistingNodeLocked(label);
  Config* config = NULL;
  if (!node) {
    config = new Config(label);
    node = new ItemNode(config);
    tree->AddNodeLocked(node);

    // 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()) {
      settings->build_settings()->toolchain_manager().ScheduleInvocationLocked(
          specified_from_here, label.GetToolchainLabel(), label.dir(),
          err);
    }
  } else if ((config = node->item()->AsConfig())) {
    // Previously saw this item as a config.

    // If we have no dep_from, we're generating it. In this case, it had better
    // not already be generated.
    if (!dep_from && node->state() != ItemNode::REFERENCED) {
      *err = Err(specified_from_here, "Duplicate config definition.",
          "You already told me about a config with this name.");
      return NULL;
    }
  } else {
    // Previously saw this thing as a non-config.
    *err = Err(specified_from_here,
               "Config name already used.",
               "Previously you specified a " +
               node->item()->GetItemTypeName() + " with this name instead.");
    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 && node->state() != ItemNode::RESOLVED)
    tree->GetExistingNodeLocked(dep_from->label())->AddDependency(node);

  return config;
}