ninja_target_writer.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// found in the LICENSE file. 4d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 5d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/ninja_target_writer.h" 6d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 7d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include <fstream> 8d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include <sstream> 9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/file_util.h" 11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/err.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "tools/gn/file_template.h" 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/ninja_binary_target_writer.h" 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/ninja_copy_target_writer.h" 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/ninja_group_target_writer.h" 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/ninja_script_target_writer.h" 17d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scheduler.h" 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "tools/gn/string_utils.h" 19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/target.h" 2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "tools/gn/trace.h" 21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)NinjaTargetWriter::NinjaTargetWriter(const Target* target, 230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const Toolchain* toolchain, 240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) std::ostream& out) 25d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch : settings_(target->settings()), 26d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch target_(target), 270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) toolchain_(toolchain), 28d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out_(out), 29d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch path_output_(settings_->build_settings()->build_dir(), 30d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ESCAPE_NINJA, true), 31d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch helper_(settings_->build_settings()) { 32d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 33d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 34d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochNinjaTargetWriter::~NinjaTargetWriter() { 35d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 37d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// static 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void NinjaTargetWriter::RunAndWriteFile(const Target* target, 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Toolchain* toolchain) { 40d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Settings* settings = target->settings(); 41d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch NinjaHelper helper(settings->build_settings()); 42d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, 4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) target->label().GetUserVisibleName(false)); 450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) trace.SetToolchain(settings->toolchain_label()); 4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 47d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::FilePath ninja_file(settings->build_settings()->GetFullPath( 48d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch helper.GetNinjaFileForTarget(target).GetSourceFile( 49d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch settings->build_settings()))); 50d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (g_scheduler->verbose_logging()) 52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) g_scheduler->Log("Writing", FilePathToUTF8(ninja_file)); 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::CreateDirectory(ninja_file.DirName()); 55d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 56d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // It's rediculously faster to write to a string and then write that to 57d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // disk in one operation than to use an fstream here. 58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::stringstream file; 59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Call out to the correct sub-type of writer. 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (target->output_type() == Target::COPY_FILES) { 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NinjaCopyTargetWriter writer(target, toolchain, file); 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) writer.Run(); 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (target->output_type() == Target::CUSTOM) { 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NinjaScriptTargetWriter writer(target, toolchain, file); 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) writer.Run(); 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (target->output_type() == Target::GROUP) { 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NinjaGroupTargetWriter writer(target, toolchain, file); 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) writer.Run(); 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (target->output_type() == Target::EXECUTABLE || 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) target->output_type() == Target::STATIC_LIBRARY || 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) target->output_type() == Target::SHARED_LIBRARY || 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) target->output_type() == Target::SOURCE_SET) { 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NinjaBinaryTargetWriter writer(target, toolchain, file); 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) writer.Run(); 76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(0); 78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 79d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string contents = file.str(); 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) file_util::WriteFile(ninja_file, contents.c_str(), 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static_cast<int>(contents.size())); 83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 84d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::string NinjaTargetWriter::GetSourcesImplicitDeps() const { 8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::ostringstream ret; 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ret << " |"; 8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Input files are order-only deps. 9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const Target::FileList& prereqs = target_->source_prereqs(); 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool has_files = !prereqs.empty(); 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (size_t i = 0; i < prereqs.size(); i++) { 9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ret << " "; 9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) path_output_.WriteFile(ret, prereqs[i]); 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Add on any direct deps marked as "hard". 980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const LabelTargetVector& deps = target_->deps(); 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (size_t i = 0; i < deps.size(); i++) { 1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (deps[i].ptr->hard_dep()) { 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) has_files = true; 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ret << " "; 1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) path_output_.WriteFile(ret, helper_.GetTargetOutputFile(deps[i].ptr)); 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (has_files) 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return ret.str(); 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return std::string(); // No files added. 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)FileTemplate NinjaTargetWriter::GetOutputTemplate() const { 113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const Target::FileList& outputs = target_->script_values().outputs(); 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::vector<std::string> output_template_args; 115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (size_t i = 0; i < outputs.size(); i++) { 116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // All outputs should be in the output dir. 117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) output_template_args.push_back( 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RemovePrefix(outputs[i].value(), 119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) settings_->build_settings()->build_dir().value())); 120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return FileTemplate(output_template_args); 122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 123