Autogen: Make cmQtAutoMocUic a free function

This commit is contained in:
Sebastian Holtermann 2019-09-27 15:57:29 +02:00
parent e0e9be3d57
commit 6bd40ccf84
3 changed files with 635 additions and 650 deletions

File diff suppressed because it is too large Load Diff

View File

@ -5,555 +5,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include "cmFileTime.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
#include "cmWorkerPool.h"
#include "cmsys/RegularExpression.hxx"
#include <cm/string_view>
#include <atomic>
#include <cstddef>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
/** \class cmQtAutoMocUic
* \brief AUTOMOC and AUTOUIC generator
/**
* Process AUTOMOC and AUTOUIC
* @return true on success
*/
class cmQtAutoMocUic : public cmQtAutoGenerator
{
public:
cmQtAutoMocUic();
~cmQtAutoMocUic() override;
cmQtAutoMocUic(cmQtAutoMocUic const&) = delete;
cmQtAutoMocUic& operator=(cmQtAutoMocUic const&) = delete;
public:
// -- Types
/** Include string with sub parts. */
struct IncludeKeyT
{
IncludeKeyT(std::string const& key, std::size_t basePrefixLength);
std::string Key; // Full include string
std::string Dir; // Include directory
std::string Base; // Base part of the include file name
};
/** Search key plus regular expression pair. */
struct KeyExpT
{
KeyExpT() = default;
KeyExpT(std::string key, std::string const& exp)
: Key(std::move(key))
, Exp(exp)
{
}
std::string Key;
cmsys::RegularExpression Exp;
};
/** Source file parsing cache. */
class ParseCacheT
{
public:
// -- Types
/** Entry of the file parsing cache. */
struct FileT
{
void Clear();
struct MocT
{
std::string Macro;
struct IncludeT
{
std::vector<IncludeKeyT> Underscore;
std::vector<IncludeKeyT> Dot;
} Include;
std::vector<std::string> Depends;
} Moc;
struct UicT
{
std::vector<IncludeKeyT> Include;
std::vector<std::string> Depends;
} Uic;
};
using FileHandleT = std::shared_ptr<FileT>;
using GetOrInsertT = std::pair<FileHandleT, bool>;
public:
ParseCacheT();
~ParseCacheT();
void Clear();
bool ReadFromFile(std::string const& fileName);
bool WriteToFile(std::string const& fileName);
//! Might return an invalid handle
FileHandleT Get(std::string const& fileName) const;
//! Always returns a valid handle
GetOrInsertT GetOrInsert(std::string const& fileName);
private:
std::unordered_map<std::string, FileHandleT> Map_;
};
/** Source file data. */
class SourceFileT
{
public:
SourceFileT(std::string fileName)
: FileName(std::move(fileName))
{
}
public:
std::string FileName;
cmFileTime FileTime;
ParseCacheT::FileHandleT ParseData;
std::string BuildPath;
bool IsHeader = false;
bool Moc = false;
bool Uic = false;
};
using SourceFileHandleT = std::shared_ptr<SourceFileT>;
using SourceFileMapT = std::map<std::string, SourceFileHandleT>;
/** Meta compiler file mapping information. */
struct MappingT
{
SourceFileHandleT SourceFile;
std::string OutputFile;
std::string IncludeString;
std::vector<SourceFileHandleT> IncluderFiles;
};
using MappingHandleT = std::shared_ptr<MappingT>;
using MappingMapT = std::map<std::string, MappingHandleT>;
/** Common settings. */
class BaseSettingsT
{
public:
// -- Constructors
BaseSettingsT();
~BaseSettingsT();
BaseSettingsT(BaseSettingsT const&) = delete;
BaseSettingsT& operator=(BaseSettingsT const&) = delete;
// -- Attributes
// - Config
bool MultiConfig = false;
unsigned int QtVersionMajor = 4;
unsigned int ThreadCount = 0;
// - Directories
std::string AutogenBuildDir;
std::string AutogenIncludeDir;
// - Files
std::string CMakeExecutable;
cmFileTime CMakeExecutableTime;
std::string ParseCacheFile;
std::vector<std::string> HeaderExtensions;
};
/** Shared common variables. */
class BaseEvalT
{
public:
// -- Parse Cache
bool ParseCacheChanged = false;
cmFileTime ParseCacheTime;
ParseCacheT ParseCache;
// -- Sources
SourceFileMapT Headers;
SourceFileMapT Sources;
};
/** Moc settings. */
class MocSettingsT
{
public:
// -- Constructors
MocSettingsT();
~MocSettingsT();
MocSettingsT(MocSettingsT const&) = delete;
MocSettingsT& operator=(MocSettingsT const&) = delete;
// -- Const methods
bool skipped(std::string const& fileName) const;
std::string MacrosString() const;
// -- Attributes
bool Enabled = false;
bool SettingsChanged = false;
bool RelaxedMode = false;
bool PathPrefix = false;
cmFileTime ExecutableTime;
std::string Executable;
std::string CompFileAbs;
std::string PredefsFileAbs;
std::unordered_set<std::string> SkipList;
std::vector<std::string> IncludePaths;
std::vector<std::string> Definitions;
std::vector<std::string> OptionsIncludes;
std::vector<std::string> OptionsDefinitions;
std::vector<std::string> OptionsExtra;
std::vector<std::string> PredefsCmd;
std::vector<KeyExpT> DependFilters;
std::vector<KeyExpT> MacroFilters;
cmsys::RegularExpression RegExpInclude;
};
/** Moc shared variables. */
class MocEvalT
{
public:
// -- predefines file
cmFileTime PredefsTime;
// -- Mappings
MappingMapT HeaderMappings;
MappingMapT SourceMappings;
MappingMapT Includes;
// -- Discovered files
SourceFileMapT HeadersDiscovered;
// -- Output directories
std::unordered_set<std::string> OutputDirs;
// -- Mocs compilation
bool CompUpdated = false;
std::vector<std::string> CompFiles;
};
/** Uic settings. */
class UicSettingsT
{
public:
struct UiFile
{
std::vector<std::string> Options;
};
public:
UicSettingsT();
~UicSettingsT();
UicSettingsT(UicSettingsT const&) = delete;
UicSettingsT& operator=(UicSettingsT const&) = delete;
// -- Const methods
bool skipped(std::string const& fileName) const;
// -- Attributes
bool Enabled = false;
bool SettingsChanged = false;
cmFileTime ExecutableTime;
std::string Executable;
std::unordered_set<std::string> SkipList;
std::vector<std::string> Options;
std::unordered_map<std::string, UiFile> UiFiles;
std::vector<std::string> SearchPaths;
cmsys::RegularExpression RegExpInclude;
};
/** Uic shared variables. */
class UicEvalT
{
public:
// -- Discovered files
SourceFileMapT UiFiles;
// -- Mappings
MappingMapT Includes;
// -- Output directories
std::unordered_set<std::string> OutputDirs;
};
/** Abstract job class for concurrent job processing. */
class JobT : public cmWorkerPool::JobT
{
protected:
/** Protected default constructor. */
JobT(bool fence = false)
: cmWorkerPool::JobT(fence)
{
}
//! Get the generator. Only valid during Process() call!
cmQtAutoMocUic* Gen() const
{
return static_cast<cmQtAutoMocUic*>(UserData());
};
// -- Accessors. Only valid during Process() call!
Logger const& Log() const { return Gen()->Log(); }
BaseSettingsT const& BaseConst() const { return Gen()->BaseConst(); }
BaseEvalT& BaseEval() const { return Gen()->BaseEval(); }
MocSettingsT const& MocConst() const { return Gen()->MocConst(); }
MocEvalT& MocEval() const { return Gen()->MocEval(); }
UicSettingsT const& UicConst() const { return Gen()->UicConst(); }
UicEvalT& UicEval() const { return Gen()->UicEval(); }
// -- Logging
std::string MessagePath(cm::string_view path) const
{
return Gen()->MessagePath(path);
}
// - Error logging with automatic abort
void LogError(GenT genType, cm::string_view message) const;
void LogCommandError(GenT genType, cm::string_view message,
std::vector<std::string> const& command,
std::string const& output) const;
/** @brief Run an external process. Use only during Process() call! */
bool RunProcess(GenT genType, cmWorkerPool::ProcessResultT& result,
std::vector<std::string> const& command,
std::string* infoMessage = nullptr);
};
/** Fence job utility class. */
class JobFenceT : public JobT
{
public:
JobFenceT()
: JobT(true)
{
}
void Process() override{};
};
/** Generate moc_predefs.h. */
class JobMocPredefsT : public JobFenceT
{
void Process() override;
bool Update(std::string* reason) const;
};
/** File parse job base class. */
class JobParseT : public JobT
{
public:
JobParseT(SourceFileHandleT fileHandle)
: FileHandle(std::move(fileHandle))
{
}
protected:
bool ReadFile();
void CreateKeys(std::vector<IncludeKeyT>& container,
std::set<std::string> const& source,
std::size_t basePrefixLength);
void MocMacro();
void MocDependecies();
void MocIncludes();
void UicIncludes();
protected:
SourceFileHandleT FileHandle;
std::string Content;
};
/** Header file parse job. */
class JobParseHeaderT : public JobParseT
{
public:
using JobParseT::JobParseT;
void Process() override;
};
/** Source file parse job. */
class JobParseSourceT : public JobParseT
{
public:
using JobParseT::JobParseT;
void Process() override;
};
/** Evaluate cached file parse data - moc. */
class JobEvalCacheT : public JobT
{
protected:
std::string MessageSearchLocations() const;
std::vector<std::string> SearchLocations;
};
/** Evaluate cached file parse data - moc. */
class JobEvalCacheMocT : public JobEvalCacheT
{
void Process() override;
bool EvalHeader(SourceFileHandleT source);
bool EvalSource(SourceFileHandleT const& source);
bool FindIncludedHeader(SourceFileHandleT& headerHandle,
cm::string_view includerDir,
cm::string_view includeBase);
bool RegisterIncluded(std::string const& includeString,
SourceFileHandleT includerFileHandle,
SourceFileHandleT sourceFileHandle) const;
void RegisterMapping(MappingHandleT mappingHandle) const;
std::string MessageHeader(cm::string_view headerBase) const;
};
/** Evaluate cached file parse data - uic. */
class JobEvalCacheUicT : public JobEvalCacheT
{
void Process() override;
bool EvalFile(SourceFileHandleT const& sourceFileHandle);
bool FindIncludedUi(cm::string_view sourceDirPrefix,
cm::string_view includePrefix);
bool RegisterMapping(std::string const& includeString,
SourceFileHandleT includerFileHandle);
std::string UiName;
SourceFileHandleT UiFileHandle;
};
/** Evaluate cached file parse data - finish */
class JobEvalCacheFinishT : public JobFenceT
{
void Process() override;
};
/** Dependency probing base job. */
class JobProbeDepsT : public JobT
{
};
/** Probes file dependencies and generates moc compile jobs. */
class JobProbeDepsMocT : public JobProbeDepsT
{
void Process() override;
bool Generate(MappingHandleT const& mapping, bool compFile) const;
bool Probe(MappingT const& mapping, std::string* reason) const;
std::pair<std::string, cmFileTime> FindDependency(
std::string const& sourceDir, std::string const& includeString) const;
};
/** Probes file dependencies and generates uic compile jobs. */
class JobProbeDepsUicT : public JobProbeDepsT
{
void Process() override;
bool Probe(MappingT const& mapping, std::string* reason) const;
};
/** Dependency probing finish job. */
class JobProbeDepsFinishT : public JobFenceT
{
void Process() override;
};
/** Meta compiler base job. */
class JobCompileT : public JobT
{
public:
JobCompileT(MappingHandleT uicMapping, std::unique_ptr<std::string> reason)
: Mapping(std::move(uicMapping))
, Reason(std::move(reason))
{
}
protected:
MappingHandleT Mapping;
std::unique_ptr<std::string> Reason;
};
/** moc compiles a file. */
class JobCompileMocT : public JobCompileT
{
public:
using JobCompileT::JobCompileT;
void Process() override;
};
/** uic compiles a file. */
class JobCompileUicT : public JobCompileT
{
public:
using JobCompileT::JobCompileT;
void Process() override;
};
/** Generate mocs_compilation.cpp. */
class JobMocsCompilationT : public JobFenceT
{
private:
void Process() override;
};
/** @brief The last job. */
class JobFinishT : public JobFenceT
{
private:
void Process() override;
};
// -- Const settings interface
BaseSettingsT const& BaseConst() const { return this->BaseConst_; }
BaseEvalT& BaseEval() { return this->BaseEval_; }
MocSettingsT const& MocConst() const { return this->MocConst_; }
MocEvalT& MocEval() { return this->MocEval_; }
UicSettingsT const& UicConst() const { return this->UicConst_; }
UicEvalT& UicEval() { return this->UicEval_; }
// -- Parallel job processing interface
cmWorkerPool& WorkerPool() { return WorkerPool_; }
void AbortError() { Abort(true); }
void AbortSuccess() { Abort(false); }
// -- Utility
std::string AbsoluteBuildPath(cm::string_view relativePath) const;
std::string AbsoluteIncludePath(cm::string_view relativePath) const;
template <class JOBTYPE>
void CreateParseJobs(SourceFileMapT const& sourceMap);
std::string CollapseFullPathTS(std::string const& path) const;
private:
// -- Abstract processing interface
bool InitFromInfo(InfoT const& info) override;
void InitJobs();
bool Process() override;
// -- Settings file
void SettingsFileRead();
bool SettingsFileWrite();
// -- Parse cache
void ParseCacheRead();
bool ParseCacheWrite();
// -- Thread processing
void Abort(bool error);
// -- Generation
bool CreateDirectories();
private:
// -- Settings
BaseSettingsT BaseConst_;
BaseEvalT BaseEval_;
MocSettingsT MocConst_;
MocEvalT MocEval_;
UicSettingsT UicConst_;
UicEvalT UicEval_;
// -- Settings file
std::string SettingsFile_;
std::string SettingsStringMoc_;
std::string SettingsStringUic_;
// -- Worker thread pool
std::atomic<bool> JobError_ = ATOMIC_VAR_INIT(false);
cmWorkerPool WorkerPool_;
// -- Concurrent processing
mutable std::mutex CMakeLibMutex_;
};
bool cmQtAutoMocUic(cm::string_view infoFile, cm::string_view config);
#endif

View File

@ -27,6 +27,7 @@
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
# include "bindexplib.h"
# include "cmFileTime.h"
# include "cmsys/ConsoleBuf.hxx"
#endif
@ -1059,10 +1060,9 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
#ifndef CMAKE_BOOTSTRAP
if ((args[1] == "cmake_autogen") && (args.size() >= 4)) {
cmQtAutoMocUic autoGen;
cm::string_view const infoFile = args[2];
cm::string_view const config = args[3];
return autoGen.Run(infoFile, config) ? 0 : 1;
return cmQtAutoMocUic(infoFile, config) ? 0 : 1;
}
if ((args[1] == "cmake_autorcc") && (args.size() >= 3)) {
cm::string_view const infoFile = args[2];