cmQtAutoGenerator.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #ifndef cmQtAutoGenerator_h
  4. #define cmQtAutoGenerator_h
  5. #include "cmConfigure.h" // IWYU pragma: keep
  6. #include "cmFilePathChecksum.h"
  7. #include "cmQtAutoGen.h"
  8. #include "cmUVHandlePtr.h"
  9. #include "cmUVSignalHackRAII.h" // IWYU pragma: keep
  10. #include "cm_uv.h"
  11. #include <array>
  12. #include <functional>
  13. #include <mutex>
  14. #include <stddef.h>
  15. #include <stdint.h>
  16. #include <string>
  17. #include <vector>
  18. class cmMakefile;
  19. /// @brief Base class for QtAutoGen gernerators
  20. class cmQtAutoGenerator : public cmQtAutoGen
  21. {
  22. public:
  23. // -- Types
  24. /// @brief Thread safe logging
  25. class Logger
  26. {
  27. public:
  28. // -- Verbosity
  29. unsigned int Verbosity() const { return this->Verbosity_; }
  30. void SetVerbosity(unsigned int value) { this->Verbosity_ = value; }
  31. void RaiseVerbosity(std::string const& value);
  32. bool Verbose() const { return (this->Verbosity_ != 0); }
  33. void SetVerbose(bool value) { this->Verbosity_ = value ? 1 : 0; }
  34. bool ColorOutput() const { return this->ColorOutput_; }
  35. void SetColorOutput(bool value);
  36. // -- Log info
  37. void Info(GeneratorT genType, std::string const& message);
  38. // -- Log warning
  39. void Warning(GeneratorT genType, std::string const& message);
  40. void WarningFile(GeneratorT genType, std::string const& filename,
  41. std::string const& message);
  42. // -- Log error
  43. void Error(GeneratorT genType, std::string const& message);
  44. void ErrorFile(GeneratorT genType, std::string const& filename,
  45. std::string const& message);
  46. void ErrorCommand(GeneratorT genType, std::string const& message,
  47. std::vector<std::string> const& command,
  48. std::string const& output);
  49. private:
  50. static std::string HeadLine(std::string const& title);
  51. private:
  52. std::mutex Mutex_;
  53. unsigned int Verbosity_ = 0;
  54. bool ColorOutput_ = false;
  55. };
  56. /// @brief Thread safe file system interface
  57. class FileSystem
  58. {
  59. public:
  60. FileSystem(Logger* log)
  61. : Log_(log)
  62. {
  63. }
  64. /// @brief Logger
  65. Logger* Log() const { return Log_; }
  66. // -- Paths
  67. /// @brief Wrapper for cmSystemTools::GetRealPath
  68. std::string GetRealPath(std::string const& filename);
  69. /// @brief Wrapper for cmSystemTools::CollapseCombinedPath
  70. std::string CollapseCombinedPath(std::string const& dir,
  71. std::string const& file);
  72. /// @brief Wrapper for cmSystemTools::SplitPath
  73. void SplitPath(const std::string& p, std::vector<std::string>& components,
  74. bool expand_home_dir = true);
  75. /// @brief Wrapper for cmSystemTools::JoinPath
  76. std::string JoinPath(const std::vector<std::string>& components);
  77. /// @brief Wrapper for cmSystemTools::JoinPath
  78. std::string JoinPath(std::vector<std::string>::const_iterator first,
  79. std::vector<std::string>::const_iterator last);
  80. /// @brief Wrapper for cmSystemTools::GetFilenameWithoutLastExtension
  81. std::string GetFilenameWithoutLastExtension(const std::string& filename);
  82. /// @brief Wrapper for cmQtAutoGen::SubDirPrefix
  83. std::string SubDirPrefix(std::string const& filename);
  84. /// @brief Wrapper for cmFilePathChecksum::setupParentDirs
  85. void setupFilePathChecksum(std::string const& currentSrcDir,
  86. std::string const& currentBinDir,
  87. std::string const& projectSrcDir,
  88. std::string const& projectBinDir);
  89. /// @brief Wrapper for cmFilePathChecksum::getPart
  90. std::string GetFilePathChecksum(std::string const& filename);
  91. // -- File access
  92. /// @brief Wrapper for cmSystemTools::FileExists
  93. bool FileExists(std::string const& filename);
  94. /// @brief Wrapper for cmSystemTools::FileExists
  95. bool FileExists(std::string const& filename, bool isFile);
  96. /// @brief Wrapper for cmSystemTools::FileLength
  97. unsigned long FileLength(std::string const& filename);
  98. bool FileIsOlderThan(std::string const& buildFile,
  99. std::string const& sourceFile,
  100. std::string* error = nullptr);
  101. bool FileRead(std::string& content, std::string const& filename,
  102. std::string* error = nullptr);
  103. /// @brief Error logging version
  104. bool FileRead(GeneratorT genType, std::string& content,
  105. std::string const& filename);
  106. bool FileWrite(std::string const& filename, std::string const& content,
  107. std::string* error = nullptr);
  108. /// @brief Error logging version
  109. bool FileWrite(GeneratorT genType, std::string const& filename,
  110. std::string const& content);
  111. bool FileDiffers(std::string const& filename, std::string const& content);
  112. bool FileRemove(std::string const& filename);
  113. bool Touch(std::string const& filename, bool create = false);
  114. // -- Directory access
  115. bool MakeDirectory(std::string const& dirname);
  116. /// @brief Error logging version
  117. bool MakeDirectory(GeneratorT genType, std::string const& dirname);
  118. bool MakeParentDirectory(std::string const& filename);
  119. /// @brief Error logging version
  120. bool MakeParentDirectory(GeneratorT genType, std::string const& filename);
  121. private:
  122. std::mutex Mutex_;
  123. cmFilePathChecksum FilePathChecksum_;
  124. Logger* Log_;
  125. };
  126. /// @brief Return value and output of an external process
  127. struct ProcessResultT
  128. {
  129. void reset();
  130. bool error() const
  131. {
  132. return (ExitStatus != 0) || (TermSignal != 0) || !ErrorMessage.empty();
  133. }
  134. std::int64_t ExitStatus = 0;
  135. int TermSignal = 0;
  136. std::string StdOut;
  137. std::string StdErr;
  138. std::string ErrorMessage;
  139. };
  140. /// @brief External process management class
  141. struct ReadOnlyProcessT
  142. {
  143. // -- Types
  144. /// @brief libuv pipe buffer class
  145. class PipeT
  146. {
  147. public:
  148. int init(uv_loop_t* uv_loop, ReadOnlyProcessT* process);
  149. int startRead(std::string* target);
  150. void reset();
  151. // -- Libuv casts
  152. uv_pipe_t* uv_pipe() { return UVPipe_.get(); }
  153. uv_stream_t* uv_stream()
  154. {
  155. return reinterpret_cast<uv_stream_t*>(uv_pipe());
  156. }
  157. uv_handle_t* uv_handle()
  158. {
  159. return reinterpret_cast<uv_handle_t*>(uv_pipe());
  160. }
  161. // -- Libuv callbacks
  162. static void UVAlloc(uv_handle_t* handle, size_t suggestedSize,
  163. uv_buf_t* buf);
  164. static void UVData(uv_stream_t* stream, ssize_t nread,
  165. const uv_buf_t* buf);
  166. private:
  167. ReadOnlyProcessT* Process_ = nullptr;
  168. std::string* Target_ = nullptr;
  169. std::vector<char> Buffer_;
  170. cm::uv_pipe_ptr UVPipe_;
  171. };
  172. /// @brief Process settings
  173. struct SetupT
  174. {
  175. std::string WorkingDirectory;
  176. std::vector<std::string> Command;
  177. ProcessResultT* Result = nullptr;
  178. bool MergedOutput = false;
  179. };
  180. // -- Const accessors
  181. const SetupT& Setup() const { return Setup_; }
  182. ProcessResultT* Result() const { return Setup_.Result; }
  183. bool IsStarted() const { return IsStarted_; }
  184. bool IsFinished() const { return IsFinished_; }
  185. // -- Runtime
  186. void setup(ProcessResultT* result, bool mergedOutput,
  187. std::vector<std::string> const& command,
  188. std::string const& workingDirectory = std::string());
  189. bool start(uv_loop_t* uv_loop, std::function<void()>&& finishedCallback);
  190. private:
  191. // -- Friends
  192. friend class PipeT;
  193. // -- Libuv callbacks
  194. static void UVExit(uv_process_t* handle, int64_t exitStatus,
  195. int termSignal);
  196. void UVTryFinish();
  197. // -- Setup
  198. SetupT Setup_;
  199. // -- Runtime
  200. bool IsStarted_ = false;
  201. bool IsFinished_ = false;
  202. std::function<void()> FinishedCallback_;
  203. std::vector<const char*> CommandPtr_;
  204. std::array<uv_stdio_container_t, 3> UVOptionsStdIO_;
  205. uv_process_options_t UVOptions_;
  206. cm::uv_process_ptr UVProcess_;
  207. PipeT UVPipeOut_;
  208. PipeT UVPipeErr_;
  209. };
  210. public:
  211. // -- Constructors
  212. cmQtAutoGenerator();
  213. virtual ~cmQtAutoGenerator();
  214. cmQtAutoGenerator(cmQtAutoGenerator const&) = delete;
  215. cmQtAutoGenerator& operator=(cmQtAutoGenerator const&) = delete;
  216. // -- Run
  217. bool Run(std::string const& infoFile, std::string const& config);
  218. // -- Accessors
  219. // Logging
  220. Logger& Log() { return Logger_; }
  221. // File System
  222. FileSystem& FileSys() { return FileSys_; }
  223. // InfoFile
  224. std::string const& InfoFile() const { return InfoFile_; }
  225. std::string const& InfoDir() const { return InfoDir_; }
  226. std::string const& InfoConfig() const { return InfoConfig_; }
  227. // libuv loop
  228. uv_loop_t* UVLoop() { return UVLoop_.get(); }
  229. cm::uv_async_ptr& UVRequest() { return UVRequest_; }
  230. // -- Utility
  231. static std::string SettingsFind(std::string const& content, const char* key);
  232. protected:
  233. // -- Abstract processing interface
  234. virtual bool Init(cmMakefile* makefile) = 0;
  235. virtual bool Process() = 0;
  236. private:
  237. // -- Logging
  238. Logger Logger_;
  239. FileSystem FileSys_;
  240. // -- Info settings
  241. std::string InfoFile_;
  242. std::string InfoDir_;
  243. std::string InfoConfig_;
  244. // -- libuv loop
  245. #ifdef CMAKE_UV_SIGNAL_HACK
  246. std::unique_ptr<cmUVSignalHackRAII> UVHackRAII_;
  247. #endif
  248. std::unique_ptr<uv_loop_t> UVLoop_;
  249. cm::uv_async_ptr UVRequest_;
  250. };
  251. #endif