mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-02 03:39:43 -06:00
AUTOUIC: Revert "Fix generating of dependency rules for UI header files"
Revert commit e5ec0e52f4 (AUTOUIC: Fix generating of dependency rules
for UI header files, 2021-07-22, v3.21.1~8^2) because it caused
regressions. For example, changing one C++ source can now cause many
others to rebuild. Revert the change pending further investigation.
Fixes: #22531
Issue: #16776
This commit is contained in:
@@ -432,8 +432,6 @@ set(SRCS
|
||||
cmQtAutoMocUic.h
|
||||
cmQtAutoRcc.cxx
|
||||
cmQtAutoRcc.h
|
||||
cmQtAutoUicHelpers.cxx
|
||||
cmQtAutoUicHelpers.h
|
||||
cmRST.cxx
|
||||
cmRST.h
|
||||
cmRuntimeDependencyArchive.cxx
|
||||
|
||||
@@ -384,39 +384,3 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmQtAutoGen::FileRead(std::string& content, std::string const& filename,
|
||||
std::string* error)
|
||||
{
|
||||
content.clear();
|
||||
if (!cmSystemTools::FileExists(filename, true)) {
|
||||
if (error != nullptr) {
|
||||
*error = "Not a file.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long const length = cmSystemTools::FileLength(filename);
|
||||
cmsys::ifstream ifs(filename.c_str(), (std::ios::in | std::ios::binary));
|
||||
|
||||
// Use lambda to save destructor calls of ifs
|
||||
return [&ifs, length, &content, error]() -> bool {
|
||||
if (!ifs) {
|
||||
if (error != nullptr) {
|
||||
*error = "Opening the file for reading failed.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
content.reserve(length);
|
||||
using IsIt = std::istreambuf_iterator<char>;
|
||||
content.assign(IsIt{ ifs }, IsIt{});
|
||||
if (!ifs) {
|
||||
content.clear();
|
||||
if (error != nullptr) {
|
||||
*error = "Reading from the file failed.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}();
|
||||
}
|
||||
|
||||
@@ -100,9 +100,6 @@ public:
|
||||
std::vector<std::string> const& newOpts,
|
||||
bool isQt5);
|
||||
|
||||
static bool FileRead(std::string& content, std::string const& filename,
|
||||
std::string* error = nullptr);
|
||||
|
||||
/** @class RccLister
|
||||
* @brief Lists files in qrc resource files
|
||||
*/
|
||||
|
||||
@@ -902,13 +902,6 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
// The reason is that their file names might be discovered from source files
|
||||
// at generation time.
|
||||
if (this->MocOrUicEnabled()) {
|
||||
std::set<std::string> uicIncludes;
|
||||
auto collectUicIncludes = [&](std::unique_ptr<cmSourceFile> const& sf) {
|
||||
std::string content;
|
||||
FileRead(content, sf->GetFullPath());
|
||||
this->AutoUicHelpers.CollectUicIncludes(uicIncludes, content);
|
||||
};
|
||||
|
||||
for (const auto& sf : this->Makefile->GetSourceFiles()) {
|
||||
// sf->GetExtension() is only valid after sf->ResolveFullPath() ...
|
||||
// Since we're iterating over source files that might be not in the
|
||||
@@ -921,10 +914,6 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
std::string const& extLower =
|
||||
cmSystemTools::LowerCase(sf->GetExtension());
|
||||
|
||||
bool const skipAutogen = sf->GetPropertyAsBool(kw.SKIP_AUTOGEN);
|
||||
bool const skipUic =
|
||||
(skipAutogen || sf->GetPropertyAsBool(kw.SKIP_AUTOUIC) ||
|
||||
!this->Uic.Enabled);
|
||||
if (cm->IsAHeaderExtension(extLower)) {
|
||||
if (!cm::contains(this->AutogenTarget.Headers, sf.get())) {
|
||||
auto muf = makeMUFile(sf.get(), fullPath, {}, false);
|
||||
@@ -932,9 +921,6 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
addMUHeader(std::move(muf), extLower);
|
||||
}
|
||||
}
|
||||
if (!skipUic && !sf->GetIsGenerated()) {
|
||||
collectUicIncludes(sf);
|
||||
}
|
||||
} else if (cm->IsACLikeSourceExtension(extLower)) {
|
||||
if (!cm::contains(this->AutogenTarget.Sources, sf.get())) {
|
||||
auto muf = makeMUFile(sf.get(), fullPath, {}, false);
|
||||
@@ -942,11 +928,11 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
addMUSource(std::move(muf));
|
||||
}
|
||||
}
|
||||
if (!skipUic && !sf->GetIsGenerated()) {
|
||||
collectUicIncludes(sf);
|
||||
}
|
||||
} else if (this->Uic.Enabled && (extLower == kw.ui)) {
|
||||
// .ui file
|
||||
bool const skipAutogen = sf->GetPropertyAsBool(kw.SKIP_AUTOGEN);
|
||||
bool const skipUic =
|
||||
(skipAutogen || sf->GetPropertyAsBool(kw.SKIP_AUTOUIC));
|
||||
if (!skipUic) {
|
||||
// Check if the .ui file has uic options
|
||||
std::string const uicOpts = sf->GetSafeProperty(kw.AUTOUIC_OPTIONS);
|
||||
@@ -956,22 +942,35 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
this->Uic.UiFilesWithOptions.emplace_back(fullPath,
|
||||
cmExpandedList(uicOpts));
|
||||
}
|
||||
|
||||
auto uiHeaderRelativePath = cmSystemTools::RelativePath(
|
||||
this->LocalGen->GetCurrentSourceDirectory(),
|
||||
cmSystemTools::GetFilenamePath(fullPath));
|
||||
|
||||
// Avoid creating a path containing adjacent slashes
|
||||
if (!uiHeaderRelativePath.empty() &&
|
||||
uiHeaderRelativePath.back() != '/') {
|
||||
uiHeaderRelativePath += '/';
|
||||
}
|
||||
|
||||
auto uiHeaderFilePath = cmStrCat(
|
||||
'/', uiHeaderRelativePath, "ui_"_s,
|
||||
cmSystemTools::GetFilenameWithoutLastExtension(fullPath), ".h"_s);
|
||||
|
||||
ConfigString uiHeader;
|
||||
std::string uiHeaderGenex;
|
||||
this->ConfigFileNamesAndGenex(
|
||||
uiHeader, uiHeaderGenex, cmStrCat(this->Dir.Build, "/include"_s),
|
||||
uiHeaderFilePath);
|
||||
|
||||
this->Uic.UiHeaders.emplace_back(
|
||||
std::make_pair(uiHeader, uiHeaderGenex));
|
||||
} else {
|
||||
// Register skipped .ui file
|
||||
this->Uic.SkipUi.insert(fullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& include : uicIncludes) {
|
||||
ConfigString uiHeader;
|
||||
std::string uiHeaderGenex;
|
||||
this->ConfigFileNamesAndGenex(uiHeader, uiHeaderGenex,
|
||||
cmStrCat(this->Dir.Build, "/include"_s),
|
||||
cmStrCat("/"_s, include));
|
||||
this->Uic.UiHeaders.emplace_back(
|
||||
std::make_pair(uiHeader, uiHeaderGenex));
|
||||
}
|
||||
}
|
||||
|
||||
// Process GENERATED sources and headers
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include "cmFilePathChecksum.h"
|
||||
#include "cmQtAutoGen.h"
|
||||
#include "cmQtAutoUicHelpers.h"
|
||||
|
||||
class cmGeneratorTarget;
|
||||
class cmGlobalGenerator;
|
||||
@@ -171,7 +170,6 @@ private:
|
||||
std::string ConfigDefault;
|
||||
std::vector<std::string> ConfigsList;
|
||||
std::string TargetsFolder;
|
||||
cmQtAutoUicHelpers AutoUicHelpers;
|
||||
|
||||
/** Common directories. */
|
||||
struct
|
||||
|
||||
@@ -121,6 +121,43 @@ bool cmQtAutoGenerator::MakeParentDirectory(std::string const& filename)
|
||||
return success;
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileRead(std::string& content,
|
||||
std::string const& filename,
|
||||
std::string* error)
|
||||
{
|
||||
content.clear();
|
||||
if (!cmSystemTools::FileExists(filename, true)) {
|
||||
if (error != nullptr) {
|
||||
*error = "Not a file.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long const length = cmSystemTools::FileLength(filename);
|
||||
cmsys::ifstream ifs(filename.c_str(), (std::ios::in | std::ios::binary));
|
||||
|
||||
// Use lambda to save destructor calls of ifs
|
||||
return [&ifs, length, &content, error]() -> bool {
|
||||
if (!ifs) {
|
||||
if (error != nullptr) {
|
||||
*error = "Opening the file for reading failed.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
content.reserve(length);
|
||||
using IsIt = std::istreambuf_iterator<char>;
|
||||
content.assign(IsIt{ ifs }, IsIt{});
|
||||
if (!ifs) {
|
||||
content.clear();
|
||||
if (error != nullptr) {
|
||||
*error = "Reading from the file failed.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}();
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileWrite(std::string const& filename,
|
||||
std::string const& content,
|
||||
std::string* error)
|
||||
|
||||
@@ -70,6 +70,8 @@ public:
|
||||
|
||||
// -- File system methods
|
||||
static bool MakeParentDirectory(std::string const& filename);
|
||||
static bool FileRead(std::string& content, std::string const& filename,
|
||||
std::string* error = nullptr);
|
||||
static bool FileWrite(std::string const& filename,
|
||||
std::string const& content,
|
||||
std::string* error = nullptr);
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmQtAutoGen.h"
|
||||
#include "cmQtAutoGenerator.h"
|
||||
#include "cmQtAutoUicHelpers.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmWorkerPool.h"
|
||||
@@ -282,7 +281,7 @@ public:
|
||||
std::vector<std::string> Options;
|
||||
std::unordered_map<std::string, UiFile> UiFiles;
|
||||
std::vector<std::string> SearchPaths;
|
||||
cmQtAutoUicHelpers AutoUicHelpers;
|
||||
cmsys::RegularExpression RegExpInclude;
|
||||
};
|
||||
|
||||
/** Uic shared variables. */
|
||||
@@ -762,7 +761,11 @@ std::string cmQtAutoMocUicT::MocSettingsT::MacrosString() const
|
||||
return res;
|
||||
}
|
||||
|
||||
cmQtAutoMocUicT::UicSettingsT::UicSettingsT() = default;
|
||||
cmQtAutoMocUicT::UicSettingsT::UicSettingsT()
|
||||
{
|
||||
this->RegExpInclude.compile("(^|\n)[ \t]*#[ \t]*include[ \t]+"
|
||||
"[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
|
||||
}
|
||||
|
||||
cmQtAutoMocUicT::UicSettingsT::~UicSettingsT() = default;
|
||||
|
||||
@@ -1053,7 +1056,16 @@ void cmQtAutoMocUicT::JobParseT::UicIncludes()
|
||||
}
|
||||
|
||||
std::set<std::string> includes;
|
||||
this->UicConst().AutoUicHelpers.CollectUicIncludes(includes, this->Content);
|
||||
{
|
||||
const char* contentChars = this->Content.c_str();
|
||||
cmsys::RegularExpression const& regExp = this->UicConst().RegExpInclude;
|
||||
cmsys::RegularExpressionMatch match;
|
||||
while (regExp.find(contentChars, match)) {
|
||||
includes.emplace(match.match(2));
|
||||
// Forward content pointer
|
||||
contentChars += match.end();
|
||||
}
|
||||
}
|
||||
this->CreateKeys(this->FileHandle->ParseData->Uic.Include, includes,
|
||||
UiUnderscoreLength);
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmQtAutoUicHelpers.h"
|
||||
|
||||
cmQtAutoUicHelpers::cmQtAutoUicHelpers()
|
||||
{
|
||||
RegExpInclude.compile("(^|\n)[ \t]*#[ \t]*include[ \t]+"
|
||||
"[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
|
||||
}
|
||||
|
||||
void cmQtAutoUicHelpers::CollectUicIncludes(std::set<std::string>& includes,
|
||||
const std::string& content) const
|
||||
{
|
||||
if (content.find("ui_") == std::string::npos) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char* contentChars = content.c_str();
|
||||
cmsys::RegularExpressionMatch match;
|
||||
while (this->RegExpInclude.find(contentChars, match)) {
|
||||
includes.emplace(match.match(2));
|
||||
// Forward content pointer
|
||||
contentChars += match.end();
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "cmsys/RegularExpression.hxx"
|
||||
|
||||
class cmQtAutoUicHelpers
|
||||
{
|
||||
public:
|
||||
cmQtAutoUicHelpers();
|
||||
virtual ~cmQtAutoUicHelpers() = default;
|
||||
void CollectUicIncludes(std::set<std::string>& includes,
|
||||
const std::string& content) const;
|
||||
|
||||
private:
|
||||
cmsys::RegularExpression RegExpInclude;
|
||||
};
|
||||
@@ -28,12 +28,10 @@ endmacro()
|
||||
configure_file("${testProjectTemplateDir}/mocwidget.h" "${testProjectSrc}/mocwidget.h" COPYONLY)
|
||||
configure_file("${testProjectTemplateDir}/mainwindow.h" "${testProjectSrc}/mainwindow.h" COPYONLY)
|
||||
configure_file("${testProjectTemplateDir}/main.cpp" "${testProjectSrc}/main.cpp" COPYONLY)
|
||||
configure_file("${testProjectTemplateDir}/subdir/subdircheck.cpp" "${testProjectSrc}/subdir/subdircheck.cpp" COPYONLY)
|
||||
configure_file("${testProjectTemplateDir}/CMakeLists.txt.in" "${testProjectSrc}/CMakeLists.txt" @ONLY)
|
||||
|
||||
set(Num 1)
|
||||
configure_file("${testProjectTemplateDir}/mainwindow.ui.in" "${testProjectSrc}/mainwindow.ui" @ONLY)
|
||||
configure_file("${testProjectTemplateDir}/subdir/mainwindowsubdir.ui.in" "${testProjectSrc}/subdir/mainwindowsubdir.ui" @ONLY)
|
||||
|
||||
if(CMAKE_GENERATOR_INSTANCE)
|
||||
set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE=${CMAKE_GENERATOR_INSTANCE}")
|
||||
@@ -97,7 +95,6 @@ sleep()
|
||||
|
||||
set(Num 2)
|
||||
configure_file("${testProjectTemplateDir}/mainwindow.ui.in" "${testProjectSrc}/mainwindow.ui" @ONLY)
|
||||
configure_file("${testProjectTemplateDir}/subdir/mainwindowsubdir.ui.in" "${testProjectSrc}/subdir/mainwindowsubdir.ui" @ONLY)
|
||||
rebuild(2)
|
||||
|
||||
execute_process(COMMAND "${testProjectBinDir}/${extra_bin_path}UicOnFileChange" RESULT_VARIABLE result)
|
||||
|
||||
@@ -8,7 +8,6 @@ set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
add_executable(UicOnFileChange main.cpp mainwindow.ui mainwindow.h
|
||||
subdir/subdircheck.cpp subdir/mainwindowsubdir.ui
|
||||
)
|
||||
target_include_directories(UicOnFileChange PRIVATE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
extern bool subdircheck();
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
MocWidget mw;
|
||||
Ui::Widget mwUi;
|
||||
mwUi.setupUi(&mw);
|
||||
return mw.objectName() == "Widget2" && subdircheck() ? 0 : 1;
|
||||
return mw.objectName() == "Widget2" ? 0 : 1;
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>WidgetSubdir</class>
|
||||
<widget class="MocWidget" name="WidgetSubdir@Num@"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,9 +0,0 @@
|
||||
#include "ui_mainwindowsubdir.h"
|
||||
|
||||
bool subdircheck()
|
||||
{
|
||||
MocWidget mw;
|
||||
Ui::WidgetSubdir mwUi;
|
||||
mwUi.setupUi(&mw);
|
||||
return mw.objectName() == "WidgetSubdir2";
|
||||
}
|
||||
Reference in New Issue
Block a user