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/script_target_generator.h"
6
7#include "tools/gn/build_settings.h"
8#include "tools/gn/err.h"
9#include "tools/gn/filesystem_utils.h"
10#include "tools/gn/parse_tree.h"
11#include "tools/gn/scope.h"
12#include "tools/gn/value.h"
13#include "tools/gn/value_extractors.h"
14#include "tools/gn/variables.h"
15
16ScriptTargetGenerator::ScriptTargetGenerator(
17    Target* target,
18    Scope* scope,
19    const FunctionCallNode* function_call,
20    Err* err)
21    : TargetGenerator(target, scope, function_call, err) {
22}
23
24ScriptTargetGenerator::~ScriptTargetGenerator() {
25}
26
27void ScriptTargetGenerator::DoRun() {
28  target_->set_output_type(Target::CUSTOM);
29
30  FillExternal();
31  if (err_->has_error())
32    return;
33
34  FillSources();
35  if (err_->has_error())
36    return;
37
38  FillSourcePrereqs();
39  if (err_->has_error())
40    return;
41
42  FillScript();
43  if (err_->has_error())
44    return;
45
46  FillScriptArgs();
47  if (err_->has_error())
48    return;
49
50  FillOutputs();
51  if (err_->has_error())
52    return;
53
54  FillDepfile();
55  if (err_->has_error())
56    return;
57
58  // Script outputs don't depend on the current toolchain so we can skip adding
59  // that dependency.
60}
61
62void ScriptTargetGenerator::FillScript() {
63  // If this gets called, the target type requires a script, so error out
64  // if it doesn't have one.
65  const Value* value = scope_->GetValue(variables::kScript, true);
66  if (!value) {
67    *err_ = Err(function_call_, "This target type requires a \"script\".");
68    return;
69  }
70  if (!value->VerifyTypeIs(Value::STRING, err_))
71    return;
72
73  target_->script_values().set_script(
74      scope_->GetSourceDir().ResolveRelativeFile(value->string_value()));
75}
76
77void ScriptTargetGenerator::FillScriptArgs() {
78  const Value* value = scope_->GetValue(variables::kArgs, true);
79  if (!value)
80    return;
81
82  std::vector<std::string> args;
83  if (!ExtractListOfStringValues(*value, &args, err_))
84    return;
85  target_->script_values().swap_in_args(&args);
86}
87
88void ScriptTargetGenerator::FillDepfile() {
89  const Value* value = scope_->GetValue(variables::kDepfile, true);
90  if (!value)
91    return;
92  target_->script_values().set_depfile(
93      scope_->settings()->build_settings()->build_dir().ResolveRelativeFile(
94          value->string_value()));
95}
96