cmQtAutoMocUic.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  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 cmQtAutoMocUic_h
  4. #define cmQtAutoMocUic_h
  5. #include "cmConfigure.h" // IWYU pragma: keep
  6. #include "cmFileTime.h"
  7. #include "cmQtAutoGen.h"
  8. #include "cmQtAutoGenerator.h"
  9. #include "cmWorkerPool.h"
  10. #include "cmsys/RegularExpression.hxx"
  11. #include <atomic>
  12. #include <cstddef>
  13. #include <map>
  14. #include <memory>
  15. #include <set>
  16. #include <string>
  17. #include <unordered_map>
  18. #include <unordered_set>
  19. #include <utility>
  20. #include <vector>
  21. class cmMakefile;
  22. /** \class cmQtAutoMocUic
  23. * \brief AUTOMOC and AUTOUIC generator
  24. */
  25. class cmQtAutoMocUic : public cmQtAutoGenerator
  26. {
  27. public:
  28. cmQtAutoMocUic();
  29. ~cmQtAutoMocUic() override;
  30. cmQtAutoMocUic(cmQtAutoMocUic const&) = delete;
  31. cmQtAutoMocUic& operator=(cmQtAutoMocUic const&) = delete;
  32. public:
  33. // -- Types
  34. /**
  35. * Search key plus regular expression pair
  36. */
  37. struct KeyExpT
  38. {
  39. KeyExpT() = default;
  40. KeyExpT(const char* key, const char* exp)
  41. : Key(key)
  42. , Exp(exp)
  43. {
  44. }
  45. KeyExpT(std::string key, std::string const& exp)
  46. : Key(std::move(key))
  47. , Exp(exp)
  48. {
  49. }
  50. std::string Key;
  51. cmsys::RegularExpression Exp;
  52. };
  53. /**
  54. * Include string with sub parts
  55. */
  56. struct IncludeKeyT
  57. {
  58. IncludeKeyT(std::string const& key, std::size_t basePrefixLength);
  59. std::string Key; // Full include string
  60. std::string Dir; // Include directory
  61. std::string Base; // Base part of the include file name
  62. };
  63. /**
  64. * Source file parsing cache
  65. */
  66. class ParseCacheT
  67. {
  68. public:
  69. // -- Types
  70. /**
  71. * Entry of the file parsing cache
  72. */
  73. struct FileT
  74. {
  75. void Clear();
  76. struct MocT
  77. {
  78. std::string Macro;
  79. struct IncludeT
  80. {
  81. std::vector<IncludeKeyT> Underscore;
  82. std::vector<IncludeKeyT> Dot;
  83. } Include;
  84. std::vector<std::string> Depends;
  85. } Moc;
  86. struct UicT
  87. {
  88. std::vector<IncludeKeyT> Include;
  89. std::vector<std::string> Depends;
  90. } Uic;
  91. };
  92. typedef std::shared_ptr<FileT> FileHandleT;
  93. typedef std::pair<FileHandleT, bool> GetOrInsertT;
  94. public:
  95. ParseCacheT();
  96. ~ParseCacheT();
  97. void Clear();
  98. bool ReadFromFile(std::string const& fileName);
  99. bool WriteToFile(std::string const& fileName);
  100. //! Might return an invalid handle
  101. FileHandleT Get(std::string const& fileName) const;
  102. //! Always returns a valid handle
  103. GetOrInsertT GetOrInsert(std::string const& fileName);
  104. private:
  105. std::unordered_map<std::string, FileHandleT> Map_;
  106. };
  107. /**
  108. * Source file data
  109. */
  110. class SourceFileT
  111. {
  112. public:
  113. SourceFileT(std::string fileName)
  114. : FileName(std::move(fileName))
  115. {
  116. }
  117. public:
  118. std::string FileName;
  119. cmFileTime FileTime;
  120. ParseCacheT::FileHandleT ParseData;
  121. std::string BuildPath;
  122. bool Moc = false;
  123. bool Uic = false;
  124. };
  125. typedef std::shared_ptr<SourceFileT> SourceFileHandleT;
  126. typedef std::map<std::string, SourceFileHandleT> SourceFileMapT;
  127. /**
  128. * Meta compiler file mapping information
  129. */
  130. struct MappingT
  131. {
  132. SourceFileHandleT SourceFile;
  133. std::string OutputFile;
  134. std::string IncludeString;
  135. std::vector<SourceFileHandleT> IncluderFiles;
  136. };
  137. typedef std::shared_ptr<MappingT> MappingHandleT;
  138. typedef std::map<std::string, MappingHandleT> MappingMapT;
  139. /**
  140. * Common settings
  141. */
  142. class BaseSettingsT
  143. {
  144. public:
  145. // -- Constructors
  146. BaseSettingsT();
  147. ~BaseSettingsT();
  148. BaseSettingsT(BaseSettingsT const&) = delete;
  149. BaseSettingsT& operator=(BaseSettingsT const&) = delete;
  150. // -- Attributes
  151. // - Config
  152. bool MultiConfig = false;
  153. bool IncludeProjectDirsBefore = false;
  154. unsigned int QtVersionMajor = 4;
  155. // - Directories
  156. std::string ProjectSourceDir;
  157. std::string ProjectBinaryDir;
  158. std::string CurrentSourceDir;
  159. std::string CurrentBinaryDir;
  160. std::string AutogenBuildDir;
  161. std::string AutogenIncludeDir;
  162. // - Files
  163. std::string CMakeExecutable;
  164. cmFileTime CMakeExecutableTime;
  165. std::string ParseCacheFile;
  166. std::vector<std::string> HeaderExtensions;
  167. };
  168. /**
  169. * Shared common variables
  170. */
  171. class BaseEvalT
  172. {
  173. public:
  174. // -- Parse Cache
  175. bool ParseCacheChanged = false;
  176. cmFileTime ParseCacheTime;
  177. ParseCacheT ParseCache;
  178. // -- Sources
  179. SourceFileMapT Headers;
  180. SourceFileMapT Sources;
  181. };
  182. /**
  183. * Moc settings
  184. */
  185. class MocSettingsT
  186. {
  187. public:
  188. // -- Constructors
  189. MocSettingsT();
  190. ~MocSettingsT();
  191. MocSettingsT(MocSettingsT const&) = delete;
  192. MocSettingsT& operator=(MocSettingsT const&) = delete;
  193. // -- Const methods
  194. bool skipped(std::string const& fileName) const;
  195. std::string MacrosString() const;
  196. // -- Attributes
  197. bool Enabled = false;
  198. bool SettingsChanged = false;
  199. bool RelaxedMode = false;
  200. cmFileTime ExecutableTime;
  201. std::string Executable;
  202. std::string CompFileAbs;
  203. std::string PredefsFileRel;
  204. std::string PredefsFileAbs;
  205. std::unordered_set<std::string> SkipList;
  206. std::vector<std::string> IncludePaths;
  207. std::vector<std::string> Includes;
  208. std::vector<std::string> Definitions;
  209. std::vector<std::string> Options;
  210. std::vector<std::string> AllOptions;
  211. std::vector<std::string> PredefsCmd;
  212. std::vector<KeyExpT> DependFilters;
  213. std::vector<KeyExpT> MacroFilters;
  214. cmsys::RegularExpression RegExpInclude;
  215. };
  216. /**
  217. * Moc shared variables
  218. */
  219. class MocEvalT
  220. {
  221. public:
  222. // -- predefines file
  223. cmFileTime PredefsTime;
  224. // -- Mappings
  225. MappingMapT HeaderMappings;
  226. MappingMapT SourceMappings;
  227. MappingMapT Includes;
  228. // -- Discovered files
  229. SourceFileMapT HeadersDiscovered;
  230. // -- Mocs compilation
  231. bool CompUpdated = false;
  232. std::vector<std::string> CompFiles;
  233. };
  234. /**
  235. * Uic settings
  236. */
  237. class UicSettingsT
  238. {
  239. public:
  240. UicSettingsT();
  241. ~UicSettingsT();
  242. UicSettingsT(UicSettingsT const&) = delete;
  243. UicSettingsT& operator=(UicSettingsT const&) = delete;
  244. // -- Const methods
  245. bool skipped(std::string const& fileName) const;
  246. // -- Attributes
  247. bool Enabled = false;
  248. bool SettingsChanged = false;
  249. cmFileTime ExecutableTime;
  250. std::string Executable;
  251. std::unordered_set<std::string> SkipList;
  252. std::vector<std::string> TargetOptions;
  253. std::map<std::string, std::vector<std::string>> Options;
  254. std::vector<std::string> SearchPaths;
  255. cmsys::RegularExpression RegExpInclude;
  256. };
  257. /**
  258. * Uic shared variables
  259. */
  260. class UicEvalT
  261. {
  262. public:
  263. SourceFileMapT UiFiles;
  264. MappingMapT Includes;
  265. };
  266. /**
  267. * Abstract job class for concurrent job processing
  268. */
  269. class JobT : public cmWorkerPool::JobT
  270. {
  271. protected:
  272. /**
  273. * @brief Protected default constructor
  274. */
  275. JobT(bool fence = false)
  276. : cmWorkerPool::JobT(fence)
  277. {
  278. }
  279. //! Get the generator. Only valid during Process() call!
  280. cmQtAutoMocUic* Gen() const
  281. {
  282. return static_cast<cmQtAutoMocUic*>(UserData());
  283. };
  284. // -- Accessors. Only valid during Process() call!
  285. Logger const& Log() const { return Gen()->Log(); }
  286. BaseSettingsT const& BaseConst() const { return Gen()->BaseConst(); }
  287. BaseEvalT& BaseEval() const { return Gen()->BaseEval(); }
  288. MocSettingsT const& MocConst() const { return Gen()->MocConst(); }
  289. MocEvalT& MocEval() const { return Gen()->MocEval(); }
  290. UicSettingsT const& UicConst() const { return Gen()->UicConst(); }
  291. UicEvalT& UicEval() const { return Gen()->UicEval(); }
  292. // -- Error logging with automatic abort
  293. void LogError(GenT genType, std::string const& message) const;
  294. void LogFileError(GenT genType, std::string const& filename,
  295. std::string const& message) const;
  296. void LogCommandError(GenT genType, std::string const& message,
  297. std::vector<std::string> const& command,
  298. std::string const& output) const;
  299. /**
  300. * @brief Run an external process. Use only during Process() call!
  301. */
  302. bool RunProcess(GenT genType, cmWorkerPool::ProcessResultT& result,
  303. std::vector<std::string> const& command,
  304. std::string* infoMessage = nullptr);
  305. };
  306. /**
  307. * Fence job utility class
  308. */
  309. class JobFenceT : public JobT
  310. {
  311. public:
  312. JobFenceT()
  313. : JobT(true)
  314. {
  315. }
  316. void Process() override{};
  317. };
  318. /**
  319. * Generate moc_predefs.h
  320. */
  321. class JobMocPredefsT : public JobFenceT
  322. {
  323. void Process() override;
  324. bool Update(std::string* reason) const;
  325. };
  326. /**
  327. * File parse job base class
  328. */
  329. class JobParseT : public JobT
  330. {
  331. public:
  332. JobParseT(SourceFileHandleT fileHandle)
  333. : FileHandle(std::move(fileHandle))
  334. {
  335. }
  336. protected:
  337. bool ReadFile();
  338. void CreateKeys(std::vector<IncludeKeyT>& container,
  339. std::set<std::string> const& source,
  340. std::size_t basePrefixLength);
  341. void MocMacro();
  342. void MocDependecies();
  343. void MocIncludes();
  344. void UicIncludes();
  345. protected:
  346. SourceFileHandleT FileHandle;
  347. std::string Content;
  348. };
  349. /**
  350. * Header file parse job
  351. */
  352. class JobParseHeaderT : public JobParseT
  353. {
  354. public:
  355. using JobParseT::JobParseT;
  356. void Process() override;
  357. };
  358. /**
  359. * Source file parse job
  360. */
  361. class JobParseSourceT : public JobParseT
  362. {
  363. public:
  364. using JobParseT::JobParseT;
  365. void Process() override;
  366. };
  367. /**
  368. * Evaluate parsed files
  369. */
  370. class JobEvaluateT : public JobFenceT
  371. {
  372. void Process() override;
  373. // -- Moc
  374. bool MocEvalHeader(SourceFileHandleT source);
  375. bool MocEvalSource(SourceFileHandleT const& source);
  376. SourceFileHandleT MocFindIncludedHeader(
  377. std::string const& includerDir, std::string const& includeBase) const;
  378. SourceFileHandleT MocFindHeader(std::string const& basePath) const;
  379. std::string MocMessageTestHeaders(std::string const& fileBase) const;
  380. bool MocRegisterIncluded(std::string const& includeString,
  381. SourceFileHandleT includerFileHandle,
  382. SourceFileHandleT sourceFileHandle,
  383. bool sourceIsHeader) const;
  384. void MocRegisterMapping(MappingHandleT mappingHandle,
  385. bool sourceIsHeader) const;
  386. // -- Uic
  387. bool UicEval(SourceFileMapT const& fileMap);
  388. bool UicEvalFile(SourceFileHandleT sourceFileHandle);
  389. SourceFileHandleT UicFindIncludedUi(std::string const& sourceFile,
  390. std::string const& sourceDir,
  391. IncludeKeyT const& incKey) const;
  392. bool UicRegisterMapping(std::string const& includeString,
  393. SourceFileHandleT uiFileHandle,
  394. SourceFileHandleT includerFileHandle);
  395. };
  396. /**
  397. * Generates moc/uic jobs
  398. */
  399. class JobGenerateT : public JobFenceT
  400. {
  401. void Process() override;
  402. // -- Moc
  403. bool MocGenerate(MappingHandleT const& mapping, bool compFile) const;
  404. bool MocUpdate(MappingT const& mapping, std::string* reason) const;
  405. std::pair<std::string, cmFileTime> MocFindDependency(
  406. std::string const& sourceDir, std::string const& includeString) const;
  407. // -- Uic
  408. bool UicGenerate(MappingHandleT const& mapping) const;
  409. bool UicUpdate(MappingT const& mapping, std::string* reason) const;
  410. };
  411. /**
  412. * File compiling base job
  413. */
  414. class JobCompileT : public JobT
  415. {
  416. public:
  417. JobCompileT(MappingHandleT uicMapping, std::unique_ptr<std::string> reason)
  418. : Mapping(std::move(uicMapping))
  419. , Reason(std::move(reason))
  420. {
  421. }
  422. protected:
  423. MappingHandleT Mapping;
  424. std::unique_ptr<std::string> Reason;
  425. };
  426. /**
  427. * moc compiles a file
  428. */
  429. class JobMocT : public JobCompileT
  430. {
  431. public:
  432. using JobCompileT::JobCompileT;
  433. void Process() override;
  434. };
  435. /**
  436. * uic compiles a file
  437. */
  438. class JobUicT : public JobCompileT
  439. {
  440. public:
  441. using JobCompileT::JobCompileT;
  442. void Process() override;
  443. };
  444. /// @brief Generate mocs_compilation.cpp
  445. ///
  446. class JobMocsCompilationT : public JobFenceT
  447. {
  448. private:
  449. void Process() override;
  450. };
  451. /// @brief The last job
  452. ///
  453. class JobFinishT : public JobFenceT
  454. {
  455. private:
  456. void Process() override;
  457. };
  458. // -- Const settings interface
  459. BaseSettingsT const& BaseConst() const { return this->BaseConst_; }
  460. BaseEvalT& BaseEval() { return this->BaseEval_; }
  461. MocSettingsT const& MocConst() const { return this->MocConst_; }
  462. MocEvalT& MocEval() { return this->MocEval_; }
  463. UicSettingsT const& UicConst() const { return this->UicConst_; }
  464. UicEvalT& UicEval() { return this->UicEval_; }
  465. // -- Parallel job processing interface
  466. cmWorkerPool& WorkerPool() { return WorkerPool_; }
  467. void AbortError() { Abort(true); }
  468. void AbortSuccess() { Abort(false); }
  469. // -- Utility
  470. std::string AbsoluteBuildPath(std::string const& relativePath) const;
  471. std::string AbsoluteIncludePath(std::string const& relativePath) const;
  472. template <class JOBTYPE>
  473. void CreateParseJobs(SourceFileMapT const& sourceMap);
  474. private:
  475. // -- Utility accessors
  476. Logger const& Log() const { return Logger_; }
  477. // -- Abstract processing interface
  478. bool Init(cmMakefile* makefile) override;
  479. void InitJobs();
  480. bool Process() override;
  481. // -- Settings file
  482. void SettingsFileRead();
  483. bool SettingsFileWrite();
  484. // -- Parse cache
  485. void ParseCacheRead();
  486. bool ParseCacheWrite();
  487. // -- Thread processing
  488. void Abort(bool error);
  489. // -- Generation
  490. bool CreateDirectories();
  491. private:
  492. // -- Utility
  493. Logger Logger_;
  494. // -- Settings
  495. BaseSettingsT BaseConst_;
  496. BaseEvalT BaseEval_;
  497. MocSettingsT MocConst_;
  498. MocEvalT MocEval_;
  499. UicSettingsT UicConst_;
  500. UicEvalT UicEval_;
  501. // -- Settings file
  502. std::string SettingsFile_;
  503. std::string SettingsStringMoc_;
  504. std::string SettingsStringUic_;
  505. // -- Worker thread pool
  506. std::atomic<bool> JobError_ = ATOMIC_VAR_INIT(false);
  507. cmWorkerPool WorkerPool_;
  508. };
  509. #endif