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/scope_per_file_provider.h" 6 7 #include "tools/gn/filesystem_utils.h" 8 #include "tools/gn/settings.h" 9 #include "tools/gn/source_file.h" 10 #include "tools/gn/toolchain_manager.h" 11 #include "tools/gn/value.h" 12 #include "tools/gn/variables.h" 13 14 ScopePerFileProvider::ScopePerFileProvider(Scope* scope, 15 const SourceFile& source_file) 16 : ProgrammaticProvider(scope), 17 source_file_(source_file) { 18 } 19 20 ScopePerFileProvider::~ScopePerFileProvider() { 21 } 22 23 const Value* ScopePerFileProvider::GetProgrammaticValue( 24 const base::StringPiece& ident) { 25 if (ident == variables::kCurrentToolchain) 26 return GetCurrentToolchain(); 27 if (ident == variables::kDefaultToolchain) 28 return GetDefaultToolchain(); 29 if (ident == variables::kPythonPath) 30 return GetPythonPath(); 31 32 if (ident == variables::kRelativeRootOutputDir) 33 return GetRelativeRootOutputDir(); 34 if (ident == variables::kRelativeRootGenDir) 35 return GetRelativeRootGenDir(); 36 if (ident == variables::kRelativeTargetOutputDir) 37 return GetRelativeTargetOutputDir(); 38 if (ident == variables::kRelativeTargetGenDir) 39 return GetRelativeTargetGenDir(); 40 return NULL; 41 } 42 43 const Value* ScopePerFileProvider::GetCurrentToolchain() { 44 if (!current_toolchain_) { 45 current_toolchain_.reset(new Value(NULL, 46 scope_->settings()->toolchain()->label().GetUserVisibleName(false))); 47 } 48 return current_toolchain_.get(); 49 } 50 51 const Value* ScopePerFileProvider::GetDefaultToolchain() { 52 if (!default_toolchain_) { 53 const ToolchainManager& toolchain_manager = 54 scope_->settings()->build_settings()->toolchain_manager(); 55 default_toolchain_.reset(new Value(NULL, 56 toolchain_manager.GetDefaultToolchainUnlocked().GetUserVisibleName( 57 false))); 58 } 59 return default_toolchain_.get(); 60 } 61 62 const Value* ScopePerFileProvider::GetPythonPath() { 63 if (!python_path_) { 64 python_path_.reset(new Value(NULL, 65 FilePathToUTF8(scope_->settings()->build_settings()->python_path()))); 66 } 67 return python_path_.get(); 68 } 69 70 const Value* ScopePerFileProvider::GetRelativeRootOutputDir() { 71 if (!relative_root_output_dir_) { 72 relative_root_output_dir_.reset(new Value(NULL, 73 GetRelativeRootWithNoLastSlash() + 74 GetRootOutputDirWithNoLastSlash(scope_->settings()))); 75 } 76 return relative_root_output_dir_.get(); 77 } 78 79 const Value* ScopePerFileProvider::GetRelativeRootGenDir() { 80 if (!relative_root_gen_dir_) { 81 relative_root_gen_dir_.reset(new Value(NULL, 82 GetRelativeRootWithNoLastSlash() + 83 GetRootGenDirWithNoLastSlash(scope_->settings()))); 84 } 85 return relative_root_gen_dir_.get(); 86 } 87 88 const Value* ScopePerFileProvider::GetRelativeTargetOutputDir() { 89 if (!relative_target_output_dir_) { 90 relative_target_output_dir_.reset(new Value(NULL, 91 GetRelativeRootWithNoLastSlash() + 92 GetRootOutputDirWithNoLastSlash(scope_->settings()) + "obj/" + 93 GetFileDirWithNoLastSlash())); 94 } 95 return relative_target_output_dir_.get(); 96 } 97 98 const Value* ScopePerFileProvider::GetRelativeTargetGenDir() { 99 if (!relative_target_gen_dir_) { 100 relative_target_gen_dir_.reset(new Value(NULL, 101 GetRelativeRootWithNoLastSlash() + 102 GetRootGenDirWithNoLastSlash(scope_->settings()) + 103 GetFileDirWithNoLastSlash())); 104 } 105 return relative_target_gen_dir_.get(); 106 } 107 108 // static 109 std::string ScopePerFileProvider::GetRootOutputDirWithNoLastSlash( 110 const Settings* settings) { 111 const std::string& output_dir = 112 settings->build_settings()->build_dir().value(); 113 CHECK(!output_dir.empty()); 114 return output_dir.substr(1, output_dir.size() - 1); 115 } 116 117 // static 118 std::string ScopePerFileProvider::GetRootGenDirWithNoLastSlash( 119 const Settings* settings) { 120 return GetRootOutputDirWithNoLastSlash(settings) + "/gen"; 121 } 122 123 std::string ScopePerFileProvider::GetFileDirWithNoLastSlash() const { 124 std::string dir_value = source_file_.GetDir().value(); 125 return dir_value.substr(0, dir_value.size() - 1); 126 } 127 128 std::string ScopePerFileProvider::GetRelativeRootWithNoLastSlash() const { 129 std::string inverted = InvertDir(source_file_.GetDir()); 130 if (inverted.empty()) 131 return "."; 132 return inverted.substr(0, inverted.size() - 1); 133 } 134