// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "tools/gn/scope_per_file_provider.h" #include "tools/gn/filesystem_utils.h" #include "tools/gn/settings.h" #include "tools/gn/source_file.h" #include "tools/gn/toolchain_manager.h" #include "tools/gn/value.h" #include "tools/gn/variables.h" ScopePerFileProvider::ScopePerFileProvider(Scope* scope) : ProgrammaticProvider(scope) { } ScopePerFileProvider::~ScopePerFileProvider() { } const Value* ScopePerFileProvider::GetProgrammaticValue( const base::StringPiece& ident) { if (ident == variables::kCurrentToolchain) return GetCurrentToolchain(); if (ident == variables::kDefaultToolchain) return GetDefaultToolchain(); if (ident == variables::kPythonPath) return GetPythonPath(); if (ident == variables::kRootBuildDir) return GetRootBuildDir(); if (ident == variables::kRootGenDir) return GetRootGenDir(); if (ident == variables::kRootOutDir) return GetRootOutDir(); if (ident == variables::kTargetGenDir) return GetTargetGenDir(); if (ident == variables::kTargetOutDir) return GetTargetOutDir(); return NULL; } const Value* ScopePerFileProvider::GetCurrentToolchain() { if (!current_toolchain_) { current_toolchain_.reset(new Value(NULL, scope_->settings()->toolchain()->label().GetUserVisibleName(false))); } return current_toolchain_.get(); } const Value* ScopePerFileProvider::GetDefaultToolchain() { if (!default_toolchain_) { const ToolchainManager& toolchain_manager = scope_->settings()->build_settings()->toolchain_manager(); default_toolchain_.reset(new Value(NULL, toolchain_manager.GetDefaultToolchainUnlocked().GetUserVisibleName( false))); } return default_toolchain_.get(); } const Value* ScopePerFileProvider::GetPythonPath() { if (!python_path_) { python_path_.reset(new Value(NULL, FilePathToUTF8(scope_->settings()->build_settings()->python_path()))); } return python_path_.get(); } const Value* ScopePerFileProvider::GetRootBuildDir() { if (!root_build_dir_) { root_build_dir_.reset(new Value(NULL, "/" + GetRootOutputDirWithNoLastSlash(scope_->settings()))); } return root_build_dir_.get(); } const Value* ScopePerFileProvider::GetRootGenDir() { if (!root_gen_dir_) { root_gen_dir_.reset(new Value(NULL, "/" + GetToolchainGenDirWithNoLastSlash(scope_->settings()))); } return root_gen_dir_.get(); } const Value* ScopePerFileProvider::GetRootOutDir() { if (!root_out_dir_) { root_out_dir_.reset(new Value(NULL, "/" + GetToolchainOutputDirWithNoLastSlash(scope_->settings()))); } return root_out_dir_.get(); } const Value* ScopePerFileProvider::GetTargetGenDir() { if (!target_gen_dir_) { target_gen_dir_.reset(new Value(NULL, "/" + GetToolchainGenDirWithNoLastSlash(scope_->settings()) + GetFileDirWithNoLastSlash())); } return target_gen_dir_.get(); } const Value* ScopePerFileProvider::GetTargetOutDir() { if (!target_out_dir_) { target_out_dir_.reset(new Value(NULL, "/" + GetToolchainOutputDirWithNoLastSlash(scope_->settings()) + "/obj" + GetFileDirWithNoLastSlash())); } return target_out_dir_.get(); } // static std::string ScopePerFileProvider::GetRootOutputDirWithNoLastSlash( const Settings* settings) { const std::string& output_dir = settings->build_settings()->build_dir().value(); if (output_dir == "//") return "//."; // Trim off a leading and trailing slash. So "//foo/bar/" -> /foo/bar". DCHECK(output_dir.size() > 2 && output_dir[0] == '/' && output_dir[output_dir.size() - 1] == '/'); return output_dir.substr(1, output_dir.size() - 2); } // static std::string ScopePerFileProvider::GetToolchainOutputDirWithNoLastSlash( const Settings* settings) { const OutputFile& toolchain_subdir = settings->toolchain_output_subdir(); std::string result; if (toolchain_subdir.value().empty()) { result = GetRootOutputDirWithNoLastSlash(settings); } else { // The toolchain subdir ends in a slash, trim it. result = GetRootOutputDirWithNoLastSlash(settings) + "/" + toolchain_subdir.value(); DCHECK(toolchain_subdir.value()[toolchain_subdir.value().size() - 1] == '/'); result.resize(result.size() - 1); } return result; } // static std::string ScopePerFileProvider::GetToolchainGenDirWithNoLastSlash( const Settings* settings) { return GetToolchainOutputDirWithNoLastSlash(settings) + "/gen"; } std::string ScopePerFileProvider::GetFileDirWithNoLastSlash() const { const std::string& dir_value = scope_->GetSourceDir().value(); if (dir_value == "//") return "//."; // Trim off a leading and trailing slash. So "//foo/bar/" -> /foo/bar". DCHECK(dir_value.size() > 2 && dir_value[0] == '/' && dir_value[dir_value.size() - 1] == '/'); return dir_value.substr(1, dir_value.size() - 2); }