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