summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2013-07-25 07:24:53 (GMT)
committerStephen Kelly <steveire@gmail.com>2013-10-24 10:30:38 (GMT)
commit84218e1870ab075c9e2be1f2947358702c849fed (patch)
treebf9c4c40c03ef8d5e07340457969b5181b7ef458 /Source
parent94a0ca604ca6ba3699b6d309938e881b2a3984a0 (diff)
downloadCMake-84218e1870ab075c9e2be1f2947358702c849fed.zip
CMake-84218e1870ab075c9e2be1f2947358702c849fed.tar.gz
CMake-84218e1870ab075c9e2be1f2947358702c849fed.tar.bz2
Add automatic uic invocation for Qt.
The source files are already processed by cmQtAutomoc to look for moc includes, so extend that to also look for ui_ includes and find corresponding .ui files to process. This replaces the need to invoke qt4_wrap_ui(). As the ui files are not likely to be part of the SOURCES of the target, store the options associated with them separately in the cmMakefile for querying during the autogen run.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGlobalGenerator.cxx4
-rw-r--r--Source/cmMakefile.cxx12
-rw-r--r--Source/cmMakefile.h5
-rw-r--r--Source/cmQtAutoGenerators.cxx391
-rw-r--r--Source/cmQtAutoGenerators.h27
-rw-r--r--Source/cmSourceFile.cxx11
-rw-r--r--Source/cmTarget.cxx2
7 files changed, 438 insertions, 14 deletions
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 386af6d..3fb6848 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1225,7 +1225,9 @@ void cmGlobalGenerator::CreateQtAutoGeneratorsTargets()
target.GetType() == cmTarget::MODULE_LIBRARY ||
target.GetType() == cmTarget::OBJECT_LIBRARY)
{
- if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported())
+ if((target.GetPropertyAsBool("AUTOMOC")
+ || target.GetPropertyAsBool("AUTOUIC"))
+ && !target.IsImported())
{
cmQtAutoGenerators autogen;
if(autogen.InitializeMocSourceFile(&target))
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 13c43fa..df64ca6 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -4240,6 +4240,18 @@ bool cmMakefile::EnforceUniqueDir(const char* srcPath, const char* binPath)
}
//----------------------------------------------------------------------------
+void cmMakefile::AddQtUiFileWithOptions(cmSourceFile *sf)
+{
+ this->QtUiFilesWithOptions.push_back(sf);
+}
+
+//----------------------------------------------------------------------------
+std::vector<cmSourceFile*> cmMakefile::GetQtUiFilesWithOptions() const
+{
+ return this->QtUiFilesWithOptions;
+}
+
+//----------------------------------------------------------------------------
cmPolicies::PolicyStatus
cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id)
{
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index ca82336..794873a 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -884,6 +884,9 @@ public:
bool IsGeneratingBuildSystem(){ return this->GeneratingBuildSystem; }
void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; }
+ void AddQtUiFileWithOptions(cmSourceFile *sf);
+ std::vector<cmSourceFile*> GetQtUiFilesWithOptions() const;
+
std::set<cmStdString> const & GetSystemIncludeDirectories() const
{ return this->SystemIncludeDirectories; }
@@ -1061,6 +1064,8 @@ private:
cmSourceFile* source);
void UpdateOutputToSourceMap(std::string const& output,
cmSourceFile* source);
+
+ std::vector<cmSourceFile*> QtUiFilesWithOptions;
};
//----------------------------------------------------------------------------
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index 7f8d283..30211f2 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -23,6 +23,7 @@
#include <cmsys/Terminal.h>
#include <cmsys/ios/sstream>
+#include <assert.h>
#include <string.h>
#if defined(__APPLE__)
@@ -117,6 +118,7 @@ cmQtAutoGenerators::cmQtAutoGenerators()
:Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0)
,ColorOutput(true)
,RunMocFailed(false)
+,RunUicFailed(false)
,GenerateAll(false)
{
@@ -255,7 +257,22 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget* target)
"", makefile->GetCurrentOutputDirectory());
std::vector<std::string> depends;
- std::string tools = "moc";
+ std::vector<std::string> toolNames;
+ if (target->GetPropertyAsBool("AUTOMOC"))
+ {
+ toolNames.push_back("moc");
+ }
+ if (target->GetPropertyAsBool("AUTOUIC"))
+ {
+ toolNames.push_back("uic");
+ }
+
+ std::string tools = toolNames[0];
+ toolNames.erase(toolNames.begin());
+ if (toolNames.size() == 1)
+ {
+ tools += " and " + toolNames[0];
+ }
std::string autogenComment = "Automatic " + tools + " for target ";
autogenComment += targetName;
@@ -322,6 +339,10 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget* target)
this->SetupAutoMocTarget(target, autogenTargetName,
configIncludes, configDefines);
}
+ if (target->GetPropertyAsBool("AUTOUIC"))
+ {
+ this->SetupAutoUicTarget(target);
+ }
const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT");
std::string inputFile = cmakeRoot;
@@ -499,6 +520,156 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget* target,
}
}
+void cmQtAutoGenerators::MergeUicOptions(std::vector<std::string> &opts,
+ const std::vector<std::string> &fileOpts,
+ bool isQt5)
+{
+ static const char* valueOptions[] = {
+ "tr",
+ "translate",
+ "postfix",
+ "generator",
+ "g"
+ };
+ std::vector<std::string> extraOpts;
+ for(std::vector<std::string>::const_iterator it = fileOpts.begin();
+ it != fileOpts.end(); ++it)
+ {
+ std::vector<std::string>::iterator existingIt
+ = std::find(opts.begin(), opts.end(), *it);
+ if (existingIt != opts.end())
+ {
+ const char *o = it->c_str();
+ if (*o == '-')
+ {
+ ++o;
+ }
+ if (isQt5 && *o == '-')
+ {
+ ++o;
+ }
+ if (std::find_if(cmArrayBegin(valueOptions), cmArrayEnd(valueOptions),
+ cmStrCmp(o)) != cmArrayEnd(valueOptions))
+ {
+ assert(existingIt + 1 != opts.end());
+ *(existingIt + 1) = *(it + 1);
+ ++it;
+ }
+ }
+ else
+ {
+ extraOpts.push_back(*it);
+ }
+ }
+ opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
+}
+
+void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget* target)
+{
+ cmMakefile *makefile = target->GetMakefile();
+
+ const char *qtUic = makefile->GetSafeDefinition("QT_UIC_EXECUTABLE");
+ makefile->AddDefinition("_qt_uic_executable", qtUic);
+
+ const std::vector<cmSourceFile*>& srcFiles = target->GetSourceFiles();
+
+ std::string skip_uic;
+ const char *sep = "";
+
+ bool skip = target->GetPropertyAsBool("SKIP_AUTOUIC");
+
+ std::set<cmStdString> skipped;
+
+ for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
+ fileIt != srcFiles.end();
+ ++fileIt)
+ {
+ cmSourceFile* sf = *fileIt;
+ std::string absFile = cmsys::SystemTools::GetRealPath(
+ sf->GetFullPath().c_str());
+ if (!skip)
+ {
+ skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC"));
+ }
+
+ if (skip)
+ {
+ skip_uic += sep;
+ skip_uic += absFile;
+ sep = ";";
+ skipped.insert(absFile);
+ }
+ }
+
+ makefile->AddDefinition("_skip_uic",
+ cmLocalGenerator::EscapeForCMake(skip_uic.c_str()).c_str());
+
+ std::vector<cmSourceFile*> uiFilesWithOptions
+ = makefile->GetQtUiFilesWithOptions();
+
+ std::string uiFileFiles;
+ std::string uiFileOptions;
+ sep = "";
+
+ const char *qtVersion = makefile->GetDefinition("_target_qt_version");
+
+ if (const char* opts = target->GetProperty("AUTOUIC_OPTIONS"))
+ {
+ makefile->AddDefinition("_uic_target_options",
+ cmLocalGenerator::EscapeForCMake(opts).c_str());
+ }
+
+ for(std::vector<cmSourceFile*>::const_iterator fileIt =
+ uiFilesWithOptions.begin();
+ fileIt != uiFilesWithOptions.end();
+ ++fileIt)
+ {
+ cmSourceFile* sf = *fileIt;
+ std::string absFile = cmsys::SystemTools::GetRealPath(
+ sf->GetFullPath().c_str());
+
+ if (!skipped.insert(absFile).second)
+ {
+ continue;
+ }
+ uiFileFiles += sep;
+ uiFileFiles += absFile;
+ uiFileOptions += sep;
+ std::string opts = sf->GetProperty("AUTOUIC_OPTIONS");
+ cmSystemTools::ReplaceString(opts, ";", "@list_sep@");
+ uiFileOptions += opts;
+ sep = ";";
+ }
+
+ makefile->AddDefinition("_qt_uic_options_files",
+ cmLocalGenerator::EscapeForCMake(uiFileFiles.c_str()).c_str());
+ makefile->AddDefinition("_qt_uic_options_options",
+ cmLocalGenerator::EscapeForCMake(uiFileOptions.c_str()).c_str());
+
+ const char* targetName = target->GetName();
+ if (strcmp(qtVersion, "5") == 0)
+ {
+ cmTarget *qt5Uic = makefile->FindTargetToUse("Qt5::uic");
+ if (!qt5Uic)
+ {
+ // Project does not use Qt5Widgets, but has AUTOUIC ON anyway
+ makefile->RemoveDefinition("_qt_uic_executable");
+ }
+ else
+ {
+ makefile->AddDefinition("_qt_uic_executable", qt5Uic->GetLocation(0));
+ }
+ }
+ else
+ {
+ if (strcmp(qtVersion, "4") != 0)
+ {
+ cmSystemTools::Error("The CMAKE_AUTOUIC feature supports only Qt 4 and "
+ "Qt 5 ", targetName);
+ }
+ }
+}
+
bool cmQtAutoGenerators::Run(const char* targetDirectory, const char *config)
{
bool success = true;
@@ -563,12 +734,15 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile,
"AM_Qt5Core_VERSION_MAJOR");
}
this->Sources = makefile->GetSafeDefinition("AM_SOURCES");
+ this->SkipMoc = makefile->GetSafeDefinition("AM_SKIP_MOC");
+ this->SkipUic = makefile->GetSafeDefinition("AM_SKIP_UIC");
this->Headers = makefile->GetSafeDefinition("AM_HEADERS");
this->IncludeProjectDirsBefore = makefile->IsOn(
"AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
this->Srcdir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR");
this->Builddir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_BINARY_DIR");
this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE");
+ this->UicExecutable = makefile->GetSafeDefinition("AM_QT_UIC_EXECUTABLE");
std::string compileDefsPropOrig = "AM_MOC_COMPILE_DEFINITIONS";
std::string compileDefsProp = compileDefsPropOrig;
if(config)
@@ -594,6 +768,31 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile,
this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR");
this->TargetName = makefile->GetSafeDefinition("AM_TARGET_NAME");
+ {
+ const char *uicOptionsFiles
+ = makefile->GetSafeDefinition("AM_UIC_OPTIONS_FILES");
+ const char *uicTargetOptions
+ = makefile->GetSafeDefinition("AM_UIC_TARGET_OPTIONS");
+ cmSystemTools::ExpandListArgument(uicTargetOptions, this->UicTargetOptions);
+ const char *uicOptionsOptions
+ = makefile->GetSafeDefinition("AM_UIC_OPTIONS_OPTIONS");
+ std::vector<std::string> uicFilesVec;
+ cmSystemTools::ExpandListArgument(uicOptionsFiles, uicFilesVec);
+ std::vector<std::string> uicOptionsVec;
+ cmSystemTools::ExpandListArgument(uicOptionsOptions, uicOptionsVec);
+ if (uicFilesVec.size() != uicOptionsVec.size())
+ {
+ return false;
+ }
+ for (std::vector<std::string>::iterator fileIt = uicFilesVec.begin(),
+ optionIt = uicOptionsVec.begin();
+ fileIt != uicFilesVec.end();
+ ++fileIt, ++optionIt)
+ {
+ cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";");
+ this->UicOptions[*fileIt] = *optionIt;
+ }
+ }
this->CurrentCompileSettingsStr = this->MakeCompileSettingsString(makefile);
this->RelaxedMode = makefile->IsOn("AM_RELAXED_MODE");
@@ -767,10 +966,18 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
const std::vector<std::string>& headerExtensions =
makefile->GetHeaderExtensions();
+ std::vector<std::string> includedUis;
+ std::vector<std::string> skippedUis;
+ std::vector<std::string> uicSkipped;
+ cmSystemTools::ExpandListArgument(this->SkipUic, uicSkipped);
+
for (std::vector<std::string>::const_iterator it = sourceFiles.begin();
it != sourceFiles.end();
++it)
{
+ const bool skipUic = std::find(uicSkipped.begin(), uicSkipped.end(), *it)
+ != uicSkipped.end();
+ std::vector<std::string>& uiFiles = skipUic ? skippedUis : includedUis;
const std::string &absFilename = *it;
if (this->Verbose)
{
@@ -778,15 +985,37 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
}
if (this->RelaxedMode)
{
- this->ParseCppFile(absFilename, headerExtensions, includedMocs);
+ this->ParseCppFile(absFilename, headerExtensions, includedMocs,
+ uiFiles);
}
else
{
- this->StrictParseCppFile(absFilename, headerExtensions, includedMocs);
+ this->StrictParseCppFile(absFilename, headerExtensions, includedMocs,
+ uiFiles);
}
this->SearchHeadersForCppFile(absFilename, headerExtensions, headerFiles);
}
+ {
+ std::vector<std::string> mocSkipped;
+ cmSystemTools::ExpandListArgument(this->SkipMoc, mocSkipped);
+ for (std::vector<std::string>::const_iterator it = mocSkipped.begin();
+ it != mocSkipped.end();
+ ++it)
+ {
+ if (std::find(uicSkipped.begin(), uicSkipped.end(), *it)
+ != uicSkipped.end())
+ {
+ const std::string &absFilename = *it;
+ if (this->Verbose)
+ {
+ std::cout << "AUTOGEN: Checking " << absFilename << std::endl;
+ }
+ this->ParseForUic(absFilename, includedUis);
+ }
+ }
+ }
+
std::vector<std::string> headerFilesVec;
cmSystemTools::ExpandListArgument(this->Headers, headerFilesVec);
for (std::vector<std::string>::const_iterator it = headerFilesVec.begin();
@@ -798,7 +1027,7 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
// key = moc source filepath, value = moc output filename
std::map<std::string, std::string> notIncludedMocs;
- this->ParseHeaders(headerFiles, includedMocs, notIncludedMocs);
+ this->ParseHeaders(headerFiles, includedMocs, notIncludedMocs, includedUis);
// run moc on all the moc's that are #included in source files
for(std::map<std::string, std::string>::const_iterator
@@ -808,6 +1037,12 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
{
this->GenerateMoc(it->first, it->second);
}
+ for(std::vector<std::string>::const_iterator it = includedUis.begin();
+ it != includedUis.end();
+ ++it)
+ {
+ this->GenerateUi(*it);
+ }
cmsys_ios::stringstream outStream;
outStream << "/* This file is autogenerated, do not edit*/\n";
@@ -840,6 +1075,12 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
std::cerr << "moc failed..."<< std::endl;
return false;
}
+
+ if (this->RunUicFailed)
+ {
+ std::cerr << "uic failed..."<< std::endl;
+ return false;
+ }
outStream.flush();
std::string automocSource = outStream.str();
if (!automocCppChanged)
@@ -866,7 +1107,8 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename,
const std::vector<std::string>& headerExtensions,
- std::map<std::string, std::string>& includedMocs)
+ std::map<std::string, std::string>& includedMocs,
+ std::vector<std::string> &includedUis)
{
cmsys::RegularExpression mocIncludeRegExp(
"[\n][ \t]*#[ \t]*include[ \t]+"
@@ -1007,6 +1249,7 @@ void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename,
matchOffset += mocIncludeRegExp.end();
} while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
}
+ this->ParseForUic(absFilename, contentsString, includedUis);
// In this case, check whether the scanned file itself contains a Q_OBJECT.
// If this is the case, the moc_foo.cpp should probably be generated from
@@ -1047,7 +1290,8 @@ void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename,
void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename,
const std::vector<std::string>& headerExtensions,
- std::map<std::string, std::string>& includedMocs)
+ std::map<std::string, std::string>& includedMocs,
+ std::vector<std::string>& includedUis)
{
cmsys::RegularExpression mocIncludeRegExp(
"[\n][ \t]*#[ \t]*include[ \t]+"
@@ -1138,6 +1382,7 @@ void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename,
matchOffset += mocIncludeRegExp.end();
} while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
}
+ this->ParseForUic(absFilename, contentsString, includedUis);
// In this case, check whether the scanned file itself contains a Q_OBJECT.
// If this is the case, the moc_foo.cpp should probably be generated from
@@ -1158,6 +1403,61 @@ void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename,
}
+void cmQtAutoGenerators::ParseForUic(const std::string& absFilename,
+ std::vector<std::string>& includedUis)
+{
+ if (this->UicExecutable.empty())
+ {
+ return;
+ }
+ const std::string contentsString = this->ReadAll(absFilename);
+ if (contentsString.empty())
+ {
+ std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n"
+ << std::endl;
+ return;
+ }
+ this->ParseForUic(absFilename, contentsString, includedUis);
+}
+
+
+void cmQtAutoGenerators::ParseForUic(const std::string&,
+ const std::string& contentsString,
+ std::vector<std::string>& includedUis)
+{
+ if (this->UicExecutable.empty())
+ {
+ return;
+ }
+ cmsys::RegularExpression uiIncludeRegExp(
+ "[\n][ \t]*#[ \t]*include[ \t]+"
+ "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
+
+ std::string::size_type matchOffset = 0;
+
+ matchOffset = 0;
+ if ((strstr(contentsString.c_str(), "ui_") != NULL)
+ && (uiIncludeRegExp.find(contentsString)))
+ {
+ do
+ {
+ const std::string currentUi = uiIncludeRegExp.match(1);
+
+ std::string basename = cmsys::SystemTools::
+ GetFilenameWithoutLastExtension(currentUi);
+
+ // basename should be the part of the ui filename used for
+ // finding the correct header, so we need to remove the ui_ part
+ basename = basename.substr(3);
+
+ includedUis.push_back(basename);
+
+ matchOffset += uiIncludeRegExp.end();
+ } while(uiIncludeRegExp.find(contentsString.c_str() + matchOffset));
+ }
+}
+
+
void
cmQtAutoGenerators::SearchHeadersForCppFile(const std::string& absFilename,
const std::vector<std::string>& headerExtensions,
@@ -1197,13 +1497,15 @@ cmQtAutoGenerators::SearchHeadersForCppFile(const std::string& absFilename,
void cmQtAutoGenerators::ParseHeaders(const std::set<std::string>& absHeaders,
const std::map<std::string, std::string>& includedMocs,
- std::map<std::string, std::string>& notIncludedMocs)
+ std::map<std::string, std::string>& notIncludedMocs,
+ std::vector<std::string>& includedUis)
{
for(std::set<std::string>::const_iterator hIt=absHeaders.begin();
hIt!=absHeaders.end();
++hIt)
{
const std::string& headerName = *hIt;
+ const std::string contents = this->ReadAll(headerName);
if (includedMocs.find(headerName) == includedMocs.end())
{
@@ -1216,7 +1518,6 @@ void cmQtAutoGenerators::ParseHeaders(const std::set<std::string>& absHeaders,
GetFilenameWithoutLastExtension(headerName);
const std::string currentMoc = "moc_" + basename + ".cpp";
- const std::string contents = this->ReadAll(headerName);
std::string macroName;
if (requiresMocing(contents, macroName))
{
@@ -1224,11 +1525,10 @@ void cmQtAutoGenerators::ParseHeaders(const std::set<std::string>& absHeaders,
notIncludedMocs[headerName] = currentMoc;
}
}
+ this->ParseForUic(headerName, contents, includedUis);
}
-
}
-
bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile,
const std::string& mocFileName)
{
@@ -1305,6 +1605,77 @@ bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile,
return false;
}
+bool cmQtAutoGenerators::GenerateUi(const std::string& uiFileName)
+{
+ if (!cmsys::SystemTools::FileExists(this->Builddir.c_str(), false))
+ {
+ cmsys::SystemTools::MakeDirectory(this->Builddir.c_str());
+ }
+
+ std::string ui_output_file = "ui_" + uiFileName + ".h";
+ std::string ui_input_file = this->Srcdir + uiFileName + ".ui";
+
+ int sourceNewerThanUi = 0;
+ bool success = cmsys::SystemTools::FileTimeCompare(ui_input_file.c_str(),
+ (this->Builddir + ui_output_file).c_str(),
+ &sourceNewerThanUi);
+ if (this->GenerateAll || !success || sourceNewerThanUi >= 0)
+ {
+ std::string msg = "Generating ";
+ msg += ui_output_file;
+ cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue
+ |cmsysTerminal_Color_ForegroundBold,
+ msg.c_str(), true, this->ColorOutput);
+
+ std::vector<cmStdString> command;
+ command.push_back(this->UicExecutable);
+
+ std::string options;
+ std::vector<std::string> opts = this->UicTargetOptions;
+ std::map<std::string, std::string>::const_iterator optionIt
+ = this->UicOptions.find(ui_input_file);
+ if (optionIt != this->UicOptions.end())
+ {
+ std::vector<std::string> fileOpts;
+ cmSystemTools::ExpandListArgument(optionIt->second, fileOpts);
+ this->MergeUicOptions(opts, fileOpts, this->QtMajorVersion == "5");
+ }
+ for(std::vector<std::string>::const_iterator optIt = opts.begin();
+ optIt != opts.end();
+ ++optIt)
+ {
+ command.push_back(*optIt);
+ }
+
+ command.push_back("-o");
+ command.push_back(this->Builddir + ui_output_file);
+ command.push_back(ui_input_file);
+
+ if (this->Verbose)
+ {
+ for(std::vector<cmStdString>::const_iterator cmdIt = command.begin();
+ cmdIt != command.end();
+ ++cmdIt)
+ {
+ std::cout << *cmdIt << " ";
+ }
+ std::cout << std::endl;
+ }
+ std::string output;
+ int retVal = 0;
+ bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal);
+ if (!result || retVal)
+ {
+ std::cerr << "AUTOUIC: error: process for " << ui_output_file <<
+ " failed:\n" << output << std::endl;
+ this->RunUicFailed = true;
+ cmSystemTools::RemoveFile(ui_output_file.c_str());
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
std::string cmQtAutoGenerators::Join(const std::vector<std::string>& lst,
char separator)
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index fe38b05..37b6154 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -31,6 +31,7 @@ private:
const std::string &autogenTargetName,
std::map<std::string, std::string> &configIncludes,
std::map<std::string, std::string> &configDefines);
+ void SetupAutoUicTarget(cmTarget* target);
cmGlobalGenerator* CreateGlobalGenerator(cmake* cm,
const char* targetDirectory);
@@ -47,19 +48,30 @@ private:
bool RunAutogen(cmMakefile* makefile);
bool GenerateMoc(const std::string& sourceFile,
const std::string& mocFileName);
+ bool GenerateUi(const std::string& uiFileName);
void ParseCppFile(const std::string& absFilename,
const std::vector<std::string>& headerExtensions,
- std::map<std::string, std::string>& includedMocs);
+ std::map<std::string, std::string>& includedMocs,
+ std::vector<std::string>& includedUis);
void StrictParseCppFile(const std::string& absFilename,
const std::vector<std::string>& headerExtensions,
- std::map<std::string, std::string>& includedMocs);
+ std::map<std::string, std::string>& includedMocs,
+ std::vector<std::string>& includedUis);
void SearchHeadersForCppFile(const std::string& absFilename,
const std::vector<std::string>& headerExtensions,
std::set<std::string>& absHeaders);
void ParseHeaders(const std::set<std::string>& absHeaders,
const std::map<std::string, std::string>& includedMocs,
- std::map<std::string, std::string>& notIncludedMocs);
+ std::map<std::string, std::string>& notIncludedMocs,
+ std::vector<std::string>& includedUis);
+
+ void ParseForUic(const std::string& fileName,
+ const std::string& contentsString,
+ std::vector<std::string>& includedUis);
+
+ void ParseForUic(const std::string& fileName,
+ std::vector<std::string>& includedUis);
void Init();
@@ -68,13 +80,19 @@ private:
bool StartsWith(const std::string& str, const std::string& with);
std::string ReadAll(const std::string& filename);
+ void MergeUicOptions(std::vector<std::string> &opts,
+ const std::vector<std::string> &fileOpts, bool isQt5);
+
std::string QtMajorVersion;
std::string Sources;
+ std::string SkipMoc;
+ std::string SkipUic;
std::string Headers;
bool IncludeProjectDirsBefore;
std::string Srcdir;
std::string Builddir;
std::string MocExecutable;
+ std::string UicExecutable;
std::string MocCompileDefinitionsStr;
std::string MocIncludesStr;
std::string MocOptionsStr;
@@ -89,10 +107,13 @@ private:
std::list<std::string> MocIncludes;
std::list<std::string> MocDefinitions;
std::vector<std::string> MocOptions;
+ std::vector<std::string> UicTargetOptions;
+ std::map<std::string, std::string> UicOptions;
bool Verbose;
bool ColorOutput;
bool RunMocFailed;
+ bool RunUicFailed;
bool GenerateAll;
bool RelaxedMode;
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index d747309..ec98c2c 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -287,6 +287,17 @@ void cmSourceFile::SetProperty(const char* prop, const char* value)
}
this->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
+
+ std::string ext =
+ cmSystemTools::GetFilenameLastExtension(this->Location.GetName());
+ if (ext == ".ui")
+ {
+ cmMakefile* mf = this->Location.GetMakefile();
+ if (strcmp(prop, "AUTOUIC_OPTIONS") == 0)
+ {
+ mf->AddQtUiFileWithOptions(this);
+ }
+ }
}
//----------------------------------------------------------------------------
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index ad4ae0c..5b77c27 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -274,7 +274,9 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->SetPropertyDefault("GNUtoMS", 0);
this->SetPropertyDefault("OSX_ARCHITECTURES", 0);
this->SetPropertyDefault("AUTOMOC", 0);
+ this->SetPropertyDefault("AUTOUIC", 0);
this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0);
+ this->SetPropertyDefault("AUTOUIC_OPTIONS", 0);
this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", 0);
this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0);
this->SetPropertyDefault("WIN32_EXECUTABLE", 0);