1 // Copyright 2019 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 "gn/rust_tool.h"
6
7 #include "gn/rust_substitution_type.h"
8 #include "gn/target.h"
9
10 const char* RustTool::kRsToolBin = "rust_bin";
11 const char* RustTool::kRsToolCDylib = "rust_cdylib";
12 const char* RustTool::kRsToolDylib = "rust_dylib";
13 const char* RustTool::kRsToolMacro = "rust_macro";
14 const char* RustTool::kRsToolRlib = "rust_rlib";
15 const char* RustTool::kRsToolStaticlib = "rust_staticlib";
16
RustTool(const char * n)17 RustTool::RustTool(const char* n) : Tool(n) {
18 CHECK(ValidateName(n));
19 // TODO: should these be settable in toolchain definition?
20 set_framework_switch("-lframework=");
21 set_lib_dir_switch("-Lnative=");
22 set_lib_switch("-l");
23 set_linker_arg("-Clink-arg=");
24 }
25
26 RustTool::~RustTool() = default;
27
AsRust()28 RustTool* RustTool::AsRust() {
29 return this;
30 }
AsRust() const31 const RustTool* RustTool::AsRust() const {
32 return this;
33 }
34
ValidateName(const char * name) const35 bool RustTool::ValidateName(const char* name) const {
36 return name == kRsToolBin || name == kRsToolCDylib ||
37 name == kRsToolDylib || name == kRsToolMacro ||
38 name == kRsToolRlib || name == kRsToolStaticlib;
39 }
40
SetComplete()41 void RustTool::SetComplete() {
42 SetToolComplete();
43 }
44
SetOutputExtension(const Value * value,std::string * var,Err * err)45 bool RustTool::SetOutputExtension(const Value* value,
46 std::string* var,
47 Err* err) {
48 DCHECK(!complete_);
49 if (!value)
50 return true; // Not present is fine.
51 if (!value->VerifyTypeIs(Value::STRING, err))
52 return false;
53 if (value->string_value().empty())
54 return true;
55
56 *var = std::move(value->string_value());
57 return true;
58 }
59
ReadOutputsPatternList(Scope * scope,const char * var,SubstitutionList * field,Err * err)60 bool RustTool::ReadOutputsPatternList(Scope* scope,
61 const char* var,
62 SubstitutionList* field,
63 Err* err) {
64 DCHECK(!complete_);
65 const Value* value = scope->GetValue(var, true);
66 if (!value)
67 return true; // Not present is fine.
68 if (!value->VerifyTypeIs(Value::LIST, err))
69 return false;
70
71 SubstitutionList list;
72 if (!list.Parse(*value, err))
73 return false;
74
75 // Validate the right kinds of patterns are used.
76 if (list.list().empty()) {
77 *err = Err(defined_from(), "\"outputs\" must be specified for this tool.");
78 return false;
79 }
80
81 for (const auto& cur_type : list.required_types()) {
82 if (!IsValidRustSubstitution(cur_type)) {
83 *err = Err(*value, "Pattern not valid here.",
84 "You used the pattern " + std::string(cur_type->name) +
85 " which is not valid\nfor this variable.");
86 return false;
87 }
88 }
89
90 *field = std::move(list);
91 return true;
92 }
93
InitTool(Scope * scope,Toolchain * toolchain,Err * err)94 bool RustTool::InitTool(Scope* scope, Toolchain* toolchain, Err* err) {
95 // Initialize default vars.
96 if (!Tool::InitTool(scope, toolchain, err)) {
97 return false;
98 }
99
100 // All Rust tools should have outputs.
101 if (!ReadOutputsPatternList(scope, "outputs", &outputs_, err)) {
102 return false;
103 }
104 return true;
105 }
106
ValidateSubstitution(const Substitution * sub_type) const107 bool RustTool::ValidateSubstitution(const Substitution* sub_type) const {
108 if (name_ == kRsToolBin || name_ == kRsToolCDylib ||
109 name_ == kRsToolDylib || name_ == kRsToolMacro ||
110 name_ == kRsToolRlib || name_ == kRsToolStaticlib)
111 return IsValidRustSubstitution(sub_type);
112 NOTREACHED();
113 return false;
114 }
115