cmQtAutoGenerator.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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 "cmQtAutoGen.h"
  7. #include "cmUVHandlePtr.h"
  8. #include "cmUVSignalHackRAII.h" // IWYU pragma: keep
  9. #include "cm_uv.h"
  10. #include <array>
  11. #include <functional>
  12. #include <mutex>
  13. #include <stddef.h>
  14. #include <stdint.h>
  15. #include <string>
  16. #include <vector>
  17. class cmMakefile;
  18. /// @brief Base class for QtAutoGen gernerators
  19. class cmQtAutoGenerator : public cmQtAutoGen
  20. {
  21. CM_DISABLE_COPY(cmQtAutoGenerator)
  22. public:
  23. // -- Types
  24. /// @brief Thread safe logging
  25. class Logger
  26. {
  27. public:
  28. // -- Verbosity
  29. bool Verbose() const { return this->Verbose_; }
  30. void SetVerbose(bool value);
  31. bool ColorOutput() const { return this->ColorOutput_; }
  32. void SetColorOutput(bool value);
  33. // -- Log info
  34. void Info(GeneratorT genType, std::string const& message);
  35. // -- Log warning
  36. void Warning(GeneratorT genType, std::string const& message);
  37. void WarningFile(GeneratorT genType, std::string const& filename,
  38. std::string const& message);
  39. // -- Log error
  40. void Error(GeneratorT genType, std::string const& message);
  41. void ErrorFile(GeneratorT genType, std::string const& filename,
  42. std::string const& message);
  43. void ErrorCommand(GeneratorT genType, std::string const& message,
  44. std::vector<std::string> const& command,
  45. std::string const& output);
  46. private:
  47. static std::string HeadLine(std::string const& title);
  48. private:
  49. std::mutex Mutex_;
  50. bool volatile Verbose_ = false;
  51. bool volatile ColorOutput_ = false;
  52. };
  53. /// @brief Thread safe file system interface
  54. class FileSystem
  55. {
  56. public:
  57. FileSystem(Logger* log)
  58. : Log_(log)
  59. {
  60. }
  61. Logger* Log() const { return Log_; }
  62. std::string RealPath(std::string const& filename);
  63. bool FileExists(std::string const& filename);
  64. bool FileIsOlderThan(std::string const& buildFile,
  65. std::string const& sourceFile,
  66. std::string* error = nullptr);
  67. bool FileRead(std::string& content, std::string const& filename,
  68. std::string* error = nullptr);
  69. /// @brief Error logging version
  70. bool FileRead(GeneratorT genType, std::string& content,
  71. std::string const& filename);
  72. bool FileWrite(std::string const& filename, std::string const& content,
  73. std::string* error = nullptr);
  74. /// @brief Error logging version
  75. bool FileWrite(GeneratorT genType, std::string const& filename,
  76. std::string const& content);
  77. bool FileDiffers(std::string const& filename, std::string const& content);
  78. bool FileRemove(std::string const& filename);
  79. bool Touch(std::string const& filename);
  80. bool MakeDirectory(std::string const& dirname);
  81. /// @brief Error logging version
  82. bool MakeDirectory(GeneratorT genType, std::string const& dirname);
  83. bool MakeParentDirectory(std::string const& filename);
  84. /// @brief Error logging version
  85. bool MakeParentDirectory(GeneratorT genType, std::string const& filename);
  86. private:
  87. std::mutex Mutex_;
  88. Logger* Log_;
  89. };
  90. /// @brief Return value and output of an external process
  91. struct ProcessResultT
  92. {
  93. void reset();
  94. bool error() const
  95. {
  96. return (ExitStatus != 0) || (TermSignal != 0) || !ErrorMessage.empty();
  97. }
  98. std::int64_t ExitStatus = 0;
  99. int TermSignal = 0;
  100. std::string StdOut;
  101. std::string StdErr;
  102. std::string ErrorMessage;
  103. };
  104. /// @brief External process management class
  105. struct ReadOnlyProcessT
  106. {
  107. // -- Types
  108. /// @brief libuv pipe buffer class
  109. class PipeT
  110. {
  111. public:
  112. int init(uv_loop_t* uv_loop, ReadOnlyProcessT* process);
  113. int startRead(std::string* target);
  114. void reset();
  115. // -- Libuv casts
  116. uv_pipe_t* uv_pipe() { return UVPipe_.get(); }
  117. uv_stream_t* uv_stream()
  118. {
  119. return reinterpret_cast<uv_stream_t*>(uv_pipe());
  120. }
  121. uv_handle_t* uv_handle()
  122. {
  123. return reinterpret_cast<uv_handle_t*>(uv_pipe());
  124. }
  125. // -- Libuv callbacks
  126. static void UVAlloc(uv_handle_t* handle, size_t suggestedSize,
  127. uv_buf_t* buf);
  128. static void UVData(uv_stream_t* stream, ssize_t nread,
  129. const uv_buf_t* buf);
  130. private:
  131. ReadOnlyProcessT* Process_ = nullptr;
  132. std::string* Target_ = nullptr;
  133. std::vector<char> Buffer_;
  134. cm::uv_pipe_ptr UVPipe_;
  135. };
  136. /// @brief Process settings
  137. struct SetupT
  138. {
  139. std::string WorkingDirectory;
  140. std::vector<std::string> Command;
  141. ProcessResultT* Result = nullptr;
  142. bool MergedOutput = false;
  143. };
  144. // -- Constructor
  145. ReadOnlyProcessT() = default;
  146. // -- Const accessors
  147. const SetupT& Setup() const { return Setup_; }
  148. ProcessResultT* Result() const { return Setup_.Result; }
  149. bool IsStarted() const { return IsStarted_; }
  150. bool IsFinished() const { return IsFinished_; }
  151. // -- Runtime
  152. void setup(ProcessResultT* result, bool mergedOutput,
  153. std::vector<std::string> const& command,
  154. std::string const& workingDirectory = std::string());
  155. bool start(uv_loop_t* uv_loop, std::function<void()>&& finishedCallback);
  156. private:
  157. // -- Friends
  158. friend class PipeT;
  159. // -- Libuv callbacks
  160. static void UVExit(uv_process_t* handle, int64_t exitStatus,
  161. int termSignal);
  162. void UVTryFinish();
  163. // -- Setup
  164. SetupT Setup_;
  165. // -- Runtime
  166. bool IsStarted_ = false;
  167. bool IsFinished_ = false;
  168. std::function<void()> FinishedCallback_;
  169. std::vector<const char*> CommandPtr_;
  170. std::array<uv_stdio_container_t, 3> UVOptionsStdIO_;
  171. uv_process_options_t UVOptions_;
  172. cm::uv_process_ptr UVProcess_;
  173. PipeT UVPipeOut_;
  174. PipeT UVPipeErr_;
  175. };
  176. public:
  177. // -- Constructors
  178. cmQtAutoGenerator();
  179. virtual ~cmQtAutoGenerator();
  180. // -- Run
  181. bool Run(std::string const& infoFile, std::string const& config);
  182. // -- Accessors
  183. // Logging
  184. Logger& Log() { return Logger_; }
  185. // File System
  186. FileSystem& FileSys() { return FileSys_; }
  187. // InfoFile
  188. std::string const& InfoFile() const { return InfoFile_; }
  189. std::string const& InfoDir() const { return InfoDir_; }
  190. std::string const& InfoConfig() const { return InfoConfig_; }
  191. // libuv loop
  192. uv_loop_t* UVLoop() { return UVLoop_.get(); }
  193. cm::uv_async_ptr& UVRequest() { return UVRequest_; }
  194. // -- Utility
  195. static std::string SettingsFind(std::string const& content, const char* key);
  196. protected:
  197. // -- Abstract processing interface
  198. virtual bool Init(cmMakefile* makefile) = 0;
  199. virtual bool Process() = 0;
  200. private:
  201. // -- Logging
  202. Logger Logger_;
  203. FileSystem FileSys_;
  204. // -- Info settings
  205. std::string InfoFile_;
  206. std::string InfoDir_;
  207. std::string InfoConfig_;
  208. // -- libuv loop
  209. #ifdef CMAKE_UV_SIGNAL_HACK
  210. std::unique_ptr<cmUVSignalHackRAII> UVHackRAII_;
  211. #endif
  212. std::unique_ptr<uv_loop_t> UVLoop_;
  213. cm::uv_async_ptr UVRequest_;
  214. };
  215. #endif