mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-27 01:19:31 -05:00
Autogen: Refactor AUTOMOC and AUTOUIC and add source file parse data caching
New features ------------ CMake's `AUTOMOC` and `AUTOUIC` now cache information extracted when parsing source files in `CMakeFiles/<ORIGIN>_autogen.dir/ParseCache.txt`. This leads to faster `<ORIGIN>_autogen` target rebuilds, because source files will be parsed again only if they're newer than the `ParseCache.txt` file. The parse cache will be recomputed if it is older than the CMake executable. `AUTOMOC` and `AUTOUIC` now check if `moc` or `uic` output files are older than the `moc` or `uic` executable. If an output file is older than the compiler, it will be regenerated. Therefore if a new `moc` or `uic` version is installed, all output files will be regenerated. `AUTOMOC` and `AUTOUIC` error and warning messages are more detailed. Internal changes ---------------- `moc` and `uic` output file names are not computed in the `_autogen` target anymore but in `cmQtAutoGenInitializer`. This makes the available at the configuration stage for improved dependency computations (to be done). In `AutogenInfo.cmake`, equally sized lists for "source file names", "source file flags" and "compiler output file names" are passed to the `_autogen` target. This replaces the separate file lists for `AUTOMOC` and `AUTOUIC`. Files times are read from the file system only once by using `cmFileTime` instances instead of `cmQtAutoGenerator::FileSystem::FileIsOlderThan` calls. All calls to not thread safe file system functions are moved to non concurrent fence jobs (see `cmWorkerPool::JobT::IsFence()`). This renders the `cmQtAutoGenerator::FileSystem` wrapper class obsolete and it is removed. Instead of composing a single large settings string that is fed to the `cmCryptoHash`, now all setting sub strings are fed one by one to the `cmCryptoHash` and the finalized result is stored. The `std::mutex` in `cmQtAutoGenerator::Logger` is tagged `mutable` and most `cmQtAutoGenerator::Logger` methods become `const`. Outlook ------- This patch provides the framework required to - extract dependencies from `.ui` files in `AUTOUIC`. These will help to address issue #15420 "AUTOUIC: Track uic external inputs". - generate adaptive `make` and `ninja` files in the `_autogen` target. These will help to address issue #16776 "AUTOUIC: Ninja needs two passes to correctly build Qt project". - generate (possibly empty) `moc` and `uic` files for all headers instead of a `mocs_compilation.cpp` file. This will help to address issue #17277 "AUTOMOC: Provide a option to allow AUTOMOC to compile individual " "moc_x.cxx instead of including all in mocs_compilation.cxx"
This commit is contained in:
@@ -194,11 +194,11 @@ std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command)
|
||||
|
||||
std::string cmQtAutoGen::SubDirPrefix(std::string const& filename)
|
||||
{
|
||||
std::string res(cmSystemTools::GetFilenamePath(filename));
|
||||
if (!res.empty()) {
|
||||
res += '/';
|
||||
std::string::size_type slash_pos = filename.rfind('/');
|
||||
if (slash_pos == std::string::npos) {
|
||||
return std::string();
|
||||
}
|
||||
return res;
|
||||
return filename.substr(0, slash_pos + 1);
|
||||
}
|
||||
|
||||
std::string cmQtAutoGen::AppendFilenameSuffix(std::string const& filename,
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -77,7 +78,8 @@ static std::string FileProjectRelativePath(cmMakefile* makefile,
|
||||
return res;
|
||||
}
|
||||
|
||||
/* @brief Tests if targetDepend is a STATIC_LIBRARY and if any of its
|
||||
/**
|
||||
* Tests if targetDepend is a STATIC_LIBRARY and if any of its
|
||||
* recursive STATIC_LIBRARY dependencies depends on targetOrigin
|
||||
* (STATIC_LIBRARY cycle).
|
||||
*/
|
||||
@@ -384,6 +386,10 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
|
||||
} else {
|
||||
AddCleanFile(makefile, this->AutogenTarget.SettingsFile);
|
||||
}
|
||||
|
||||
this->AutogenTarget.ParseCacheFile = this->Dir.Info;
|
||||
this->AutogenTarget.ParseCacheFile += "/ParseCache.txt";
|
||||
AddCleanFile(makefile, this->AutogenTarget.ParseCacheFile);
|
||||
}
|
||||
|
||||
// Autogen target: Compute user defined dependencies
|
||||
@@ -1255,53 +1261,107 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
|
||||
ofs.Write("AM_INCLUDE_DIR", this->Dir.Include);
|
||||
ofs.WriteConfig("AM_INCLUDE_DIR", this->Dir.ConfigInclude);
|
||||
|
||||
// Use sorted sets
|
||||
std::set<std::string> headers;
|
||||
std::set<std::string> sources;
|
||||
std::set<std::string> moc_headers;
|
||||
std::set<std::string> moc_sources;
|
||||
std::vector<std::string> headers;
|
||||
std::vector<std::string> headersFlags;
|
||||
std::vector<std::string> headersBuildPaths;
|
||||
std::vector<std::string> sources;
|
||||
std::vector<std::string> sourcesFlags;
|
||||
std::set<std::string> moc_skip;
|
||||
std::set<std::string> uic_headers;
|
||||
std::set<std::string> uic_sources;
|
||||
std::set<std::string> uic_skip;
|
||||
|
||||
// Filter headers
|
||||
for (auto const& pair : this->AutogenTarget.Headers) {
|
||||
MUFile const& muf = *pair.second;
|
||||
if (muf.Generated && !this->CMP0071Accept) {
|
||||
continue;
|
||||
{
|
||||
auto headerCount = this->AutogenTarget.Headers.size();
|
||||
headers.reserve(headerCount);
|
||||
headersFlags.reserve(headerCount);
|
||||
|
||||
std::vector<MUFile const*> sortedHeaders;
|
||||
{
|
||||
sortedHeaders.reserve(headerCount);
|
||||
for (auto const& pair : this->AutogenTarget.Headers) {
|
||||
sortedHeaders.emplace_back(pair.second.get());
|
||||
}
|
||||
std::sort(sortedHeaders.begin(), sortedHeaders.end(),
|
||||
[](MUFile const* a, MUFile const* b) {
|
||||
return (a->RealPath < b->RealPath);
|
||||
});
|
||||
}
|
||||
if (muf.SkipMoc) {
|
||||
moc_skip.insert(muf.RealPath);
|
||||
}
|
||||
if (muf.SkipUic) {
|
||||
uic_skip.insert(muf.RealPath);
|
||||
}
|
||||
if (muf.MocIt && muf.UicIt) {
|
||||
headers.insert(muf.RealPath);
|
||||
} else if (muf.MocIt) {
|
||||
moc_headers.insert(muf.RealPath);
|
||||
} else if (muf.UicIt) {
|
||||
uic_headers.insert(muf.RealPath);
|
||||
|
||||
for (MUFile const* const muf : sortedHeaders) {
|
||||
if (muf->Generated && !this->CMP0071Accept) {
|
||||
continue;
|
||||
}
|
||||
if (muf->SkipMoc) {
|
||||
moc_skip.insert(muf->RealPath);
|
||||
}
|
||||
if (muf->SkipUic) {
|
||||
uic_skip.insert(muf->RealPath);
|
||||
}
|
||||
if (muf->MocIt || muf->UicIt) {
|
||||
headers.emplace_back(muf->RealPath);
|
||||
std::string flags;
|
||||
flags += muf->MocIt ? 'M' : 'm';
|
||||
flags += muf->UicIt ? 'U' : 'u';
|
||||
headersFlags.emplace_back(std::move(flags));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Header build paths
|
||||
{
|
||||
cmFilePathChecksum const fpathCheckSum(makefile);
|
||||
std::unordered_set<std::string> emitted;
|
||||
for (std::string const& hdr : headers) {
|
||||
std::string basePath = fpathCheckSum.getPart(hdr);
|
||||
basePath += "/moc_";
|
||||
basePath += cmSystemTools::GetFilenameWithoutLastExtension(hdr);
|
||||
for (unsigned int ii = 1; ii != 1024; ++ii) {
|
||||
std::string path = basePath;
|
||||
if (ii > 1) {
|
||||
path += '_';
|
||||
path += std::to_string(ii);
|
||||
}
|
||||
path += ".cpp";
|
||||
if (emitted.emplace(path).second) {
|
||||
headersBuildPaths.emplace_back(std::move(path));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter sources
|
||||
for (auto const& pair : this->AutogenTarget.Sources) {
|
||||
MUFile const& muf = *pair.second;
|
||||
if (muf.Generated && !this->CMP0071Accept) {
|
||||
continue;
|
||||
{
|
||||
auto sourcesCount = this->AutogenTarget.Sources.size();
|
||||
sources.reserve(sourcesCount);
|
||||
sourcesFlags.reserve(sourcesCount);
|
||||
|
||||
std::vector<MUFile const*> sorted;
|
||||
sorted.reserve(sourcesCount);
|
||||
for (auto const& pair : this->AutogenTarget.Sources) {
|
||||
sorted.emplace_back(pair.second.get());
|
||||
}
|
||||
if (muf.SkipMoc) {
|
||||
moc_skip.insert(muf.RealPath);
|
||||
}
|
||||
if (muf.SkipUic) {
|
||||
uic_skip.insert(muf.RealPath);
|
||||
}
|
||||
if (muf.MocIt && muf.UicIt) {
|
||||
sources.insert(muf.RealPath);
|
||||
} else if (muf.MocIt) {
|
||||
moc_sources.insert(muf.RealPath);
|
||||
} else if (muf.UicIt) {
|
||||
uic_sources.insert(muf.RealPath);
|
||||
std::sort(sorted.begin(), sorted.end(),
|
||||
[](MUFile const* a, MUFile const* b) {
|
||||
return (a->RealPath < b->RealPath);
|
||||
});
|
||||
|
||||
for (MUFile const* const muf : sorted) {
|
||||
if (muf->Generated && !this->CMP0071Accept) {
|
||||
continue;
|
||||
}
|
||||
if (muf->SkipMoc) {
|
||||
moc_skip.insert(muf->RealPath);
|
||||
}
|
||||
if (muf->SkipUic) {
|
||||
uic_skip.insert(muf->RealPath);
|
||||
}
|
||||
if (muf->MocIt || muf->UicIt) {
|
||||
sources.emplace_back(muf->RealPath);
|
||||
std::string flags;
|
||||
flags += muf->MocIt ? 'M' : 'm';
|
||||
flags += muf->UicIt ? 'U' : 'u';
|
||||
sourcesFlags.emplace_back(std::move(flags));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1311,17 +1371,20 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
|
||||
ofs.Write("AM_QT_UIC_EXECUTABLE", this->Uic.Executable);
|
||||
|
||||
ofs.Write("# Files\n");
|
||||
ofs.Write("AM_CMAKE_EXECUTABLE", cmSystemTools::GetCMakeCommand());
|
||||
ofs.Write("AM_SETTINGS_FILE", this->AutogenTarget.SettingsFile);
|
||||
ofs.WriteConfig("AM_SETTINGS_FILE",
|
||||
this->AutogenTarget.ConfigSettingsFile);
|
||||
ofs.Write("AM_PARSE_CACHE_FILE", this->AutogenTarget.ParseCacheFile);
|
||||
ofs.WriteStrings("AM_HEADERS", headers);
|
||||
ofs.WriteStrings("AM_HEADERS_FLAGS", headersFlags);
|
||||
ofs.WriteStrings("AM_HEADERS_BUILD_PATHS", headersBuildPaths);
|
||||
ofs.WriteStrings("AM_SOURCES", sources);
|
||||
ofs.WriteStrings("AM_SOURCES_FLAGS", sourcesFlags);
|
||||
|
||||
// Write moc settings
|
||||
if (this->Moc.Enabled) {
|
||||
ofs.Write("# MOC settings\n");
|
||||
ofs.WriteStrings("AM_MOC_HEADERS", moc_headers);
|
||||
ofs.WriteStrings("AM_MOC_SOURCES", moc_sources);
|
||||
ofs.WriteStrings("AM_MOC_SKIP", moc_skip);
|
||||
ofs.WriteStrings("AM_MOC_DEFINITIONS", this->Moc.Defines);
|
||||
ofs.WriteConfigStrings("AM_MOC_DEFINITIONS", this->Moc.ConfigDefines);
|
||||
@@ -1343,8 +1406,6 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
|
||||
uic_skip.insert(this->Uic.SkipUi.begin(), this->Uic.SkipUi.end());
|
||||
|
||||
ofs.Write("# UIC settings\n");
|
||||
ofs.WriteStrings("AM_UIC_HEADERS", uic_headers);
|
||||
ofs.WriteStrings("AM_UIC_SOURCES", uic_sources);
|
||||
ofs.WriteStrings("AM_UIC_SKIP", uic_skip);
|
||||
ofs.WriteStrings("AM_UIC_TARGET_OPTIONS", this->Uic.Options);
|
||||
ofs.WriteConfigStrings("AM_UIC_TARGET_OPTIONS", this->Uic.ConfigOptions);
|
||||
|
||||
@@ -183,6 +183,7 @@ private:
|
||||
// Configuration files
|
||||
std::string InfoFile;
|
||||
std::string SettingsFile;
|
||||
std::string ParseCacheFile;
|
||||
std::map<std::string, std::string> ConfigSettingsFile;
|
||||
// Dependencies
|
||||
bool DependOrigin = false;
|
||||
|
||||
+25
-176
@@ -66,7 +66,8 @@ std::string cmQtAutoGenerator::Logger::HeadLine(std::string const& title)
|
||||
return head;
|
||||
}
|
||||
|
||||
void cmQtAutoGenerator::Logger::Info(GenT genType, std::string const& message)
|
||||
void cmQtAutoGenerator::Logger::Info(GenT genType,
|
||||
std::string const& message) const
|
||||
{
|
||||
std::string msg = GeneratorName(genType);
|
||||
msg += ": ";
|
||||
@@ -81,7 +82,7 @@ void cmQtAutoGenerator::Logger::Info(GenT genType, std::string const& message)
|
||||
}
|
||||
|
||||
void cmQtAutoGenerator::Logger::Warning(GenT genType,
|
||||
std::string const& message)
|
||||
std::string const& message) const
|
||||
{
|
||||
std::string msg;
|
||||
if (message.find('\n') == std::string::npos) {
|
||||
@@ -106,7 +107,7 @@ void cmQtAutoGenerator::Logger::Warning(GenT genType,
|
||||
|
||||
void cmQtAutoGenerator::Logger::WarningFile(GenT genType,
|
||||
std::string const& filename,
|
||||
std::string const& message)
|
||||
std::string const& message) const
|
||||
{
|
||||
std::string msg = " ";
|
||||
msg += Quoted(filename);
|
||||
@@ -116,7 +117,8 @@ void cmQtAutoGenerator::Logger::WarningFile(GenT genType,
|
||||
Warning(genType, msg);
|
||||
}
|
||||
|
||||
void cmQtAutoGenerator::Logger::Error(GenT genType, std::string const& message)
|
||||
void cmQtAutoGenerator::Logger::Error(GenT genType,
|
||||
std::string const& message) const
|
||||
{
|
||||
std::string msg;
|
||||
msg += HeadLine(GeneratorName(genType) + " error");
|
||||
@@ -134,7 +136,7 @@ void cmQtAutoGenerator::Logger::Error(GenT genType, std::string const& message)
|
||||
|
||||
void cmQtAutoGenerator::Logger::ErrorFile(GenT genType,
|
||||
std::string const& filename,
|
||||
std::string const& message)
|
||||
std::string const& message) const
|
||||
{
|
||||
std::string emsg = " ";
|
||||
emsg += Quoted(filename);
|
||||
@@ -146,7 +148,7 @@ void cmQtAutoGenerator::Logger::ErrorFile(GenT genType,
|
||||
|
||||
void cmQtAutoGenerator::Logger::ErrorCommand(
|
||||
GenT genType, std::string const& message,
|
||||
std::vector<std::string> const& command, std::string const& output)
|
||||
std::vector<std::string> const& command, std::string const& output) const
|
||||
{
|
||||
std::string msg;
|
||||
msg.push_back('\n');
|
||||
@@ -191,7 +193,7 @@ bool cmQtAutoGenerator::FileRead(std::string& content,
|
||||
content.clear();
|
||||
if (!cmSystemTools::FileExists(filename, true)) {
|
||||
if (error != nullptr) {
|
||||
error->append("Not a file.");
|
||||
*error = "Not a file.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -203,7 +205,7 @@ bool cmQtAutoGenerator::FileRead(std::string& content,
|
||||
return [&ifs, length, &content, error]() -> bool {
|
||||
if (!ifs) {
|
||||
if (error != nullptr) {
|
||||
error->append("Opening the file for reading failed.");
|
||||
*error = "Opening the file for reading failed.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -213,7 +215,7 @@ bool cmQtAutoGenerator::FileRead(std::string& content,
|
||||
if (!ifs) {
|
||||
content.clear();
|
||||
if (error != nullptr) {
|
||||
error->append("Reading from the file failed.");
|
||||
*error = "Reading from the file failed.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -228,7 +230,7 @@ bool cmQtAutoGenerator::FileWrite(std::string const& filename,
|
||||
// Make sure the parent directory exists
|
||||
if (!cmQtAutoGenerator::MakeParentDirectory(filename)) {
|
||||
if (error != nullptr) {
|
||||
error->assign("Could not create parent directory.");
|
||||
*error = "Could not create parent directory.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -240,14 +242,14 @@ bool cmQtAutoGenerator::FileWrite(std::string const& filename,
|
||||
return [&ofs, &content, error]() -> bool {
|
||||
if (!ofs) {
|
||||
if (error != nullptr) {
|
||||
error->assign("Opening file for writing failed.");
|
||||
*error = "Opening file for writing failed.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
ofs << content;
|
||||
if (!ofs.good()) {
|
||||
if (error != nullptr) {
|
||||
error->assign("File writing failed.");
|
||||
*error = "File writing failed.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -255,176 +257,17 @@ bool cmQtAutoGenerator::FileWrite(std::string const& filename,
|
||||
}();
|
||||
}
|
||||
|
||||
cmQtAutoGenerator::FileSystem::FileSystem() = default;
|
||||
|
||||
cmQtAutoGenerator::FileSystem::~FileSystem() = default;
|
||||
|
||||
std::string cmQtAutoGenerator::FileSystem::GetRealPath(
|
||||
std::string const& filename)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmSystemTools::GetRealPath(filename);
|
||||
}
|
||||
|
||||
std::string cmQtAutoGenerator::FileSystem::CollapseFullPath(
|
||||
std::string const& file, std::string const& dir)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmSystemTools::CollapseFullPath(file, dir);
|
||||
}
|
||||
|
||||
void cmQtAutoGenerator::FileSystem::SplitPath(
|
||||
const std::string& p, std::vector<std::string>& components,
|
||||
bool expand_home_dir)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
cmSystemTools::SplitPath(p, components, expand_home_dir);
|
||||
}
|
||||
|
||||
std::string cmQtAutoGenerator::FileSystem::JoinPath(
|
||||
const std::vector<std::string>& components)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmSystemTools::JoinPath(components);
|
||||
}
|
||||
|
||||
std::string cmQtAutoGenerator::FileSystem::JoinPath(
|
||||
std::vector<std::string>::const_iterator first,
|
||||
std::vector<std::string>::const_iterator last)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmSystemTools::JoinPath(first, last);
|
||||
}
|
||||
|
||||
std::string cmQtAutoGenerator::FileSystem::GetFilenameWithoutLastExtension(
|
||||
const std::string& filename)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmSystemTools::GetFilenameWithoutLastExtension(filename);
|
||||
}
|
||||
|
||||
std::string cmQtAutoGenerator::FileSystem::SubDirPrefix(
|
||||
std::string const& filename)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmQtAutoGen::SubDirPrefix(filename);
|
||||
}
|
||||
|
||||
void cmQtAutoGenerator::FileSystem::setupFilePathChecksum(
|
||||
std::string const& currentSrcDir, std::string const& currentBinDir,
|
||||
std::string const& projectSrcDir, std::string const& projectBinDir)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
FilePathChecksum_.setupParentDirs(currentSrcDir, currentBinDir,
|
||||
projectSrcDir, projectBinDir);
|
||||
}
|
||||
|
||||
std::string cmQtAutoGenerator::FileSystem::GetFilePathChecksum(
|
||||
std::string const& filename)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return FilePathChecksum_.getPart(filename);
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileSystem::FileExists(std::string const& filename)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmSystemTools::FileExists(filename);
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileSystem::FileExists(std::string const& filename,
|
||||
bool isFile)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmSystemTools::FileExists(filename, isFile);
|
||||
}
|
||||
|
||||
unsigned long cmQtAutoGenerator::FileSystem::FileLength(
|
||||
std::string const& filename)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmSystemTools::FileLength(filename);
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileSystem::FileIsOlderThan(
|
||||
std::string const& buildFile, std::string const& sourceFile,
|
||||
std::string* error)
|
||||
{
|
||||
bool res(false);
|
||||
int result = 0;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
res = cmSystemTools::FileTimeCompare(buildFile, sourceFile, &result);
|
||||
}
|
||||
if (res) {
|
||||
res = (result < 0);
|
||||
} else {
|
||||
if (error != nullptr) {
|
||||
error->append(
|
||||
"File modification time comparison failed for the files\n ");
|
||||
error->append(Quoted(buildFile));
|
||||
error->append("\nand\n ");
|
||||
error->append(Quoted(sourceFile));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileSystem::FileRead(std::string& content,
|
||||
std::string const& filename,
|
||||
std::string* error)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmQtAutoGenerator::FileRead(content, filename, error);
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileSystem::FileWrite(std::string const& filename,
|
||||
std::string const& content,
|
||||
std::string* error)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmQtAutoGenerator::FileWrite(filename, content, error);
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileSystem::FileDiffers(std::string const& filename,
|
||||
std::string const& content)
|
||||
bool cmQtAutoGenerator::FileDiffers(std::string const& filename,
|
||||
std::string const& content)
|
||||
{
|
||||
bool differs = true;
|
||||
{
|
||||
std::string oldContents;
|
||||
if (FileRead(oldContents, filename)) {
|
||||
differs = (oldContents != content);
|
||||
}
|
||||
std::string oldContents;
|
||||
if (FileRead(oldContents, filename) && (oldContents == content)) {
|
||||
differs = false;
|
||||
}
|
||||
return differs;
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileSystem::FileRemove(std::string const& filename)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmSystemTools::RemoveFile(filename);
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileSystem::Touch(std::string const& filename,
|
||||
bool create)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmSystemTools::Touch(filename, create);
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileSystem::MakeDirectory(std::string const& dirname)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmSystemTools::MakeDirectory(dirname);
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileSystem::MakeParentDirectory(
|
||||
std::string const& filename)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmQtAutoGenerator::MakeParentDirectory(filename);
|
||||
}
|
||||
|
||||
cmQtAutoGenerator::cmQtAutoGenerator() = default;
|
||||
|
||||
cmQtAutoGenerator::~cmQtAutoGenerator() = default;
|
||||
@@ -435,6 +278,12 @@ bool cmQtAutoGenerator::Run(std::string const& infoFile,
|
||||
// Info settings
|
||||
InfoFile_ = infoFile;
|
||||
cmSystemTools::ConvertToUnixSlashes(InfoFile_);
|
||||
if (!InfoFileTime_.Load(InfoFile_)) {
|
||||
std::string msg = "Autogen: The info file ";
|
||||
msg += Quoted(InfoFile_);
|
||||
msg += " is not readable\n";
|
||||
cmSystemTools::Stderr(msg);
|
||||
}
|
||||
InfoDir_ = cmSystemTools::GetFilenamePath(infoFile);
|
||||
InfoConfig_ = config;
|
||||
|
||||
|
||||
+19
-75
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include "cmFilePathChecksum.h"
|
||||
#include "cmFileTime.h"
|
||||
#include "cmQtAutoGen.h"
|
||||
|
||||
#include <mutex>
|
||||
@@ -14,13 +14,17 @@
|
||||
|
||||
class cmMakefile;
|
||||
|
||||
/// @brief Base class for QtAutoGen gernerators
|
||||
/** \class cmQtAutoGenerator
|
||||
* \brief Base class for QtAutoGen generators
|
||||
*/
|
||||
class cmQtAutoGenerator : public cmQtAutoGen
|
||||
{
|
||||
public:
|
||||
// -- Types
|
||||
|
||||
/// @brief Thread safe logging
|
||||
/**
|
||||
* Thread safe logger
|
||||
*/
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
@@ -37,24 +41,24 @@ public:
|
||||
bool ColorOutput() const { return this->ColorOutput_; }
|
||||
void SetColorOutput(bool value);
|
||||
// -- Log info
|
||||
void Info(GenT genType, std::string const& message);
|
||||
void Info(GenT genType, std::string const& message) const;
|
||||
// -- Log warning
|
||||
void Warning(GenT genType, std::string const& message);
|
||||
void Warning(GenT genType, std::string const& message) const;
|
||||
void WarningFile(GenT genType, std::string const& filename,
|
||||
std::string const& message);
|
||||
std::string const& message) const;
|
||||
// -- Log error
|
||||
void Error(GenT genType, std::string const& message);
|
||||
void Error(GenT genType, std::string const& message) const;
|
||||
void ErrorFile(GenT genType, std::string const& filename,
|
||||
std::string const& message);
|
||||
std::string const& message) const;
|
||||
void ErrorCommand(GenT genType, std::string const& message,
|
||||
std::vector<std::string> const& command,
|
||||
std::string const& output);
|
||||
std::string const& output) const;
|
||||
|
||||
private:
|
||||
static std::string HeadLine(std::string const& title);
|
||||
|
||||
private:
|
||||
std::mutex Mutex_;
|
||||
mutable std::mutex Mutex_;
|
||||
unsigned int Verbosity_ = 0;
|
||||
bool ColorOutput_ = false;
|
||||
};
|
||||
@@ -66,70 +70,8 @@ public:
|
||||
static bool FileWrite(std::string const& filename,
|
||||
std::string const& content,
|
||||
std::string* error = nullptr);
|
||||
|
||||
/// @brief Thread safe file system interface
|
||||
class FileSystem
|
||||
{
|
||||
public:
|
||||
FileSystem();
|
||||
~FileSystem();
|
||||
|
||||
// -- Paths
|
||||
/// @brief Wrapper for cmSystemTools::GetRealPath
|
||||
std::string GetRealPath(std::string const& filename);
|
||||
/// @brief Wrapper for cmSystemTools::CollapseFullPath
|
||||
std::string CollapseFullPath(std::string const& file,
|
||||
std::string const& dir);
|
||||
/// @brief Wrapper for cmSystemTools::SplitPath
|
||||
void SplitPath(const std::string& p, std::vector<std::string>& components,
|
||||
bool expand_home_dir = true);
|
||||
/// @brief Wrapper for cmSystemTools::JoinPath
|
||||
std::string JoinPath(const std::vector<std::string>& components);
|
||||
/// @brief Wrapper for cmSystemTools::JoinPath
|
||||
std::string JoinPath(std::vector<std::string>::const_iterator first,
|
||||
std::vector<std::string>::const_iterator last);
|
||||
/// @brief Wrapper for cmSystemTools::GetFilenameWithoutLastExtension
|
||||
std::string GetFilenameWithoutLastExtension(const std::string& filename);
|
||||
/// @brief Wrapper for cmQtAutoGen::SubDirPrefix
|
||||
std::string SubDirPrefix(std::string const& filename);
|
||||
/// @brief Wrapper for cmFilePathChecksum::setupParentDirs
|
||||
void setupFilePathChecksum(std::string const& currentSrcDir,
|
||||
std::string const& currentBinDir,
|
||||
std::string const& projectSrcDir,
|
||||
std::string const& projectBinDir);
|
||||
/// @brief Wrapper for cmFilePathChecksum::getPart
|
||||
std::string GetFilePathChecksum(std::string const& filename);
|
||||
|
||||
// -- File access
|
||||
/// @brief Wrapper for cmSystemTools::FileExists
|
||||
bool FileExists(std::string const& filename);
|
||||
/// @brief Wrapper for cmSystemTools::FileExists
|
||||
bool FileExists(std::string const& filename, bool isFile);
|
||||
/// @brief Wrapper for cmSystemTools::FileLength
|
||||
unsigned long FileLength(std::string const& filename);
|
||||
bool FileIsOlderThan(std::string const& buildFile,
|
||||
std::string const& sourceFile,
|
||||
std::string* error = nullptr);
|
||||
|
||||
bool FileRead(std::string& content, std::string const& filename,
|
||||
std::string* error = nullptr);
|
||||
|
||||
bool FileWrite(std::string const& filename, std::string const& content,
|
||||
std::string* error = nullptr);
|
||||
|
||||
bool FileDiffers(std::string const& filename, std::string const& content);
|
||||
|
||||
bool FileRemove(std::string const& filename);
|
||||
bool Touch(std::string const& filename, bool create = false);
|
||||
|
||||
// -- Directory access
|
||||
bool MakeDirectory(std::string const& dirname);
|
||||
bool MakeParentDirectory(std::string const& filename);
|
||||
|
||||
private:
|
||||
std::mutex Mutex_;
|
||||
cmFilePathChecksum FilePathChecksum_;
|
||||
};
|
||||
static bool FileDiffers(std::string const& filename,
|
||||
std::string const& content);
|
||||
|
||||
public:
|
||||
// -- Constructors
|
||||
@@ -142,8 +84,9 @@ public:
|
||||
// -- Run
|
||||
bool Run(std::string const& infoFile, std::string const& config);
|
||||
|
||||
// InfoFile
|
||||
// -- InfoFile
|
||||
std::string const& InfoFile() const { return InfoFile_; }
|
||||
cmFileTime const& InfoFileTime() const { return InfoFileTime_; }
|
||||
std::string const& InfoDir() const { return InfoDir_; }
|
||||
std::string const& InfoConfig() const { return InfoConfig_; }
|
||||
|
||||
@@ -158,6 +101,7 @@ protected:
|
||||
private:
|
||||
// -- Info settings
|
||||
std::string InfoFile_;
|
||||
cmFileTime InfoFileTime_;
|
||||
std::string InfoDir_;
|
||||
std::string InfoConfig_;
|
||||
};
|
||||
|
||||
+1679
-1228
File diff suppressed because it is too large
Load Diff
+340
-177
@@ -5,25 +5,28 @@
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include "cmFileTime.h"
|
||||
#include "cmQtAutoGen.h"
|
||||
#include "cmQtAutoGenerator.h"
|
||||
#include "cmWorkerPool.h"
|
||||
#include "cmsys/RegularExpression.hxx"
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <memory> // IWYU pragma: keep
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class cmMakefile;
|
||||
|
||||
// @brief AUTOMOC and AUTOUIC generator
|
||||
/** \class cmQtAutoMocUic
|
||||
* \brief AUTOMOC and AUTOUIC generator
|
||||
*/
|
||||
class cmQtAutoMocUic : public cmQtAutoGenerator
|
||||
{
|
||||
public:
|
||||
@@ -35,10 +38,10 @@ public:
|
||||
|
||||
public:
|
||||
// -- Types
|
||||
typedef std::multimap<std::string, std::array<std::string, 2>> IncludesMap;
|
||||
|
||||
/// @brief Search key plus regular expression pair
|
||||
///
|
||||
/**
|
||||
* Search key plus regular expression pair
|
||||
*/
|
||||
struct KeyExpT
|
||||
{
|
||||
KeyExpT() = default;
|
||||
@@ -59,35 +62,123 @@ public:
|
||||
cmsys::RegularExpression Exp;
|
||||
};
|
||||
|
||||
/// @brief Common settings
|
||||
///
|
||||
/**
|
||||
* 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
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
typedef std::shared_ptr<FileT> FileHandleT;
|
||||
typedef std::pair<FileHandleT, bool> GetOrInsertT;
|
||||
|
||||
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 Moc = false;
|
||||
bool Uic = false;
|
||||
};
|
||||
typedef std::shared_ptr<SourceFileT> SourceFileHandleT;
|
||||
typedef std::map<std::string, SourceFileHandleT> SourceFileMapT;
|
||||
|
||||
/**
|
||||
* Meta compiler file mapping information
|
||||
*/
|
||||
struct MappingT
|
||||
{
|
||||
SourceFileHandleT SourceFile;
|
||||
std::string OutputFile;
|
||||
std::string IncludeString;
|
||||
std::vector<SourceFileHandleT> IncluderFiles;
|
||||
};
|
||||
typedef std::shared_ptr<MappingT> MappingHandleT;
|
||||
typedef std::map<std::string, MappingHandleT> MappingMapT;
|
||||
|
||||
/**
|
||||
* Common settings
|
||||
*/
|
||||
class BaseSettingsT
|
||||
{
|
||||
public:
|
||||
// -- Volatile methods
|
||||
BaseSettingsT(FileSystem* fileSystem)
|
||||
: MultiConfig(false)
|
||||
, IncludeProjectDirsBefore(false)
|
||||
, QtVersionMajor(4)
|
||||
, NumThreads(1)
|
||||
, FileSys(fileSystem)
|
||||
{
|
||||
}
|
||||
// -- Constructors
|
||||
BaseSettingsT();
|
||||
~BaseSettingsT();
|
||||
|
||||
BaseSettingsT(BaseSettingsT const&) = delete;
|
||||
BaseSettingsT& operator=(BaseSettingsT const&) = delete;
|
||||
|
||||
// -- Const methods
|
||||
std::string AbsoluteBuildPath(std::string const& relativePath) const;
|
||||
bool FindHeader(std::string& header,
|
||||
std::string const& testBasePath) const;
|
||||
|
||||
// -- Attributes
|
||||
// - Config
|
||||
bool MultiConfig;
|
||||
bool IncludeProjectDirsBefore;
|
||||
unsigned int QtVersionMajor;
|
||||
unsigned int NumThreads;
|
||||
bool MultiConfig = false;
|
||||
bool IncludeProjectDirsBefore = false;
|
||||
unsigned int QtVersionMajor = 4;
|
||||
// - Directories
|
||||
std::string ProjectSourceDir;
|
||||
std::string ProjectBinaryDir;
|
||||
@@ -96,37 +187,50 @@ public:
|
||||
std::string AutogenBuildDir;
|
||||
std::string AutogenIncludeDir;
|
||||
// - Files
|
||||
std::string CMakeExecutable;
|
||||
cmFileTime CMakeExecutableTime;
|
||||
std::string ParseCacheFile;
|
||||
std::vector<std::string> HeaderExtensions;
|
||||
// - File system
|
||||
FileSystem* FileSys;
|
||||
};
|
||||
|
||||
/// @brief Moc settings
|
||||
///
|
||||
/**
|
||||
* 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:
|
||||
MocSettingsT(FileSystem* fileSys)
|
||||
: FileSys(fileSys)
|
||||
{
|
||||
}
|
||||
// -- Constructors
|
||||
MocSettingsT();
|
||||
~MocSettingsT();
|
||||
|
||||
MocSettingsT(MocSettingsT const&) = delete;
|
||||
MocSettingsT& operator=(MocSettingsT const&) = delete;
|
||||
|
||||
// -- 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;
|
||||
cmFileTime ExecutableTime;
|
||||
std::string Executable;
|
||||
std::string CompFileAbs;
|
||||
std::string PredefsFileRel;
|
||||
@@ -141,16 +245,35 @@ public:
|
||||
std::vector<KeyExpT> DependFilters;
|
||||
std::vector<KeyExpT> MacroFilters;
|
||||
cmsys::RegularExpression RegExpInclude;
|
||||
// - File system
|
||||
FileSystem* FileSys;
|
||||
};
|
||||
|
||||
/// @brief Uic settings
|
||||
///
|
||||
/**
|
||||
* Moc shared variables
|
||||
*/
|
||||
class MocEvalT
|
||||
{
|
||||
public:
|
||||
// -- predefines file
|
||||
cmFileTime PredefsTime;
|
||||
// -- Mappings
|
||||
MappingMapT HeaderMappings;
|
||||
MappingMapT SourceMappings;
|
||||
MappingMapT Includes;
|
||||
// -- Discovered files
|
||||
SourceFileMapT HeadersDiscovered;
|
||||
// -- Mocs compilation
|
||||
bool CompUpdated = false;
|
||||
std::vector<std::string> CompFiles;
|
||||
};
|
||||
|
||||
/**
|
||||
* Uic settings
|
||||
*/
|
||||
class UicSettingsT
|
||||
{
|
||||
public:
|
||||
UicSettingsT() = default;
|
||||
UicSettingsT();
|
||||
~UicSettingsT();
|
||||
|
||||
UicSettingsT(UicSettingsT const&) = delete;
|
||||
UicSettingsT& operator=(UicSettingsT const&) = delete;
|
||||
@@ -161,6 +284,7 @@ public:
|
||||
// -- Attributes
|
||||
bool Enabled = false;
|
||||
bool SettingsChanged = false;
|
||||
cmFileTime ExecutableTime;
|
||||
std::string Executable;
|
||||
std::unordered_set<std::string> SkipList;
|
||||
std::vector<std::string> TargetOptions;
|
||||
@@ -169,8 +293,19 @@ public:
|
||||
cmsys::RegularExpression RegExpInclude;
|
||||
};
|
||||
|
||||
/// @brief Abstract job class for concurrent job processing
|
||||
///
|
||||
/**
|
||||
* Uic shared variables
|
||||
*/
|
||||
class UicEvalT
|
||||
{
|
||||
public:
|
||||
SourceFileMapT UiFiles;
|
||||
MappingMapT Includes;
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract job class for concurrent job processing
|
||||
*/
|
||||
class JobT : public cmWorkerPool::JobT
|
||||
{
|
||||
protected:
|
||||
@@ -188,10 +323,14 @@ public:
|
||||
return static_cast<cmQtAutoMocUic*>(UserData());
|
||||
};
|
||||
|
||||
//! Get the file system interface. Only valid during Process() call!
|
||||
FileSystem& FileSys() { return Gen()->FileSys(); }
|
||||
//! Get the logger. Only valid during Process() call!
|
||||
Logger& Log() { return Gen()->Log(); }
|
||||
// -- 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(); }
|
||||
|
||||
// -- Error logging with automatic abort
|
||||
void LogError(GenT genType, std::string const& message) const;
|
||||
@@ -205,11 +344,13 @@ public:
|
||||
* @brief Run an external process. Use only during Process() call!
|
||||
*/
|
||||
bool RunProcess(GenT genType, cmWorkerPool::ProcessResultT& result,
|
||||
std::vector<std::string> const& command);
|
||||
std::vector<std::string> const& command,
|
||||
std::string* infoMessage = nullptr);
|
||||
};
|
||||
|
||||
/// @brief Fence job utility class
|
||||
///
|
||||
/**
|
||||
* Fence job utility class
|
||||
*/
|
||||
class JobFenceT : public JobT
|
||||
{
|
||||
public:
|
||||
@@ -220,58 +361,143 @@ public:
|
||||
void Process() override{};
|
||||
};
|
||||
|
||||
/// @brief Generate moc_predefs.h
|
||||
///
|
||||
class JobMocPredefsT : public JobT
|
||||
/**
|
||||
* Generate moc_predefs.h
|
||||
*/
|
||||
class JobMocPredefsT : public JobFenceT
|
||||
{
|
||||
private:
|
||||
void Process() override;
|
||||
bool Update(std::string* reason) const;
|
||||
};
|
||||
|
||||
/// @brief Parses a source file
|
||||
///
|
||||
/**
|
||||
* File parse job base class
|
||||
*/
|
||||
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)
|
||||
JobParseT(SourceFileHandleT fileHandle)
|
||||
: FileHandle(std::move(fileHandle))
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
struct MetaT
|
||||
{
|
||||
std::string Content;
|
||||
std::string FileDir;
|
||||
std::string FileBase;
|
||||
};
|
||||
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();
|
||||
|
||||
void Process() override;
|
||||
bool ParseMocSource(MetaT const& meta);
|
||||
bool ParseMocHeader(MetaT const& meta);
|
||||
std::string MocStringHeaders(std::string const& fileBase) const;
|
||||
std::string MocFindIncludedHeader(std::string const& includerDir,
|
||||
std::string const& includeBase);
|
||||
bool ParseUic(MetaT const& meta);
|
||||
bool ParseUicInclude(MetaT const& meta, std::string&& includeString);
|
||||
std::string UicFindIncludedFile(MetaT const& meta,
|
||||
std::string const& includeString);
|
||||
|
||||
private:
|
||||
std::string FileName;
|
||||
bool AutoMoc = false;
|
||||
bool AutoUic = false;
|
||||
bool Header = false;
|
||||
protected:
|
||||
SourceFileHandleT FileHandle;
|
||||
std::string Content;
|
||||
};
|
||||
|
||||
/// @brief Generates additional jobs after all files have been parsed
|
||||
///
|
||||
class JobPostParseT : public JobFenceT
|
||||
/**
|
||||
* Header file parse job
|
||||
*/
|
||||
class JobParseHeaderT : public JobParseT
|
||||
{
|
||||
private:
|
||||
public:
|
||||
using JobParseT::JobParseT;
|
||||
void Process() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Source file parse job
|
||||
*/
|
||||
class JobParseSourceT : public JobParseT
|
||||
{
|
||||
public:
|
||||
using JobParseT::JobParseT;
|
||||
void Process() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Evaluate parsed files
|
||||
*/
|
||||
class JobEvaluateT : public JobFenceT
|
||||
{
|
||||
void Process() override;
|
||||
|
||||
// -- Moc
|
||||
bool MocEvalHeader(SourceFileHandleT source);
|
||||
bool MocEvalSource(SourceFileHandleT const& source);
|
||||
SourceFileHandleT MocFindIncludedHeader(
|
||||
std::string const& includerDir, std::string const& includeBase) const;
|
||||
SourceFileHandleT MocFindHeader(std::string const& basePath) const;
|
||||
std::string MocMessageTestHeaders(std::string const& fileBase) const;
|
||||
bool MocRegisterIncluded(std::string const& includeString,
|
||||
SourceFileHandleT includerFileHandle,
|
||||
SourceFileHandleT sourceFileHandle,
|
||||
bool sourceIsHeader) const;
|
||||
void MocRegisterMapping(MappingHandleT mappingHandle,
|
||||
bool sourceIsHeader) const;
|
||||
|
||||
// -- Uic
|
||||
bool UicEval(SourceFileMapT const& fileMap);
|
||||
bool UicEvalFile(SourceFileHandleT sourceFileHandle);
|
||||
SourceFileHandleT UicFindIncludedUi(std::string const& sourceFile,
|
||||
std::string const& sourceDir,
|
||||
IncludeKeyT const& incKey) const;
|
||||
bool UicRegisterMapping(std::string const& includeString,
|
||||
SourceFileHandleT uiFileHandle,
|
||||
SourceFileHandleT includerFileHandle);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates moc/uic jobs
|
||||
*/
|
||||
class JobGenerateT : public JobFenceT
|
||||
{
|
||||
void Process() override;
|
||||
// -- Moc
|
||||
bool MocGenerate(MappingHandleT const& mapping, bool compFile) const;
|
||||
bool MocUpdate(MappingT const& mapping, std::string* reason) const;
|
||||
std::pair<std::string, cmFileTime> MocFindDependency(
|
||||
std::string const& sourceDir, std::string const& includeString) const;
|
||||
// -- Uic
|
||||
bool UicGenerate(MappingHandleT const& mapping) const;
|
||||
bool UicUpdate(MappingT const& mapping, std::string* reason) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* File compiling 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 JobMocT : public JobCompileT
|
||||
{
|
||||
public:
|
||||
using JobCompileT::JobCompileT;
|
||||
void Process() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* uic compiles a file
|
||||
*/
|
||||
class JobUicT : public JobCompileT
|
||||
{
|
||||
public:
|
||||
using JobCompileT::JobCompileT;
|
||||
void Process() override;
|
||||
};
|
||||
|
||||
@@ -283,60 +509,6 @@ public:
|
||||
void Process() override;
|
||||
};
|
||||
|
||||
/// @brief Moc a file job
|
||||
///
|
||||
class JobMocT : public JobT
|
||||
{
|
||||
public:
|
||||
JobMocT(std::string sourceFile, std::string includerFile,
|
||||
std::string includeString)
|
||||
: SourceFile(std::move(sourceFile))
|
||||
, IncluderFile(std::move(includerFile))
|
||||
, IncludeString(std::move(includeString))
|
||||
{
|
||||
}
|
||||
|
||||
void FindDependencies(std::string const& content);
|
||||
|
||||
private:
|
||||
void Process() override;
|
||||
bool UpdateRequired();
|
||||
void GenerateMoc();
|
||||
|
||||
public:
|
||||
std::string SourceFile;
|
||||
std::string IncluderFile;
|
||||
std::string IncludeString;
|
||||
std::string BuildFile;
|
||||
bool DependsValid = false;
|
||||
std::set<std::string> Depends;
|
||||
};
|
||||
|
||||
/// @brief Uic a file job
|
||||
///
|
||||
class JobUicT : public JobT
|
||||
{
|
||||
public:
|
||||
JobUicT(std::string sourceFile, std::string includerFile,
|
||||
std::string includeString)
|
||||
: SourceFile(std::move(sourceFile))
|
||||
, IncluderFile(std::move(includerFile))
|
||||
, IncludeString(std::move(includeString))
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void Process() override;
|
||||
bool UpdateRequired();
|
||||
void GenerateUic();
|
||||
|
||||
public:
|
||||
std::string SourceFile;
|
||||
std::string IncluderFile;
|
||||
std::string IncludeString;
|
||||
std::string BuildFile;
|
||||
};
|
||||
|
||||
/// @brief The last job
|
||||
///
|
||||
class JobFinishT : public JobFenceT
|
||||
@@ -346,39 +518,37 @@ public:
|
||||
};
|
||||
|
||||
// -- Const settings interface
|
||||
const BaseSettingsT& Base() const { return this->Base_; }
|
||||
const MocSettingsT& Moc() const { return this->Moc_; }
|
||||
const UicSettingsT& Uic() const { return this->Uic_; }
|
||||
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); }
|
||||
bool ParallelJobPushMoc(cmWorkerPool::JobHandleT&& jobHandle);
|
||||
bool ParallelJobPushUic(cmWorkerPool::JobHandleT&& jobHandle);
|
||||
|
||||
// -- Mocs compilation include file updated flag
|
||||
void ParallelMocAutoUpdated() { MocAutoFileUpdated_.store(true); }
|
||||
bool MocAutoFileUpdated() const { return MocAutoFileUpdated_.load(); }
|
||||
|
||||
// -- Mocs compilation file register
|
||||
std::string ParallelMocAutoRegister(std::string const& baseName);
|
||||
bool ParallelMocIncluded(std::string const& sourceFile);
|
||||
std::set<std::string> const& MocAutoFiles() const
|
||||
{
|
||||
return this->MocAutoFiles_;
|
||||
}
|
||||
// -- Utility
|
||||
std::string AbsoluteBuildPath(std::string const& relativePath) const;
|
||||
std::string AbsoluteIncludePath(std::string const& relativePath) const;
|
||||
template <class JOBTYPE>
|
||||
void CreateParseJobs(SourceFileMapT const& sourceMap);
|
||||
|
||||
private:
|
||||
// -- Utility accessors
|
||||
Logger& Log() { return Logger_; }
|
||||
FileSystem& FileSys() { return FileSys_; }
|
||||
Logger const& Log() const { return Logger_; }
|
||||
// -- Abstract processing interface
|
||||
bool Init(cmMakefile* makefile) 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
|
||||
@@ -387,25 +557,18 @@ private:
|
||||
private:
|
||||
// -- Utility
|
||||
Logger Logger_;
|
||||
FileSystem FileSys_;
|
||||
// -- Settings
|
||||
BaseSettingsT Base_;
|
||||
MocSettingsT Moc_;
|
||||
UicSettingsT Uic_;
|
||||
// -- Moc meta
|
||||
std::mutex MocMetaMutex_;
|
||||
std::set<std::string> MocIncludedFiles_;
|
||||
IncludesMap MocIncludes_;
|
||||
std::set<std::string> MocAutoFiles_;
|
||||
std::atomic<bool> MocAutoFileUpdated_ = ATOMIC_VAR_INIT(false);
|
||||
// -- Uic meta
|
||||
std::mutex UicMetaMutex_;
|
||||
IncludesMap UicIncludes_;
|
||||
BaseSettingsT BaseConst_;
|
||||
BaseEvalT BaseEval_;
|
||||
MocSettingsT MocConst_;
|
||||
MocEvalT MocEval_;
|
||||
UicSettingsT UicConst_;
|
||||
UicEvalT UicEval_;
|
||||
// -- Settings file
|
||||
std::string SettingsFile_;
|
||||
std::string SettingsStringMoc_;
|
||||
std::string SettingsStringUic_;
|
||||
// -- Thread pool and job queue
|
||||
// -- Worker thread pool
|
||||
std::atomic<bool> JobError_ = ATOMIC_VAR_INIT(false);
|
||||
cmWorkerPool WorkerPool_;
|
||||
};
|
||||
|
||||
@@ -57,7 +57,7 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile)
|
||||
}
|
||||
|
||||
// - Configurations
|
||||
Log().RaiseVerbosity(InfoGet("ARCC_VERBOSITY"));
|
||||
Logger_.RaiseVerbosity(InfoGet("ARCC_VERBOSITY"));
|
||||
MultiConfig_ = makefile->IsOn("ARCC_MULTI_CONFIG");
|
||||
|
||||
// - Directories
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
|
||||
private:
|
||||
// -- Utility
|
||||
Logger& Log() { return Logger_; }
|
||||
Logger const& Log() const { return Logger_; }
|
||||
bool IsMultiConfig() const { return MultiConfig_; }
|
||||
std::string MultiConfigOutput() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user