1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 file Copyright.txt or https://cmake.org/licensing for details. */ 3 #pragma once 4 5 #include "cmConfigure.h" // IWYU pragma: keep 6 7 #include <map> 8 #include <memory> 9 #include <set> 10 #include <string> 11 #include <utility> 12 #include <vector> 13 14 #include <cm3p/json/value.h> 15 16 #include "cmCommonTargetGenerator.h" 17 #include "cmGlobalNinjaGenerator.h" 18 #include "cmNinjaTypes.h" 19 #include "cmOSXBundleGenerator.h" 20 21 class cmCustomCommand; 22 class cmGeneratedFileStream; 23 class cmGeneratorTarget; 24 class cmLocalNinjaGenerator; 25 class cmMakefile; 26 class cmSourceFile; 27 28 class cmNinjaTargetGenerator : public cmCommonTargetGenerator 29 { 30 public: 31 /// Create a cmNinjaTargetGenerator according to the @a target's type. 32 static std::unique_ptr<cmNinjaTargetGenerator> New( 33 cmGeneratorTarget* target); 34 35 /// Build a NinjaTargetGenerator. 36 cmNinjaTargetGenerator(cmGeneratorTarget* target); 37 38 /// Destructor. 39 ~cmNinjaTargetGenerator() override; 40 41 virtual void Generate(const std::string& config) = 0; 42 43 std::string GetTargetName() const; 44 45 protected: 46 bool SetMsvcTargetPdbVariable(cmNinjaVars&, const std::string& config) const; 47 48 cmGeneratedFileStream& GetImplFileStream(const std::string& config) const; 49 cmGeneratedFileStream& GetCommonFileStream() const; 50 cmGeneratedFileStream& GetRulesFileStream() const; 51 GetGeneratorTarget()52 cmGeneratorTarget* GetGeneratorTarget() const 53 { 54 return this->GeneratorTarget; 55 } 56 GetLocalGenerator()57 cmLocalNinjaGenerator* GetLocalGenerator() const 58 { 59 return this->LocalGenerator; 60 } 61 62 cmGlobalNinjaGenerator* GetGlobalGenerator() const; 63 GetMakefile()64 cmMakefile* GetMakefile() const { return this->Makefile; } 65 66 std::string LanguageCompilerRule(const std::string& lang, 67 const std::string& config) const; 68 std::string LanguagePreprocessAndScanRule(std::string const& lang, 69 const std::string& config) const; 70 std::string LanguageScanRule(std::string const& lang, 71 const std::string& config) const; 72 std::string LanguageDyndepRule(std::string const& lang, 73 const std::string& config) const; 74 bool NeedDyndep(std::string const& lang, std::string const& config) const; 75 bool NeedExplicitPreprocessing(std::string const& lang) const; 76 bool CompileWithDefines(std::string const& lang) const; 77 bool NeedCxxModuleSupport(std::string const& lang, 78 std::string const& config) const; 79 80 std::string OrderDependsTargetForTarget(const std::string& config); 81 82 std::string ComputeOrderDependsForTarget(); 83 84 /** 85 * Compute the flags for compilation of object files for a given @a language. 86 * @note Generally it is the value of the variable whose name is computed 87 * by LanguageFlagsVarName(). 88 */ 89 std::string ComputeFlagsForObject(cmSourceFile const* source, 90 const std::string& language, 91 const std::string& config); 92 93 void AddIncludeFlags(std::string& flags, std::string const& lang, 94 const std::string& config) override; 95 96 std::string ComputeDefines(cmSourceFile const* source, 97 const std::string& language, 98 const std::string& config); 99 100 std::string ComputeIncludes(cmSourceFile const* source, 101 const std::string& language, 102 const std::string& config); 103 ConvertToNinjaPath(const std::string & path)104 std::string const& ConvertToNinjaPath(const std::string& path) const 105 { 106 return this->GetGlobalGenerator()->ConvertToNinjaPath(path); 107 } MapToNinjaPath()108 cmGlobalNinjaGenerator::MapToNinjaPathImpl MapToNinjaPath() const 109 { 110 return this->GetGlobalGenerator()->MapToNinjaPath(); 111 } 112 ConvertToNinjaAbsPath(std::string path)113 std::string ConvertToNinjaAbsPath(std::string path) const 114 { 115 return this->GetGlobalGenerator()->ConvertToNinjaAbsPath(std::move(path)); 116 } 117 118 /// @return the list of link dependency for the given target @a target. 119 cmNinjaDeps ComputeLinkDeps(const std::string& linkLanguage, 120 const std::string& config, 121 bool ignoreType = false) const; 122 123 /// @return the source file path for the given @a source. 124 std::string GetCompiledSourceNinjaPath(cmSourceFile const* source) const; 125 126 /// @return the object file path for the given @a source. 127 std::string GetObjectFilePath(cmSourceFile const* source, 128 const std::string& config) const; 129 130 /// @return the preprocessed source file path for the given @a source. 131 std::string GetPreprocessedFilePath(cmSourceFile const* source, 132 const std::string& config) const; 133 134 /// @return the dyndep file path for this target. 135 std::string GetDyndepFilePath(std::string const& lang, 136 const std::string& config) const; 137 138 /// @return the target dependency scanner info file path 139 std::string GetTargetDependInfoPath(std::string const& lang, 140 const std::string& config) const; 141 142 /// @return the file path where the target named @a name is generated. 143 std::string GetTargetFilePath(const std::string& name, 144 const std::string& config) const; 145 146 /// @return the output path for the target. 147 virtual std::string GetTargetOutputDir(const std::string& config) const; 148 149 void WriteLanguageRules(const std::string& language, 150 const std::string& config); 151 void WriteCompileRule(const std::string& language, 152 const std::string& config); 153 void WriteObjectBuildStatements(const std::string& config, 154 const std::string& fileConfig, 155 bool firstForConfig); 156 void WriteObjectBuildStatement(cmSourceFile const* source, 157 const std::string& config, 158 const std::string& fileConfig, 159 bool firstForConfig); 160 void WriteTargetDependInfo(std::string const& lang, 161 const std::string& config); 162 163 void EmitSwiftDependencyInfo(cmSourceFile const* source, 164 const std::string& config); 165 166 void ExportObjectCompileCommand( 167 std::string const& language, std::string const& sourceFileName, 168 std::string const& objectDir, std::string const& objectFileName, 169 std::string const& objectFileDir, std::string const& flags, 170 std::string const& defines, std::string const& includes, 171 std::string const& outputConfig); 172 173 void AdditionalCleanFiles(const std::string& config); 174 175 cmNinjaDeps GetObjects(const std::string& config) const; 176 177 void EnsureDirectoryExists(const std::string& dir) const; 178 void EnsureParentDirectoryExists(const std::string& path) const; 179 180 // write rules for macOS Application Bundle content. 181 struct MacOSXContentGeneratorType 182 : cmOSXBundleGenerator::MacOSXContentGeneratorType 183 { MacOSXContentGeneratorTypeMacOSXContentGeneratorType184 MacOSXContentGeneratorType(cmNinjaTargetGenerator* g, 185 std::string fileConfig) 186 : Generator(g) 187 , FileConfig(std::move(fileConfig)) 188 { 189 } 190 191 void operator()(cmSourceFile const& source, const char* pkgloc, 192 const std::string& config) override; 193 194 private: 195 cmNinjaTargetGenerator* Generator; 196 std::string FileConfig; 197 }; 198 friend struct MacOSXContentGeneratorType; 199 200 // Properly initialized by sub-classes. 201 std::unique_ptr<cmOSXBundleGenerator> OSXBundleGenerator; 202 std::set<std::string> MacContentFolders; 203 204 void addPoolNinjaVariable(const std::string& pool_property, 205 cmGeneratorTarget* target, cmNinjaVars& vars); 206 207 bool ForceResponseFile(); 208 209 private: 210 cmLocalNinjaGenerator* LocalGenerator; 211 212 struct ByConfig 213 { 214 /// List of object files for this target. 215 cmNinjaDeps Objects; 216 // Fortran Support 217 std::map<std::string, cmNinjaDeps> DDIFiles; 218 // Swift Support 219 Json::Value SwiftOutputMap; 220 std::vector<cmCustomCommand const*> CustomCommands; 221 cmNinjaDeps ExtraFiles; 222 std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator; 223 }; 224 225 std::map<std::string, ByConfig> Configs; 226 }; 227