summaryrefslogtreecommitdiffstats
path: root/Source/cmQtAutoGeneratorMocUic.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmQtAutoGeneratorMocUic.h')
-rw-r--r--Source/cmQtAutoGeneratorMocUic.h510
1 files changed, 378 insertions, 132 deletions
diff --git a/Source/cmQtAutoGeneratorMocUic.h b/Source/cmQtAutoGeneratorMocUic.h
index d510939..215e25a 100644
--- a/Source/cmQtAutoGeneratorMocUic.h
+++ b/Source/cmQtAutoGeneratorMocUic.h
@@ -8,188 +8,434 @@
#include "cmFilePathChecksum.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
+#include "cmUVHandlePtr.h"
+#include "cm_uv.h"
#include "cmsys/RegularExpression.hxx"
+#include <algorithm>
+#include <condition_variable>
+#include <cstddef>
+#include <deque>
#include <map>
#include <memory> // IWYU pragma: keep
+#include <mutex>
#include <set>
#include <string>
+#include <thread>
#include <vector>
class cmMakefile;
+// @brief AUTOMOC and AUTOUIC generator
class cmQtAutoGeneratorMocUic : public cmQtAutoGenerator
{
CM_DISABLE_COPY(cmQtAutoGeneratorMocUic)
public:
cmQtAutoGeneratorMocUic();
+ ~cmQtAutoGeneratorMocUic() override;
-private:
+public:
// -- Types
+ class WorkerT;
/// @brief Search key plus regular expression pair
- struct KeyRegExp
+ ///
+ struct KeyExpT
{
- KeyRegExp() = default;
+ KeyExpT() = default;
- KeyRegExp(const char* key, const char* regExp)
+ KeyExpT(const char* key, const char* exp)
: Key(key)
- , RegExp(regExp)
+ , Exp(exp)
{
}
- KeyRegExp(std::string const& key, std::string const& regExp)
+ KeyExpT(std::string const& key, std::string const& exp)
: Key(key)
- , RegExp(regExp)
+ , Exp(exp)
{
}
std::string Key;
- cmsys::RegularExpression RegExp;
+ cmsys::RegularExpression Exp;
};
- /// @brief Source file job
- struct SourceJob
+ /// @brief Common settings
+ ///
+ class BaseSettingsT
{
- bool Moc = false;
- bool Uic = false;
+ CM_DISABLE_COPY(BaseSettingsT)
+ public:
+ // -- Volatile methods
+ BaseSettingsT(FileSystem* fileSystem)
+ : MultiConfig(MultiConfigT::WRAPPER)
+ , IncludeProjectDirsBefore(false)
+ , QtVersionMajor(4)
+ , NumThreads(1)
+ , FileSys(fileSystem)
+ {
+ }
+
+ // -- Const methods
+ std::string AbsoluteBuildPath(std::string const& relativePath) const;
+ bool FindHeader(std::string& header,
+ std::string const& testBasePath) const;
+
+ // -- Attributes
+ // - Config
+ std::string ConfigSuffix;
+ MultiConfigT MultiConfig;
+ bool IncludeProjectDirsBefore;
+ unsigned int QtVersionMajor;
+ unsigned int NumThreads;
+ // - Directories
+ std::string ProjectSourceDir;
+ std::string ProjectBinaryDir;
+ std::string CurrentSourceDir;
+ std::string CurrentBinaryDir;
+ std::string AutogenBuildDir;
+ std::string AutogenIncludeDirRel;
+ std::string AutogenIncludeDirAbs;
+ // - Files
+ cmFilePathChecksum FilePathChecksum;
+ std::vector<std::string> HeaderExtensions;
+ // - File system
+ FileSystem* FileSys;
};
- /// @brief MOC job
- struct MocJobAuto
+ /// @brief Moc settings
+ ///
+ class MocSettingsT
{
- std::string SourceFile;
- std::string BuildFileRel;
- std::set<std::string> Depends;
+ CM_DISABLE_COPY(MocSettingsT)
+ public:
+ MocSettingsT(FileSystem* fileSys)
+ : FileSys(fileSys)
+ {
+ }
+
+ // -- Const methods
+ bool skipped(std::string const& fileName) const;
+ std::string FindMacro(std::string const& content) const;
+ std::string MacrosString() const;
+ std::string FindIncludedFile(std::string const& sourcePath,
+ std::string const& includeString) const;
+ void FindDependencies(std::string const& content,
+ std::set<std::string>& depends) const;
+
+ // -- Attributes
+ bool Enabled = false;
+ bool SettingsChanged = false;
+ bool RelaxedMode = false;
+ std::string Executable;
+ std::string CompFileRel;
+ std::string CompFileAbs;
+ std::string PredefsFileRel;
+ std::string PredefsFileAbs;
+ std::set<std::string> SkipList;
+ std::vector<std::string> IncludePaths;
+ std::vector<std::string> Includes;
+ std::vector<std::string> Definitions;
+ std::vector<std::string> Options;
+ std::vector<std::string> AllOptions;
+ std::vector<std::string> PredefsCmd;
+ std::vector<KeyExpT> DependFilters;
+ std::vector<KeyExpT> MacroFilters;
+ cmsys::RegularExpression RegExpInclude;
+ // - File system
+ FileSystem* FileSys;
};
- /// @brief MOC job
- struct MocJobIncluded : MocJobAuto
+ /// @brief Uic settings
+ ///
+ class UicSettingsT
{
- bool DependsValid = false;
- std::string Includer;
+ CM_DISABLE_COPY(UicSettingsT)
+ public:
+ UicSettingsT() = default;
+ // -- Const methods
+ bool skipped(std::string const& fileName) const;
+
+ // -- Attributes
+ bool Enabled = false;
+ bool SettingsChanged = false;
+ std::string Executable;
+ std::set<std::string> SkipList;
+ std::vector<std::string> TargetOptions;
+ std::map<std::string, std::vector<std::string>> Options;
+ std::vector<std::string> SearchPaths;
+ cmsys::RegularExpression RegExpInclude;
+ };
+
+ /// @brief Abstract job class for threaded processing
+ ///
+ class JobT
+ {
+ CM_DISABLE_COPY(JobT)
+ public:
+ JobT() = default;
+ virtual ~JobT() = default;
+ // -- Abstract processing interface
+ virtual void Process(WorkerT& wrk) = 0;
+ };
+
+ /// @brief Deleter for classes derived from Job
+ ///
+ struct JobDeleterT
+ {
+ void operator()(JobT* job);
+ };
+
+ // Job management types
+ typedef std::unique_ptr<JobT, JobDeleterT> JobHandleT;
+ typedef std::deque<JobHandleT> JobQueueT;
+
+ /// @brief Parse source job
+ ///
+ class JobParseT : public JobT
+ {
+ public:
+ JobParseT(std::string&& fileName, bool moc, bool uic, bool header = false)
+ : FileName(std::move(fileName))
+ , AutoMoc(moc)
+ , AutoUic(uic)
+ , Header(header)
+ {
+ }
+
+ private:
+ struct MetaT
+ {
+ std::string Content;
+ std::string FileDir;
+ std::string FileBase;
+ };
+
+ void Process(WorkerT& wrk) override;
+ bool ParseMocSource(WorkerT& wrk, MetaT const& meta);
+ bool ParseMocHeader(WorkerT& wrk, MetaT const& meta);
+ std::string MocStringHeaders(WorkerT& wrk,
+ std::string const& fileBase) const;
+ std::string MocFindIncludedHeader(WorkerT& wrk,
+ std::string const& includerDir,
+ std::string const& includeBase);
+ bool ParseUic(WorkerT& wrk, MetaT const& meta);
+ bool ParseUicInclude(WorkerT& wrk, MetaT const& meta,
+ std::string&& includeString);
+ std::string UicFindIncludedFile(WorkerT& wrk, MetaT const& meta,
+ std::string const& includeString);
+
+ private:
+ std::string FileName;
+ bool AutoMoc = false;
+ bool AutoUic = false;
+ bool Header = false;
+ };
+
+ /// @brief Generate moc_predefs
+ ///
+ class JobMocPredefsT : public JobT
+ {
+ private:
+ void Process(WorkerT& wrk) override;
+ };
+
+ /// @brief Moc a file job
+ ///
+ class JobMocT : public JobT
+ {
+ public:
+ JobMocT(std::string&& sourceFile, std::string const& includerFile,
+ std::string&& includeString)
+ : SourceFile(std::move(sourceFile))
+ , IncluderFile(includerFile)
+ , IncludeString(std::move(includeString))
+ {
+ }
+
+ void FindDependencies(WorkerT& wrk, std::string const& content);
+
+ private:
+ void Process(WorkerT& wrk) override;
+ bool UpdateRequired(WorkerT& wrk);
+ void GenerateMoc(WorkerT& wrk);
+
+ public:
+ std::string SourceFile;
+ std::string IncluderFile;
std::string IncludeString;
+ std::string BuildFile;
+ bool DependsValid = false;
+ std::set<std::string> Depends;
};
- /// @brief UIC job
- struct UicJob
+ /// @brief Uic a file job
+ ///
+ class JobUicT : public JobT
{
+ public:
+ JobUicT(std::string&& sourceFile, std::string const& includerFile,
+ std::string&& includeString)
+ : SourceFile(std::move(sourceFile))
+ , IncluderFile(includerFile)
+ , IncludeString(std::move(includeString))
+ {
+ }
+
+ private:
+ void Process(WorkerT& wrk) override;
+ bool UpdateRequired(WorkerT& wrk);
+ void GenerateUic(WorkerT& wrk);
+
+ public:
std::string SourceFile;
- std::string BuildFileRel;
- std::string Includer;
+ std::string IncluderFile;
std::string IncludeString;
+ std::string BuildFile;
};
- // -- Initialization
- bool InitInfoFile(cmMakefile* makefile);
+ /// @brief Worker Thread
+ ///
+ class WorkerT
+ {
+ CM_DISABLE_COPY(WorkerT)
+ public:
+ WorkerT(cmQtAutoGeneratorMocUic* gen, uv_loop_t* uvLoop);
+ ~WorkerT();
+
+ // -- Const accessors
+ cmQtAutoGeneratorMocUic& Gen() const { return *Gen_; }
+ Logger& Log() const { return Gen_->Log(); }
+ FileSystem& FileSys() const { return Gen_->FileSys(); }
+ const BaseSettingsT& Base() const { return Gen_->Base(); }
+ const MocSettingsT& Moc() const { return Gen_->Moc(); }
+ const UicSettingsT& Uic() const { return Gen_->Uic(); }
- // -- Settings file
- void SettingsFileRead(cmMakefile* makefile);
- bool SettingsFileWrite();
- bool SettingsChanged() const
+ // -- Log info
+ void LogInfo(GeneratorT genType, std::string const& message) const;
+ // -- Log warning
+ void LogWarning(GeneratorT genType, std::string const& message) const;
+ void LogFileWarning(GeneratorT genType, std::string const& filename,
+ std::string const& message) const;
+ // -- Log error
+ void LogError(GeneratorT genType, std::string const& message) const;
+ void LogFileError(GeneratorT genType, std::string const& filename,
+ std::string const& message) const;
+ void LogCommandError(GeneratorT genType, std::string const& message,
+ std::vector<std::string> const& command,
+ std::string const& output) const;
+
+ // -- External processes
+ /// @brief Verbose logging version
+ bool RunProcess(GeneratorT genType, ProcessResultT& result,
+ std::vector<std::string> const& command);
+
+ private:
+ /// @brief Thread main loop
+ void Loop();
+
+ // -- Libuv callbacks
+ static void UVProcessStart(uv_async_t* handle);
+ void UVProcessFinished();
+
+ private:
+ // -- Generator
+ cmQtAutoGeneratorMocUic* Gen_;
+ // -- Job handle
+ JobHandleT JobHandle_;
+ // -- Process management
+ std::mutex ProcessMutex_;
+ cm::uv_async_ptr ProcessRequest_;
+ std::condition_variable ProcessCondition_;
+ std::unique_ptr<ReadOnlyProcessT> Process_;
+ // -- System thread
+ std::thread Thread_;
+ };
+
+ /// @brief Processing stage
+ enum class StageT
{
- return (this->MocSettingsChanged || this->UicSettingsChanged);
- }
-
- // -- Central processing
- bool Process(cmMakefile* makefile) override;
-
- // -- Source parsing
- bool ParseSourceFile(std::string const& absFilename, const SourceJob& job);
- bool ParseHeaderFile(std::string const& absFilename, const SourceJob& job);
- bool ParsePostprocess();
-
- // -- Moc
- bool MocEnabled() const { return !this->MocExecutable.empty(); }
- bool MocSkip(std::string const& absFilename) const;
- bool MocRequired(std::string const& contentText,
- std::string* macroName = nullptr);
- // Moc strings
- std::string MocStringMacros() const;
- std::string MocStringHeaders(std::string const& fileBase) const;
- std::string MocFindIncludedHeader(std::string const& sourcePath,
- std::string const& includeBase) const;
- bool MocFindIncludedFile(std::string& absFile, std::string const& sourceFile,
- std::string const& includeString) const;
- // Moc depends
- bool MocDependFilterPush(std::string const& key, std::string const& regExp);
- void MocFindDepends(std::string const& absFilename,
- std::string const& contentText,
- std::set<std::string>& depends);
- // Moc
- bool MocParseSourceContent(std::string const& absFilename,
- std::string const& contentText);
- void MocParseHeaderContent(std::string const& absFilename,
- std::string const& contentText);
-
- bool MocGenerateAll();
- bool MocGenerateFile(const MocJobAuto& mocJob, bool* generated = nullptr);
-
- // -- Uic
- bool UicEnabled() const { return !this->UicExecutable.empty(); }
- bool UicSkip(std::string const& absFilename) const;
- bool UicParseContent(std::string const& fileName,
- std::string const& contentText);
- bool UicFindIncludedFile(std::string& absFile, std::string const& sourceFile,
- std::string const& includeString);
- bool UicGenerateAll();
- bool UicGenerateFile(const UicJob& uicJob);
-
- // -- Utility
- bool FindHeader(std::string& header, std::string const& testBasePath) const;
-
- // -- Meta
- std::string ConfigSuffix;
- cmQtAutoGen::MultiConfig MultiConfig;
+ SETTINGS_READ,
+ CREATE_DIRECTORIES,
+ PARSE_SOURCES,
+ PARSE_HEADERS,
+ MOC_PREDEFS,
+ MOC_PROCESS,
+ MOCS_COMPILATION,
+ UIC_PROCESS,
+ SETTINGS_WRITE,
+ FINISH,
+ END
+ };
+
+ // -- Const settings interface
+ const BaseSettingsT& Base() const { return this->Base_; }
+ const MocSettingsT& Moc() const { return this->Moc_; }
+ const UicSettingsT& Uic() const { return this->Uic_; }
+
+ // -- Worker thread interface
+ void WorkerSwapJob(JobHandleT& jobHandle);
+ // -- Parallel job processing interface
+ void ParallelRegisterJobError();
+ bool ParallelJobPushMoc(JobHandleT& jobHandle);
+ bool ParallelJobPushUic(JobHandleT& jobHandle);
+ bool ParallelMocIncluded(std::string const& sourceFile);
+ void ParallelMocAutoRegister(std::string const& mocFile);
+ void ParallelMocAutoUpdated();
+
+private:
+ // -- Abstract processing interface
+ bool Init(cmMakefile* makefile) override;
+ bool Process() override;
+ // -- Process stage
+ static void UVPollStage(uv_async_t* handle);
+ void PollStage();
+ void SetStage(StageT stage);
+ // -- Settings file
+ void SettingsFileRead();
+ void SettingsFileWrite();
+ // -- Thread processing
+ bool ThreadsStartJobs(JobQueueT& queue);
+ bool ThreadsJobsDone();
+ void ThreadsStop();
+ void RegisterJobError();
+ // -- Generation
+ void CreateDirectories();
+ void MocGenerateCompilation();
+
+private:
// -- Settings
- bool IncludeProjectDirsBefore;
- std::string SettingsFile;
- std::string SettingsStringMoc;
- std::string SettingsStringUic;
- // -- Directories
- std::string ProjectSourceDir;
- std::string ProjectBinaryDir;
- std::string CurrentSourceDir;
- std::string CurrentBinaryDir;
- std::string AutogenBuildDir;
- std::string AutogenIncludeDir;
- // -- Qt environment
- unsigned long QtVersionMajor;
- std::string MocExecutable;
- std::string UicExecutable;
- // -- File lists
- std::map<std::string, SourceJob> HeaderJobs;
- std::map<std::string, SourceJob> SourceJobs;
- std::vector<std::string> HeaderExtensions;
- cmFilePathChecksum FilePathChecksum;
- // -- Moc
- bool MocSettingsChanged;
- bool MocPredefsChanged;
- bool MocRelaxedMode;
- std::string MocCompFileRel;
- std::string MocCompFileAbs;
- std::string MocPredefsFileRel;
- std::string MocPredefsFileAbs;
- std::vector<std::string> MocSkipList;
- std::vector<std::string> MocIncludePaths;
- std::vector<std::string> MocIncludes;
- std::vector<std::string> MocDefinitions;
- std::vector<std::string> MocOptions;
- std::vector<std::string> MocAllOptions;
- std::vector<std::string> MocPredefsCmd;
- std::vector<KeyRegExp> MocDependFilters;
- std::vector<KeyRegExp> MocMacroFilters;
- cmsys::RegularExpression MocRegExpInclude;
- std::vector<std::unique_ptr<MocJobIncluded>> MocJobsIncluded;
- std::vector<std::unique_ptr<MocJobAuto>> MocJobsAuto;
- // -- Uic
- bool UicSettingsChanged;
- std::vector<std::string> UicSkipList;
- std::vector<std::string> UicTargetOptions;
- std::map<std::string, std::vector<std::string>> UicOptions;
- std::vector<std::string> UicSearchPaths;
- cmsys::RegularExpression UicRegExpInclude;
- std::vector<std::unique_ptr<UicJob>> UicJobs;
+ BaseSettingsT Base_;
+ MocSettingsT Moc_;
+ UicSettingsT Uic_;
+ // -- Progress
+ StageT Stage_;
+ // -- Job queues
+ std::mutex JobsMutex_;
+ struct
+ {
+ JobQueueT Sources;
+ JobQueueT Headers;
+ JobQueueT MocPredefs;
+ JobQueueT Moc;
+ JobQueueT Uic;
+ } JobQueues_;
+ JobQueueT JobQueue_;
+ std::size_t volatile JobsRemain_;
+ bool volatile JobError_;
+ bool volatile JobThreadsAbort_;
+ std::condition_variable JobsConditionRead_;
+ // -- Moc meta
+ std::set<std::string> MocIncludedStrings_;
+ std::set<std::string> MocIncludedFiles_;
+ std::set<std::string> MocAutoFiles_;
+ bool volatile MocAutoFileUpdated_;
+ // -- Settings file
+ std::string SettingsFile_;
+ std::string SettingsStringMoc_;
+ std::string SettingsStringUic_;
+ // -- Threads and loops
+ std::vector<std::unique_ptr<WorkerT>> Workers_;
};
#endif