summaryrefslogtreecommitdiffstats
path: root/Source/cmQtAutoGenerator.cxx
diff options
context:
space:
mode:
authorSebastian Holtermann <sebholt@xwmw.org>2019-05-02 09:03:13 (GMT)
committerSebastian Holtermann <sebholt@xwmw.org>2019-05-07 10:42:19 (GMT)
commit7d50e1c6118b292ea3061ec9fee0230c5d50a5ff (patch)
tree48d3f4c459c88cc2c02fa78b0279324e2fbb5cce /Source/cmQtAutoGenerator.cxx
parentc6f6e2b3053de02de149e80bd6a0f686a6731f68 (diff)
downloadCMake-7d50e1c6118b292ea3061ec9fee0230c5d50a5ff.zip
CMake-7d50e1c6118b292ea3061ec9fee0230c5d50a5ff.tar.gz
CMake-7d50e1c6118b292ea3061ec9fee0230c5d50a5ff.tar.bz2
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"
Diffstat (limited to 'Source/cmQtAutoGenerator.cxx')
-rw-r--r--Source/cmQtAutoGenerator.cxx201
1 files changed, 25 insertions, 176 deletions
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index 6fbea82..f7e377d 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -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;