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 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/strings/string_util.h" 12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/err.h" 1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "tools/gn/filesystem_utils.h" 1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "tools/gn/ninja_action_target_writer.h" 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/ninja_binary_target_writer.h" 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/ninja_copy_target_writer.h" 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/ninja_group_target_writer.h" 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "tools/gn/ninja_utils.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "tools/gn/output_file.h" 20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scheduler.h" 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "tools/gn/string_utils.h" 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "tools/gn/substitution_writer.h" 23d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/target.h" 2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "tools/gn/trace.h" 25d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)NinjaTargetWriter::NinjaTargetWriter(const Target* target, 270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) std::ostream& out) 28d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch : settings_(target->settings()), 29d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch target_(target), 30d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out_(out), 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) path_output_(settings_->build_settings()->build_dir(), ESCAPE_NINJA) { 32d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 33d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 34d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochNinjaTargetWriter::~NinjaTargetWriter() { 35d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 37d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// static 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void NinjaTargetWriter::RunAndWriteFile(const Target* target) { 39d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Settings* settings = target->settings(); 40d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, 4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) target->label().GetUserVisibleName(false)); 430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) trace.SetToolchain(settings->toolchain_label()); 4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 45d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::FilePath ninja_file(settings->build_settings()->GetFullPath( 4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) GetNinjaFileForTarget(target))); 47d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (g_scheduler->verbose_logging()) 49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) g_scheduler->Log("Writing", FilePathToUTF8(ninja_file)); 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::CreateDirectory(ninja_file.DirName()); 52d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 53d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // It's rediculously faster to write to a string and then write that to 54d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // disk in one operation than to use an fstream here. 55d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::stringstream file; 56d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Call out to the correct sub-type of writer. 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (target->output_type() == Target::COPY_FILES) { 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NinjaCopyTargetWriter writer(target, file); 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) writer.Run(); 6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else if (target->output_type() == Target::ACTION || 6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) target->output_type() == Target::ACTION_FOREACH) { 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NinjaActionTargetWriter writer(target, file); 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) writer.Run(); 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (target->output_type() == Target::GROUP) { 6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NinjaGroupTargetWriter writer(target, file); 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) writer.Run(); 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (target->output_type() == Target::EXECUTABLE || 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) target->output_type() == Target::STATIC_LIBRARY || 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) target->output_type() == Target::SHARED_LIBRARY || 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) target->output_type() == Target::SOURCE_SET) { 7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NinjaBinaryTargetWriter writer(target, file); 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) writer.Run(); 74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(0); 76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string contents = file.str(); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WriteFile(ninja_file, contents.c_str(), 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static_cast<int>(contents.size())); 81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void NinjaTargetWriter::WriteSharedVars(const SubstitutionBits& bits) { 8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool written_anything = false; 8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Target label. 8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (bits.used[SUBSTITUTION_LABEL]) { 8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) out_ << kSubstitutionNinjaNames[SUBSTITUTION_LABEL] << " = " 8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << SubstitutionWriter::GetTargetSubstitution( 9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target_, SUBSTITUTION_LABEL) 9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << std::endl; 9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) written_anything = true; 9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Root gen dir. 9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (bits.used[SUBSTITUTION_ROOT_GEN_DIR]) { 9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) out_ << kSubstitutionNinjaNames[SUBSTITUTION_ROOT_GEN_DIR] << " = " 9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << SubstitutionWriter::GetTargetSubstitution( 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target_, SUBSTITUTION_ROOT_GEN_DIR) 10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << std::endl; 10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) written_anything = true; 10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Root out dir. 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (bits.used[SUBSTITUTION_ROOT_OUT_DIR]) { 10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) out_ << kSubstitutionNinjaNames[SUBSTITUTION_ROOT_OUT_DIR] << " = " 10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << SubstitutionWriter::GetTargetSubstitution( 10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target_, SUBSTITUTION_ROOT_OUT_DIR) 10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << std::endl; 11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) written_anything = true; 11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Target gen dir. 11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (bits.used[SUBSTITUTION_TARGET_GEN_DIR]) { 11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) out_ << kSubstitutionNinjaNames[SUBSTITUTION_TARGET_GEN_DIR] << " = " 11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << SubstitutionWriter::GetTargetSubstitution( 11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target_, SUBSTITUTION_TARGET_GEN_DIR) 11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << std::endl; 11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) written_anything = true; 12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Target out dir. 12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (bits.used[SUBSTITUTION_TARGET_OUT_DIR]) { 12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) out_ << kSubstitutionNinjaNames[SUBSTITUTION_TARGET_OUT_DIR] << " = " 12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << SubstitutionWriter::GetTargetSubstitution( 12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target_, SUBSTITUTION_TARGET_OUT_DIR) 12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << std::endl; 12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) written_anything = true; 12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Target output name. 13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (bits.used[SUBSTITUTION_TARGET_OUTPUT_NAME]) { 13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) out_ << kSubstitutionNinjaNames[SUBSTITUTION_TARGET_OUTPUT_NAME] << " = " 13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << SubstitutionWriter::GetTargetSubstitution( 13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target_, SUBSTITUTION_TARGET_OUTPUT_NAME) 13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << std::endl; 13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) written_anything = true; 13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If we wrote any vars, separate them from the rest of the file that follows 14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // with a blank line. 14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (written_anything) 14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) out_ << std::endl; 14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciOutputFile NinjaTargetWriter::WriteInputDepsStampAndGetDep( 147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::vector<const Target*>& extra_hard_deps) const { 14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) CHECK(target_->toolchain()) 14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << "Toolchain not set on target " 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << target_->label().GetUserVisibleName(true); 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // For an action (where we run a script only once) the sources are the same 153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // as the source prereqs. 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool list_sources_as_input_deps = (target_->output_type() == Target::ACTION); 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Actions get implicit dependencies on the script itself. 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool add_script_source_as_dep = 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (target_->output_type() == Target::ACTION) || 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (target_->output_type() == Target::ACTION_FOREACH); 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!add_script_source_as_dep && 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extra_hard_deps.empty() && 163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) target_->inputs().empty() && 164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) target_->recursive_hard_deps().empty() && 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (!list_sources_as_input_deps || target_->sources().empty()) && 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) target_->toolchain()->deps().empty()) 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return OutputFile(); // No input/hard deps. 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // One potential optimization is if there are few input dependencies (or 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // potentially few sources that depend on these) it's better to just write 171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // all hard deps on each sources line than have this intermediate stamp. We 172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // do the stamp file because duplicating all the order-only deps for each 173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // source file can really explode the ninja file but this won't be the most 174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // optimal thing in all cases. 175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) OutputFile input_stamp_file( 17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RebaseSourceAbsolutePath(GetTargetOutputDir(target_).value(), 17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) settings_->build_settings()->build_dir())); 179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_stamp_file.value().append(target_->label().name()); 180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_stamp_file.value().append(".inputdeps.stamp"); 181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out_ << "build "; 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci path_output_.WriteFile(out_, input_stamp_file); 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out_ << ": " 18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << GetNinjaRulePrefixForToolchain(settings_) 18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << Toolchain::ToolTypeToName(Toolchain::TYPE_STAMP); 18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Script file (if applicable). 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (add_script_source_as_dep) { 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) out_ << " "; 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) path_output_.WriteFile(out_, target_->action_values().script()); 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Input files are order-only deps. 195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const Target::FileList& prereqs = target_->inputs(); 19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (size_t i = 0; i < prereqs.size(); i++) { 197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) out_ << " "; 198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) path_output_.WriteFile(out_, prereqs[i]); 19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (list_sources_as_input_deps) { 201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const Target::FileList& sources = target_->sources(); 202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (size_t i = 0; i < sources.size(); i++) { 203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) out_ << " "; 204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) path_output_.WriteFile(out_, sources[i]); 20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // The different souces of input deps may duplicate some targets, so uniquify 20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // them (ordering doesn't matter for this case). 21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::set<const Target*> unique_deps; 21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Hard dependencies that are direct or indirect dependencies. 213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::set<const Target*>& hard_deps = target_->recursive_hard_deps(); 214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (std::set<const Target*>::const_iterator i = hard_deps.begin(); 215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) i != hard_deps.end(); ++i) { 21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) unique_deps.insert(*i); 217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Extra hard dependencies passed in. 22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) unique_deps.insert(extra_hard_deps.begin(), extra_hard_deps.end()); 22103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Toolchain dependencies. These must be resolved before doing anything. 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // This just writs all toolchain deps for simplicity. If we find that 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // toolchains often have more than one dependency, we could consider writing 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // a toolchain-specific stamp file and only include the stamp here. 22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const LabelTargetVector& toolchain_deps = target_->toolchain()->deps(); 22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < toolchain_deps.size(); i++) 22803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) unique_deps.insert(toolchain_deps[i].ptr); 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (std::set<const Target*>::const_iterator i = unique_deps.begin(); 23103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) i != unique_deps.end(); ++i) { 23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(!(*i)->dependency_output_file().value().empty()); 233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) out_ << " "; 23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) path_output_.WriteFile(out_, (*i)->dependency_output_file()); 235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) out_ << "\n"; 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return input_stamp_file; 23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void NinjaTargetWriter::WriteStampForTarget( 24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::vector<OutputFile>& files, 24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::vector<OutputFile>& order_only_deps) { 24403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const OutputFile& stamp_file = target_->dependency_output_file(); 24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // First validate that the target's dependency is a stamp file. Otherwise, 24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // we shouldn't have gotten here! 24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) CHECK(EndsWith(stamp_file.value(), ".stamp", false)) 24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << "Output should end in \".stamp\" for stamp file output. Instead got: " 25003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << "\"" << stamp_file.value() << "\""; 25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) out_ << "build "; 25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) path_output_.WriteFile(out_, stamp_file); 25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) out_ << ": " 25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << GetNinjaRulePrefixForToolchain(settings_) 25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << Toolchain::ToolTypeToName(Toolchain::TYPE_STAMP); 25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) path_output_.WriteFiles(out_, files); 25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!order_only_deps.empty()) { 26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) out_ << " ||"; 26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) path_output_.WriteFiles(out_, order_only_deps); 26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) out_ << std::endl; 26503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 266