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