• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_framework_dir_switch("-Lframework=");
22   set_lib_dir_switch("-Lnative=");
23   set_lib_switch("-l");
24   set_linker_arg("-Clink-arg=");
25   set_dynamic_link_switch("-Clink-arg=-Bdynamic");
26 }
27 
28 RustTool::~RustTool() = default;
29 
AsRust()30 RustTool* RustTool::AsRust() {
31   return this;
32 }
AsRust() const33 const RustTool* RustTool::AsRust() const {
34   return this;
35 }
36 
ValidateName(const char * name) const37 bool RustTool::ValidateName(const char* name) const {
38   return name == kRsToolBin || name == kRsToolCDylib || name == kRsToolDylib ||
39          name == kRsToolMacro || name == kRsToolRlib ||
40          name == kRsToolStaticlib;
41 }
42 
MayLink() const43 bool RustTool::MayLink() const {
44   return name_ == kRsToolBin || name_ == kRsToolCDylib ||
45          name_ == kRsToolDylib || name_ == kRsToolMacro;
46 }
47 
SetComplete()48 void RustTool::SetComplete() {
49   SetToolComplete();
50 }
51 
GetSysroot() const52 std::string_view RustTool::GetSysroot() const {
53   return rust_sysroot_;
54 }
55 
SetOutputExtension(const Value * value,std::string * var,Err * err)56 bool RustTool::SetOutputExtension(const Value* value,
57                                   std::string* var,
58                                   Err* err) {
59   DCHECK(!complete_);
60   if (!value)
61     return true;  // Not present is fine.
62   if (!value->VerifyTypeIs(Value::STRING, err))
63     return false;
64   if (value->string_value().empty())
65     return true;
66 
67   *var = std::move(value->string_value());
68   return true;
69 }
70 
ReadOutputsPatternList(Scope * scope,const char * var,SubstitutionList * field,Err * err)71 bool RustTool::ReadOutputsPatternList(Scope* scope,
72                                       const char* var,
73                                       SubstitutionList* field,
74                                       Err* err) {
75   DCHECK(!complete_);
76   const Value* value = scope->GetValue(var, true);
77   if (!value)
78     return true;  // Not present is fine.
79   if (!value->VerifyTypeIs(Value::LIST, err))
80     return false;
81 
82   SubstitutionList list;
83   if (!list.Parse(*value, err))
84     return false;
85 
86   // Validate the right kinds of patterns are used.
87   if (list.list().empty()) {
88     *err = Err(defined_from(), "\"outputs\" must be specified for this tool.");
89     return false;
90   }
91 
92   for (const auto& cur_type : list.required_types()) {
93     if (!IsValidRustSubstitution(cur_type)) {
94       *err = Err(*value, "Pattern not valid here.",
95                  "You used the pattern " + std::string(cur_type->name) +
96                      " which is not valid\nfor this variable.");
97       return false;
98     }
99   }
100 
101   *field = std::move(list);
102   return true;
103 }
104 
InitTool(Scope * scope,Toolchain * toolchain,Err * err)105 bool RustTool::InitTool(Scope* scope, Toolchain* toolchain, Err* err) {
106   // Initialize default vars.
107   if (!Tool::InitTool(scope, toolchain, err)) {
108     return false;
109   }
110 
111   // All Rust tools should have outputs.
112   if (!ReadOutputsPatternList(scope, "outputs", &outputs_, err)) {
113     return false;
114   }
115 
116   // Check for a sysroot. Sets an empty string when not explicitly set.
117   if (!ReadString(scope, "rust_sysroot", &rust_sysroot_, err)) {
118     return false;
119   }
120 
121   if (MayLink()) {
122     if (!ReadString(scope, "dynamic_link_switch", &dynamic_link_switch_, err)) {
123       return false;
124     }
125   }
126 
127   return true;
128 }
129 
ValidateSubstitution(const Substitution * sub_type) const130 bool RustTool::ValidateSubstitution(const Substitution* sub_type) const {
131   if (MayLink())
132     return IsValidRustLinkerSubstitution(sub_type);
133   if (ValidateName(name_))
134     return IsValidRustSubstitution(sub_type);
135   NOTREACHED();
136   return false;
137 }
138