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 <iosfwd> 8 #include <map> 9 #include <memory> 10 #include <set> 11 #include <string> 12 #include <vector> 13 14 #include "cmCommonTargetGenerator.h" 15 #include "cmGeneratorTarget.h" 16 #include "cmLocalUnixMakefileGenerator3.h" 17 #include "cmOSXBundleGenerator.h" 18 19 class cmCustomCommandGenerator; 20 class cmGeneratedFileStream; 21 class cmGlobalUnixMakefileGenerator3; 22 class cmLinkLineComputer; 23 class cmOutputConverter; 24 class cmSourceFile; 25 class cmStateDirectory; 26 27 /** \class cmMakefileTargetGenerator 28 * \brief Support Routines for writing makefiles 29 * 30 */ 31 class cmMakefileTargetGenerator : public cmCommonTargetGenerator 32 { 33 public: 34 // constructor to set the ivars 35 cmMakefileTargetGenerator(cmGeneratorTarget* target); 36 cmMakefileTargetGenerator(const cmMakefileTargetGenerator&) = delete; 37 ~cmMakefileTargetGenerator() override; 38 39 cmMakefileTargetGenerator& operator=(const cmMakefileTargetGenerator&) = 40 delete; 41 42 // construct using this factory call 43 static std::unique_ptr<cmMakefileTargetGenerator> New( 44 cmGeneratorTarget* tgt); 45 46 /* the main entry point for this class. Writes the Makefiles associated 47 with this target */ 48 virtual void WriteRuleFiles() = 0; 49 50 /* return the number of actions that have progress reporting on them */ GetNumberOfProgressActions()51 virtual unsigned long GetNumberOfProgressActions() 52 { 53 return this->NumberOfProgressActions; 54 } GetProgressFileNameFull()55 std::string GetProgressFileNameFull() { return this->ProgressFileNameFull; } 56 GetGeneratorTarget()57 cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; } 58 59 std::string GetConfigName(); 60 61 protected: 62 void GetDeviceLinkFlags(std::string& linkFlags, 63 const std::string& linkLanguage); 64 void GetTargetLinkFlags(std::string& flags, const std::string& linkLanguage); 65 66 // create the file and directory etc 67 void CreateRuleFile(); 68 69 // outputs the rules for object files and custom commands used by 70 // this target 71 void WriteTargetBuildRules(); 72 73 // write some common code at the top of build.make 74 void WriteCommonCodeRules(); 75 void WriteTargetLanguageFlags(); 76 77 // write the clean rules for this target 78 void WriteTargetCleanRules(); 79 80 // write the depend rules for this target 81 void WriteTargetDependRules(); 82 83 // write rules for macOS Application Bundle content. 84 struct MacOSXContentGeneratorType 85 : cmOSXBundleGenerator::MacOSXContentGeneratorType 86 { MacOSXContentGeneratorTypeMacOSXContentGeneratorType87 MacOSXContentGeneratorType(cmMakefileTargetGenerator* gen) 88 : Generator(gen) 89 { 90 } 91 92 void operator()(cmSourceFile const& source, const char* pkgloc, 93 const std::string& config) override; 94 95 private: 96 cmMakefileTargetGenerator* Generator; 97 }; 98 friend struct MacOSXContentGeneratorType; 99 100 // write the rules for an object 101 void WriteObjectRuleFiles(cmSourceFile const& source); 102 103 // write the depend.make file for an object 104 void WriteObjectDependRules(cmSourceFile const& source, 105 std::vector<std::string>& depends); 106 107 // CUDA device linking. 108 void WriteDeviceLinkRule(std::vector<std::string>& commands, 109 const std::string& output); 110 111 // write the build rule for a custom command 112 void GenerateCustomRuleFile(cmCustomCommandGenerator const& ccg); 113 114 // write a rule to drive building of more than one output from 115 // another rule 116 void GenerateExtraOutput(const char* out, const char* in, 117 bool symbolic = false); 118 119 void MakeEchoProgress(cmLocalUnixMakefileGenerator3::EchoProgress&) const; 120 121 // write out the variable that lists the objects for this target 122 void WriteObjectsVariable(std::string& variableName, 123 std::string& variableNameExternal, 124 bool useWatcomQuote); 125 void WriteObjectsStrings(std::vector<std::string>& objStrings, 126 std::string::size_type limit = std::string::npos); 127 128 // write the driver rule to build target outputs 129 void WriteTargetDriverRule(const std::string& main_output, bool relink); 130 131 void DriveCustomCommands(std::vector<std::string>& depends); 132 133 // append intertarget dependencies 134 void AppendTargetDepends(std::vector<std::string>& depends, 135 bool ignoreType = false); 136 137 // Append object file dependencies. 138 void AppendObjectDepends(std::vector<std::string>& depends); 139 140 // Append link rule dependencies (objects, etc.). 141 void AppendLinkDepends(std::vector<std::string>& depends, 142 const std::string& linkLanguage); 143 144 // Lookup the link rule for this target. 145 std::string GetLinkRule(const std::string& linkRuleVar); 146 147 /** Create a script to hold link rules and a command to invoke the 148 script at build time. */ 149 void CreateLinkScript(const char* name, 150 std::vector<std::string> const& link_commands, 151 std::vector<std::string>& makefile_commands, 152 std::vector<std::string>& makefile_depends); 153 154 std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer( 155 cmOutputConverter* outputConverter, cmStateDirectory const& stateDir); 156 157 /** Create a response file with the given set of options. Returns 158 the relative path from the target build working directory to the 159 response file name. */ 160 std::string CreateResponseFile(const char* name, std::string const& options, 161 std::vector<std::string>& makefile_depends); 162 163 bool CheckUseResponseFileForObjects(std::string const& l) const; 164 bool CheckUseResponseFileForLibraries(std::string const& l) const; 165 166 /** Create list of flags for link libraries. */ 167 void CreateLinkLibs(cmLinkLineComputer* linkLineComputer, 168 std::string& linkLibs, bool useResponseFile, 169 std::vector<std::string>& makefile_depends); 170 171 /** Create lists of object files for linking and cleaning. */ 172 void CreateObjectLists(bool useLinkScript, bool useArchiveRules, 173 bool useResponseFile, std::string& buildObjs, 174 std::vector<std::string>& makefile_depends, 175 bool useWatcomQuote); 176 177 /** Add commands for generate def files */ 178 void GenDefFile(std::vector<std::string>& real_link_commands); 179 180 void AddIncludeFlags(std::string& flags, const std::string& lang, 181 const std::string& config) override; 182 183 virtual void CloseFileStreams(); 184 cmLocalUnixMakefileGenerator3* LocalGenerator; 185 cmGlobalUnixMakefileGenerator3* GlobalGenerator; 186 187 enum CustomCommandDriveType 188 { 189 OnBuild, 190 OnDepends, 191 OnUtility 192 }; 193 CustomCommandDriveType CustomCommandDriver; 194 195 // the full path to the build file 196 std::string BuildFileName; 197 std::string BuildFileNameFull; 198 199 // the full path to the progress file 200 std::string ProgressFileNameFull; 201 unsigned long NumberOfProgressActions; 202 bool NoRuleMessages; 203 204 bool CMP0113New = false; 205 206 // the path to the directory the build file is in 207 std::string TargetBuildDirectory; 208 std::string TargetBuildDirectoryFull; 209 210 // the stream for the build file 211 std::unique_ptr<cmGeneratedFileStream> BuildFileStream; 212 213 // the stream for the flag file 214 std::string FlagFileNameFull; 215 std::unique_ptr<cmGeneratedFileStream> FlagFileStream; 216 class StringList : public std::vector<std::string> 217 { 218 }; 219 std::map<std::string, StringList> FlagFileDepends; 220 221 // the stream for the info file 222 std::string InfoFileNameFull; 223 std::unique_ptr<cmGeneratedFileStream> InfoFileStream; 224 225 // files to clean 226 std::set<std::string> CleanFiles; 227 228 // objects used by this target 229 std::vector<std::string> Objects; 230 std::vector<std::string> ExternalObjects; 231 232 // Set of object file names that will be built in this directory. 233 std::set<std::string> ObjectFiles; 234 235 // Set of extra output files to be driven by the build. 236 std::set<std::string> ExtraFiles; 237 238 // Set of custom command output files to be driven by the build. 239 std::set<std::string> CustomCommandOutputs; 240 241 using MultipleOutputPairsType = std::map<std::string, std::string>; 242 MultipleOutputPairsType MultipleOutputPairs; 243 bool WriteMakeRule(std::ostream& os, const char* comment, 244 const std::vector<std::string>& outputs, 245 const std::vector<std::string>& depends, 246 const std::vector<std::string>& commands, 247 bool in_help = false); 248 249 // Target name info. 250 cmGeneratorTarget::Names TargetNames; 251 252 // macOS content info. 253 std::set<std::string> MacContentFolders; 254 std::unique_ptr<cmOSXBundleGenerator> OSXBundleGenerator; 255 std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator; 256 }; 257