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/toolchain.h"
6
7#include <string.h>
8
9#include "base/logging.h"
10#include "tools/gn/target.h"
11#include "tools/gn/value.h"
12
13const char* Toolchain::kToolCc = "cc";
14const char* Toolchain::kToolCxx = "cxx";
15const char* Toolchain::kToolObjC = "objc";
16const char* Toolchain::kToolObjCxx = "objcxx";
17const char* Toolchain::kToolRc = "rc";
18const char* Toolchain::kToolAsm = "asm";
19const char* Toolchain::kToolAlink = "alink";
20const char* Toolchain::kToolSolink = "solink";
21const char* Toolchain::kToolLink = "link";
22const char* Toolchain::kToolStamp = "stamp";
23const char* Toolchain::kToolCopy = "copy";
24
25Toolchain::Toolchain(const Settings* settings, const Label& label)
26    : Item(settings, label),
27      concurrent_links_(0),
28      setup_complete_(false) {
29}
30
31Toolchain::~Toolchain() {
32}
33
34Toolchain* Toolchain::AsToolchain() {
35  return this;
36}
37
38const Toolchain* Toolchain::AsToolchain() const {
39  return this;
40}
41
42// static
43Toolchain::ToolType Toolchain::ToolNameToType(const base::StringPiece& str) {
44  if (str == kToolCc) return TYPE_CC;
45  if (str == kToolCxx) return TYPE_CXX;
46  if (str == kToolObjC) return TYPE_OBJC;
47  if (str == kToolObjCxx) return TYPE_OBJCXX;
48  if (str == kToolRc) return TYPE_RC;
49  if (str == kToolAsm) return TYPE_ASM;
50  if (str == kToolAlink) return TYPE_ALINK;
51  if (str == kToolSolink) return TYPE_SOLINK;
52  if (str == kToolLink) return TYPE_LINK;
53  if (str == kToolStamp) return TYPE_STAMP;
54  if (str == kToolCopy) return TYPE_COPY;
55  return TYPE_NONE;
56}
57
58// static
59std::string Toolchain::ToolTypeToName(ToolType type) {
60  switch (type) {
61    case TYPE_CC: return kToolCc;
62    case TYPE_CXX: return kToolCxx;
63    case TYPE_OBJC: return kToolObjC;
64    case TYPE_OBJCXX: return kToolObjCxx;
65    case TYPE_RC: return kToolRc;
66    case TYPE_ASM: return kToolAsm;
67    case TYPE_ALINK: return kToolAlink;
68    case TYPE_SOLINK: return kToolSolink;
69    case TYPE_LINK: return kToolLink;
70    case TYPE_STAMP: return kToolStamp;
71    case TYPE_COPY: return kToolCopy;
72    default:
73      NOTREACHED();
74      return std::string();
75  }
76}
77
78const Tool* Toolchain::GetTool(ToolType type) const {
79  DCHECK(type != TYPE_NONE);
80  return tools_[static_cast<size_t>(type)].get();
81}
82
83void Toolchain::SetTool(ToolType type, scoped_ptr<Tool> t) {
84  DCHECK(type != TYPE_NONE);
85  DCHECK(!tools_[type].get());
86  t->SetComplete();
87  tools_[type] = t.Pass();
88}
89
90void Toolchain::ToolchainSetupComplete() {
91  // Collect required bits from all tools.
92  for (size_t i = 0; i < TYPE_NUMTYPES; i++) {
93    if (tools_[i])
94      substitution_bits_.MergeFrom(tools_[i]->substitution_bits());
95  }
96
97  setup_complete_ = true;
98}
99
100// static
101Toolchain::ToolType Toolchain::GetToolTypeForSourceType(SourceFileType type) {
102  switch (type) {
103    case SOURCE_C:
104      return TYPE_CC;
105    case SOURCE_CC:
106      return TYPE_CXX;
107    case SOURCE_M:
108      return TYPE_OBJC;
109    case SOURCE_MM:
110      return TYPE_OBJCXX;
111    case SOURCE_ASM:
112    case SOURCE_S:
113      return TYPE_ASM;
114    case SOURCE_RC:
115      return TYPE_RC;
116    case SOURCE_UNKNOWN:
117    case SOURCE_H:
118    case SOURCE_O:
119      return TYPE_NONE;
120    default:
121      NOTREACHED();
122      return TYPE_NONE;
123  }
124}
125
126const Tool* Toolchain::GetToolForSourceType(SourceFileType type) {
127  return tools_[GetToolTypeForSourceType(type)].get();
128}
129
130// static
131Toolchain::ToolType Toolchain::GetToolTypeForTargetFinalOutput(
132    const Target* target) {
133  // The contents of this list might be suprising (i.e. stamp tool for copy
134  // rules). See the header for why.
135  switch (target->output_type()) {
136    case Target::GROUP:
137      return TYPE_STAMP;
138    case Target::EXECUTABLE:
139      return Toolchain::TYPE_LINK;
140    case Target::SHARED_LIBRARY:
141      return Toolchain::TYPE_SOLINK;
142    case Target::STATIC_LIBRARY:
143      return Toolchain::TYPE_ALINK;
144    case Target::SOURCE_SET:
145      return TYPE_STAMP;
146    case Target::COPY_FILES:
147    case Target::ACTION:
148    case Target::ACTION_FOREACH:
149      return TYPE_STAMP;
150    default:
151      NOTREACHED();
152      return Toolchain::TYPE_NONE;
153  }
154}
155
156const Tool* Toolchain::GetToolForTargetFinalOutput(const Target* target) const {
157  return tools_[GetToolTypeForTargetFinalOutput(target)].get();
158}
159