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 #ifndef TOOLS_GN_NINJA_TARGET_WRITER_H_ 6 #define TOOLS_GN_NINJA_TARGET_WRITER_H_ 7 8 #include <iosfwd> 9 10 #include "gn/path_output.h" 11 #include "gn/resolved_target_data.h" 12 #include "gn/substitution_type.h" 13 14 class OutputFile; 15 class Settings; 16 class Target; 17 struct SubstitutionBits; 18 19 // Generates one target's ".ninja" file. The toplevel "build.ninja" file is 20 // generated by the NinjaBuildWriter. 21 class NinjaTargetWriter { 22 public: 23 NinjaTargetWriter(const Target* target, std::ostream& out); 24 virtual ~NinjaTargetWriter(); 25 26 // Returns a ResolvedTargetData that can be used to retrieve information 27 // from targets. The instance can be set through SetResolvedTargetData() 28 // or may be created on demand otherwise (which is useful to keep unit-tests 29 // simple). 30 const ResolvedTargetData& resolved() const; 31 32 // Sets the ResolvedTargetData instance to return for future resolved() 33 // calls. Does not transfer ownership, and allows several NinjaTargetWriter 34 // instances to share the same cached information. 35 void SetResolvedTargetData(ResolvedTargetData* resolved); 36 37 // Set the vector that will receive the Ninja output file paths generated 38 // by this writer. A nullptr value means no output files needs to be 39 // collected. 40 void SetNinjaOutputs(std::vector<OutputFile>* ninja_outputs); 41 42 // Returns the build line to be written to the toolchain build file. 43 // 44 // Some targets have their rules written to separate files, and some can have 45 // their rules coalesced in the main build file. For the coalesced case, this 46 // function will return the rules as a string. For the separate file case, 47 // the separate ninja file will be written and the return string will be the 48 // subninja command to load that file. 49 // 50 // If |ninja_outputs| is not nullptr, it will be set with the list of 51 // Ninja output paths generated by the corresponding writer. 52 static std::string RunAndWriteFile( 53 const Target* target, 54 ResolvedTargetData* resolved = nullptr, 55 std::vector<OutputFile>* ninja_outputs = nullptr); 56 57 virtual void Run() = 0; 58 59 protected: 60 // Returns a writable pointer to resolved(). Only used internally. 61 ResolvedTargetData* GetResolvedTargetData(); 62 63 // Writes out the substitution values that are shared between the different 64 // types of tools (target gen dir, target label, etc.). Only the substitutions 65 // identified by the given bits will be written. 66 void WriteSharedVars(const SubstitutionBits& bits); 67 68 // Writes out the substitution values that are shared between C compiler tools 69 // and action tools. Only the substitutions identified by the given bits will 70 // be written. 71 // If respect_source_used is set, the generated substitution values will 72 // respect the types of source code used; otherwise they will respect the bits 73 // passed in. 74 void WriteCCompilerVars(const SubstitutionBits& bits, 75 bool indent, 76 bool respect_source_used); 77 78 // Writes out the substitution values that are shared between Rust tools 79 // and action tools. Only the substitutions identified by the given bits will 80 // be written, unless 'always_write' is specified. 81 void WriteRustCompilerVars(const SubstitutionBits& bits, 82 bool indent, 83 bool always_write); 84 85 // Writes to the output stream a stamp rule for input dependencies, and 86 // returns the file to be appended to source rules that encodes the 87 // order-only dependencies for the current target. 88 // If num_stamp_uses is small, this might return all input dependencies 89 // directly, without writing a stamp file. 90 // If there are no implicit dependencies and no additional target dependencies 91 // are passed in, this returns an empty vector. 92 std::vector<OutputFile> WriteInputDepsStampAndGetDep( 93 const std::vector<const Target*>& additional_hard_deps, 94 size_t num_stamp_uses) const; 95 96 // Writes to the output file a final stamp rule for the target that stamps 97 // the given list of files. This function assumes the stamp is for the target 98 // as a whole so the stamp file is set as the target's dependency output. 99 void WriteStampForTarget(const std::vector<OutputFile>& deps, 100 const std::vector<OutputFile>& order_only_deps); 101 102 const Settings* settings_; // Non-owning. 103 const Target* target_; // Non-owning. 104 std::ostream& out_; 105 PathOutput path_output_; 106 107 // Write a Ninja output file to out_, and also add it to |*ninja_outputs_| 108 // if needed. 109 void WriteOutput(const OutputFile& output) const; 110 void WriteOutput(OutputFile&& output) const; 111 112 // Same as WriteOutput() for a list of Ninja output file paths. 113 void WriteOutputs(const std::vector<OutputFile>& outputs) const; 114 void WriteOutputs(std::vector<OutputFile>&& outputs) const; 115 116 // The list of all Ninja output file paths generated by this writer for 117 // this target. Used to implement the --ide=ninja_outputs `gn gen` flag. 118 // Needs to be mutable because WriteOutput() and WriteOutputs() need to 119 // be const. 120 mutable std::vector<OutputFile>* ninja_outputs_ = nullptr; 121 122 // The ResolvedTargetData instance can be set through SetResolvedTargetData() 123 // or it will be created lazily when resolved() is called, hence the need 124 // for 'mutable' here. 125 mutable ResolvedTargetData* resolved_ptr_ = nullptr; 126 mutable std::unique_ptr<ResolvedTargetData> resolved_owned_; 127 128 private: 129 void WriteCopyRules(); 130 void WriteEscapedSubstitution(const Substitution* type); 131 132 NinjaTargetWriter(const NinjaTargetWriter&) = delete; 133 NinjaTargetWriter& operator=(const NinjaTargetWriter&) = delete; 134 }; 135 136 #endif // TOOLS_GN_NINJA_TARGET_WRITER_H_ 137