ninja_toolchain_writer.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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/ninja_toolchain_writer.h" 6 7#include <fstream> 8 9#include "base/file_util.h" 10#include "base/strings/stringize_macros.h" 11#include "tools/gn/build_settings.h" 12#include "tools/gn/item_node.h" 13#include "tools/gn/settings.h" 14#include "tools/gn/target.h" 15#include "tools/gn/toolchain.h" 16#include "tools/gn/trace.h" 17 18NinjaToolchainWriter::NinjaToolchainWriter( 19 const Settings* settings, 20 const std::vector<const Target*>& targets, 21 const std::set<std::string>& skip_files, 22 std::ostream& out) 23 : settings_(settings), 24 targets_(targets), 25 skip_files_(skip_files), 26 out_(out), 27 path_output_(settings_->build_settings()->build_dir(), 28 ESCAPE_NINJA, true), 29 helper_(settings->build_settings()) { 30} 31 32NinjaToolchainWriter::~NinjaToolchainWriter() { 33} 34 35void NinjaToolchainWriter::Run() { 36 WriteRules(); 37 WriteSubninjas(); 38} 39 40// static 41bool NinjaToolchainWriter::RunAndWriteFile( 42 const Settings* settings, 43 const std::vector<const Target*>& targets, 44 const std::set<std::string>& skip_files) { 45 NinjaHelper helper(settings->build_settings()); 46 base::FilePath ninja_file(settings->build_settings()->GetFullPath( 47 helper.GetNinjaFileForToolchain(settings).GetSourceFile( 48 settings->build_settings()))); 49 ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, FilePathToUTF8(ninja_file)); 50 51 file_util::CreateDirectory(ninja_file.DirName()); 52 53 std::ofstream file; 54 file.open(FilePathToUTF8(ninja_file).c_str(), 55 std::ios_base::out | std::ios_base::binary); 56 if (file.fail()) 57 return false; 58 59 NinjaToolchainWriter gen(settings, targets, skip_files, file); 60 gen.Run(); 61 return true; 62} 63 64void NinjaToolchainWriter::WriteRules() { 65 const Toolchain* tc = settings_->toolchain(); 66 std::string indent(" "); 67 68 NinjaHelper helper(settings_->build_settings()); 69 std::string rule_prefix = helper.GetRulePrefix(tc); 70 71 for (int i = Toolchain::TYPE_NONE + 1; i < Toolchain::TYPE_NUMTYPES; i++) { 72 Toolchain::ToolType tool_type = static_cast<Toolchain::ToolType>(i); 73 const Toolchain::Tool& tool = tc->GetTool(tool_type); 74 if (tool.empty()) 75 continue; 76 77 out_ << "rule " << rule_prefix << Toolchain::ToolTypeToName(tool_type) 78 << std::endl; 79 80 #define WRITE_ARG(name) \ 81 if (!tool.name.empty()) \ 82 out_ << indent << " " STRINGIZE(name) " = " << tool.name << std::endl; 83 WRITE_ARG(command); 84 WRITE_ARG(depfile); 85 WRITE_ARG(deps); 86 WRITE_ARG(description); 87 WRITE_ARG(pool); 88 WRITE_ARG(restat); 89 WRITE_ARG(rspfile); 90 WRITE_ARG(rspfile_content); 91 #undef WRITE_ARG 92 } 93 out_ << std::endl; 94} 95 96void NinjaToolchainWriter::WriteSubninjas() { 97 // Write subninja commands for each generated target. 98 for (size_t i = 0; i < targets_.size(); i++) { 99 if (!targets_[i]->item_node()->should_generate() || 100 (targets_[i]->settings()->build_settings()->using_external_generator() 101 && targets_[i]->external())) 102 continue; 103 104 OutputFile ninja_file = helper_.GetNinjaFileForTarget(targets_[i]); 105 if (skip_files_.find(ninja_file.value()) != skip_files_.end()) 106 continue; 107 108 out_ << "subninja "; 109 path_output_.WriteFile(out_, ninja_file); 110 out_ << std::endl; 111 } 112 out_ << std::endl; 113} 114