[Cmake-commits] CMake branch, next, updated. v2.8.12-3924-gfd7f2ba
Stephen Kelly
steveire at gmail.com
Sat Oct 12 04:40:19 EDT 2013
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".
The branch, next has been updated
via fd7f2ba55f795694933a81436f25b0de3005c0c6 (commit)
via 567ba903fa3bb20ef4e27939a41de5d24fdb5fec (commit)
via a9eafee477f367ae070c1fa4f0bd53c6bb250c06 (commit)
from 5ddd06b29c00455756744e1ab06ec3f442496c48 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fd7f2ba55f795694933a81436f25b0de3005c0c6
commit fd7f2ba55f795694933a81436f25b0de3005c0c6
Merge: 5ddd06b 567ba90
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Sat Oct 12 04:40:15 2013 -0400
Commit: CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Sat Oct 12 04:40:15 2013 -0400
Merge topic 'Qt-auto-generators' into next
567ba90 Add automatic rcc invocation for Qt.
a9eafee Add automatic uic invocation for Qt.
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=567ba903fa3bb20ef4e27939a41de5d24fdb5fec
commit 567ba903fa3bb20ef4e27939a41de5d24fdb5fec
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Sun Sep 15 14:41:07 2013 +0200
Commit: Stephen Kelly <steveire at gmail.com>
CommitDate: Sat Oct 12 10:39:13 2013 +0200
Add automatic rcc invocation for Qt.
This replaces the need to invoke qt4_add_resources by allowing
adding the source .qrc file directly to the target sources.
diff --git a/Modules/AutogenInfo.cmake.in b/Modules/AutogenInfo.cmake.in
index b55397a..8e38d86 100644
--- a/Modules/AutogenInfo.cmake.in
+++ b/Modules/AutogenInfo.cmake.in
@@ -1,4 +1,5 @@
set(AM_SOURCES @_moc_files@ )
+set(AM_RCC_SOURCES @_rcc_files@ )
set(AM_SKIP_MOC @_skip_moc@ )
set(AM_SKIP_UIC @_skip_uic@ )
set(AM_HEADERS @_moc_headers@ )
@@ -10,6 +11,7 @@ set(AM_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@/")
set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/")
set(AM_QT_MOC_EXECUTABLE "@_qt_moc_executable@")
set(AM_QT_UIC_EXECUTABLE "@_qt_uic_executable@")
+set(AM_QT_RCC_EXECUTABLE "@_qt_rcc_executable@")
set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/")
set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/")
set(AM_QT_VERSION_MAJOR "@_target_qt_version@")
@@ -17,3 +19,5 @@ set(AM_TARGET_NAME @_moc_target_name@)
set(AM_RELAXED_MODE "@_moc_relaxed_mode@")
set(AM_UIC_OPTIONS_FILES @_qt_uic_options_files@)
set(AM_UIC_OPTIONS_OPTIONS @_qt_uic_options_options@)
+set(AM_RCC_OPTIONS_FILES @_qt_rcc_options_files@)
+set(AM_RCC_OPTIONS_OPTIONS @_qt_rcc_options_options@)
diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx
index 2f4d154..051c146 100644
--- a/Source/cmDocumentVariables.cxx
+++ b/Source/cmDocumentVariables.cxx
@@ -1345,6 +1345,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
"Variables that Control the Build");
cm->DefineProperty
+ ("CMAKE_AUTORCC", cmProperty::VARIABLE,
+ "Whether to handle rcc automatically for Qt targets.",
+ "This variable is used to initialize the "
+ "AUTORCC property on all the targets. "
+ "See that target property for additional information.",
+ false,
+ "Variables that Control the Build");
+
+ cm->DefineProperty
("CMAKE_AUTOMOC_MOC_OPTIONS", cmProperty::VARIABLE,
"Additional options for moc when using automoc (see CMAKE_AUTOMOC).",
"This variable is used to initialize the "
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 1635eb8..d3509a0 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1170,7 +1170,8 @@ void cmGlobalGenerator::CreateQtAutoGeneratorsTargets()
target.GetType() == cmTarget::OBJECT_LIBRARY)
{
if((target.GetPropertyAsBool("AUTOMOC")
- || target.GetPropertyAsBool("AUTOUIC"))
+ || target.GetPropertyAsBool("AUTOUIC")
+ || target.GetPropertyAsBool("AUTORCC"))
&& !target.IsImported())
{
cmQtAutoGenerators autogen;
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index 9d886fe..a94d415 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -118,6 +118,7 @@ cmQtAutoGenerators::cmQtAutoGenerators()
,ColorOutput(true)
,RunMocFailed(false)
,RunUicFailed(false)
+,RunRccFailed(false)
,GenerateAll(false)
{
@@ -265,9 +266,18 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget* target)
{
toolNames.push_back("uic");
}
+ if (target->GetPropertyAsBool("AUTORCC"))
+ {
+ toolNames.push_back("rcc");
+ }
std::string tools = toolNames[0];
toolNames.erase(toolNames.begin());
+ while (toolNames.size() > 1)
+ {
+ tools += ", " + toolNames[0];
+ toolNames.erase(toolNames.begin());
+ }
if (toolNames.size() == 1)
{
tools += " and " + toolNames[0];
@@ -342,6 +352,10 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget* target)
{
this->SetupAutoUicTarget(target);
}
+ if (target->GetPropertyAsBool("AUTORCC"))
+ {
+ this->SetupAutoRccTarget(target);
+ }
const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT");
std::string inputFile = cmakeRoot;
@@ -603,6 +617,104 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget* target)
}
}
+void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget* target)
+{
+ std::string _rcc_files;
+ const char* sepRccFiles = "";
+ cmMakefile *makefile = target->GetMakefile();
+
+ std::vector<cmSourceFile*> newFiles;
+
+ const std::vector<cmSourceFile*>& srcFiles = target->GetSourceFiles();
+
+ std::string rccFileFiles;
+ std::string rccFileOptions;
+ const char *sep = "";
+
+ for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
+ fileIt != srcFiles.end();
+ ++fileIt)
+ {
+ cmSourceFile* sf = *fileIt;
+ std::string ext = sf->GetExtension();
+ if (ext == "qrc")
+ {
+ std::string absFile = cmsys::SystemTools::GetRealPath(
+ sf->GetFullPath().c_str());
+ bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"));
+
+ if (!skip)
+ {
+ _rcc_files += sepRccFiles;
+ _rcc_files += absFile;
+ sepRccFiles = ";";
+
+ std::string basename = cmsys::SystemTools::
+ GetFilenameWithoutLastExtension(absFile);
+
+ std::string rcc_output_file = makefile->GetCurrentOutputDirectory();
+ rcc_output_file += "/qrc_" + basename + ".cpp";
+ makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
+ rcc_output_file.c_str(), false);
+ cmSourceFile* rccCppSource
+ = makefile->GetOrCreateSource(rcc_output_file.c_str(), true);
+ newFiles.push_back(rccCppSource);
+
+ if (const char *prop = sf->GetProperty("AUTORCC_OPTIONS"))
+ {
+ rccFileFiles += sep;
+ rccFileFiles += absFile;
+ rccFileOptions += sep;
+ std::string opts = prop;
+ cmSystemTools::ReplaceString(opts, ";", "@list_sep@");
+ rccFileOptions += opts;
+ sep = ";";
+ }
+ }
+ }
+ }
+
+ for(std::vector<cmSourceFile*>::const_iterator fileIt = newFiles.begin();
+ fileIt != newFiles.end();
+ ++fileIt)
+ {
+ target->AddSourceFile(*fileIt);
+ }
+
+ makefile->AddDefinition("_rcc_files",
+ cmLocalGenerator::EscapeForCMake(_rcc_files.c_str()).c_str());
+
+ makefile->AddDefinition("_qt_rcc_options_files",
+ cmLocalGenerator::EscapeForCMake(rccFileFiles.c_str()).c_str());
+ makefile->AddDefinition("_qt_rcc_options_options",
+ cmLocalGenerator::EscapeForCMake(rccFileOptions.c_str()).c_str());
+
+ const char *qtRcc = makefile->GetSafeDefinition("QT_RCC_EXECUTABLE");
+ makefile->AddDefinition("_qt_rcc_executable", qtRcc);
+
+ const char* targetName = target->GetName();
+ const char *qtVersion = makefile->GetDefinition("_target_qt_version");
+ if (strcmp(qtVersion, "5") == 0)
+ {
+ cmTarget *qt5Rcc = makefile->FindTargetToUse("Qt5::rcc");
+ if (!qt5Rcc)
+ {
+ cmSystemTools::Error("Qt5::rcc target not found ",
+ targetName);
+ return;
+ }
+ makefile->AddDefinition("_qt_rcc_executable", qt5Rcc->GetLocation(0));
+ }
+ else
+ {
+ if (strcmp(qtVersion, "4") != 0)
+ {
+ cmSystemTools::Error("The CMAKE_AUTORCC feature supports only Qt 4 and "
+ "Qt 5 ", targetName);
+ }
+ }
+}
+
bool cmQtAutoGenerators::Run(const char* targetDirectory, const char *config)
{
bool success = true;
@@ -667,6 +779,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile,
"AM_Qt5Core_VERSION_MAJOR");
}
this->Sources = makefile->GetSafeDefinition("AM_SOURCES");
+ this->RccSources = makefile->GetSafeDefinition("AM_RCC_SOURCES");
this->SkipMoc = makefile->GetSafeDefinition("AM_SKIP_MOC");
this->SkipUic = makefile->GetSafeDefinition("AM_SKIP_UIC");
this->Headers = makefile->GetSafeDefinition("AM_HEADERS");
@@ -676,6 +789,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile,
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");
+ this->RccExecutable = makefile->GetSafeDefinition("AM_QT_RCC_EXECUTABLE");
std::string compileDefsPropOrig = "AM_MOC_COMPILE_DEFINITIONS";
std::string compileDefsProp = compileDefsPropOrig;
if(config)
@@ -723,6 +837,28 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile,
this->UicOptions[*fileIt] = *optionIt;
}
}
+ {
+ const char *rccOptionsFiles
+ = makefile->GetSafeDefinition("AM_RCC_OPTIONS_FILES");
+ const char *rccOptionsOptions
+ = makefile->GetSafeDefinition("AM_RCC_OPTIONS_OPTIONS");
+ std::vector<std::string> rccFilesVec;
+ cmSystemTools::ExpandListArgument(rccOptionsFiles, rccFilesVec);
+ std::vector<std::string> rccOptionsVec;
+ cmSystemTools::ExpandListArgument(rccOptionsOptions, rccOptionsVec);
+ if (rccFilesVec.size() != rccOptionsVec.size())
+ {
+ return false;
+ }
+ for (std::vector<std::string>::iterator fileIt = rccFilesVec.begin(),
+ optionIt = rccOptionsVec.begin();
+ fileIt != rccFilesVec.end();
+ ++fileIt, ++optionIt)
+ {
+ cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";");
+ this->RccOptions[*fileIt] = *optionIt;
+ }
+ }
this->CurrentCompileSettingsStr = this->MakeCompileSettingsString(makefile);
this->RelaxedMode = makefile->IsOn("AM_RELAXED_MODE");
@@ -974,6 +1110,11 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
this->GenerateUi(*it);
}
+ if(!this->RccExecutable.empty())
+ {
+ this->GenerateQrc();
+ }
+
cmsys_ios::stringstream outStream;
outStream << "/* This file is autogenerated, do not edit*/\n";
@@ -1011,6 +1152,11 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
std::cerr << "uic failed..."<< std::endl;
return false;
}
+ if (this->RunRccFailed)
+ {
+ std::cerr << "rcc failed..."<< std::endl;
+ return false;
+ }
outStream.flush();
std::string automocSource = outStream.str();
if (!automocCppChanged)
@@ -1596,6 +1742,71 @@ bool cmQtAutoGenerators::GenerateUi(const std::string& uiFileName)
return true;
}
+bool cmQtAutoGenerators::GenerateQrc()
+{
+ std::vector<std::string> sourceFiles;
+ cmSystemTools::ExpandListArgument(this->RccSources, sourceFiles);
+
+ for(std::vector<std::string>::const_iterator si = sourceFiles.begin();
+ si != sourceFiles.end(); ++si)
+ {
+ std::string ext = cmsys::SystemTools::GetFilenameLastExtension(*si);
+
+ if (ext != ".qrc")
+ {
+ continue;
+ }
+ std::vector<cmStdString> command;
+ command.push_back(this->RccExecutable);
+
+ std::string basename = cmsys::SystemTools::
+ GetFilenameWithoutLastExtension(*si);
+
+ std::string rcc_output_file = "qrc_" + basename + ".cpp";
+
+ std::string options;
+ std::map<std::string, std::string>::const_iterator optionIt
+ = this->RccOptions.find(*si);
+ if (optionIt != this->RccOptions.end())
+ {
+ std::vector<std::string> opts;
+ cmSystemTools::ExpandListArgument(optionIt->second, opts);
+ 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(rcc_output_file);
+ command.push_back(*si);
+
+ 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 << "AUTORCC: error: process for " << rcc_output_file <<
+ " failed:\n" << output << std::endl;
+ this->RunRccFailed = true;
+ cmSystemTools::RemoveFile(rcc_output_file.c_str());
+ }
+ }
+ return true;
+}
+
std::string cmQtAutoGenerators::Join(const std::vector<std::string>& lst,
char separator)
{
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index 4e8960f..15cfe0d 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -32,6 +32,7 @@ private:
std::map<std::string, std::string> &configIncludes,
std::map<std::string, std::string> &configDefines);
void SetupAutoUicTarget(cmTarget* target);
+ void SetupAutoRccTarget(cmTarget* target);
cmGlobalGenerator* CreateGlobalGenerator(cmake* cm,
const char* targetDirectory);
@@ -49,6 +50,7 @@ private:
bool GenerateMoc(const std::string& sourceFile,
const std::string& mocFileName);
bool GenerateUi(const std::string& uiFileName);
+ bool GenerateQrc();
void ParseCppFile(const std::string& absFilename,
const std::vector<std::string>& headerExtensions,
std::map<std::string, std::string>& includedMocs,
@@ -82,6 +84,7 @@ private:
std::string QtMajorVersion;
std::string Sources;
+ std::string RccSources;
std::string SkipMoc;
std::string SkipUic;
std::string Headers;
@@ -90,6 +93,7 @@ private:
std::string Builddir;
std::string MocExecutable;
std::string UicExecutable;
+ std::string RccExecutable;
std::string MocCompileDefinitionsStr;
std::string MocIncludesStr;
std::string MocOptionsStr;
@@ -105,11 +109,13 @@ private:
std::list<std::string> MocDefinitions;
std::vector<std::string> MocOptions;
std::map<std::string, std::string> UicOptions;
+ std::map<std::string, std::string> RccOptions;
bool Verbose;
bool ColorOutput;
bool RunMocFailed;
bool RunUicFailed;
+ bool RunRccFailed;
bool GenerateAll;
bool RelaxedMode;
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index 5514fef..1a103c2 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -417,6 +417,16 @@ void cmSourceFile::DefineProperties(cmake *cm)
"By default it is empty.");
cm->DefineProperty
+ ("AUTORCC_OPTIONS", cmProperty::SOURCE_FILE,
+ "Additional options for rcc when using autorcc (see the AUTORCC target "
+ "property)",
+ "This property holds additional command line options "
+ "which will be used when rcc is executed during the build via autorcc, "
+ "i.e. it is equivalent to the optional OPTIONS argument of the "
+ "qt4_add_resources() macro.\n"
+ "By default it is empty.");
+
+ cm->DefineProperty
("COMPILE_FLAGS", cmProperty::SOURCE_FILE,
"Additional flags to be added when compiling this source file.",
"These flags will be added to the list of compile flags when "
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 140fc98..3812421 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -268,6 +268,22 @@ void cmTarget::DefineProperties(cmake *cm)
"autouic targets together in an IDE, e.g. in MSVS.");
cm->DefineProperty
+ ("AUTORCC", cmProperty::TARGET,
+ "Should the target be processed with autorcc (for Qt projects).",
+ "AUTORCC is a boolean specifying whether CMake will handle "
+ "the Qt rcc code generator automatically, i.e. without having to use "
+ "the QT4_ADD_RESOURCES() or QT5_ADD_RESOURCES() macro. Currently Qt4 "
+ "and Qt5 are supported. "
+ "When this property is set to TRUE, CMake will handle .qrc files added "
+ "as target sources at build time and invoke rcc accordingly. "
+ "This property is initialized by the value of the variable "
+ "CMAKE_AUTORCC if it is set when a target is created.\n"
+ "Additional command line options for rcc can be set via the "
+ "RCC_OPTIONS source file property on the .qrc file.\n"
+ "The global property AUTOGEN_TARGETS_FOLDER can be used to group the"
+ "autorcc targets together in an IDE, e.g. in MSVS.");
+
+ cm->DefineProperty
("AUTOMOC_MOC_OPTIONS", cmProperty::TARGET,
"Additional options for moc when using automoc (see the AUTOMOC property)",
"This property is only used if the AUTOMOC property is set to TRUE for "
@@ -1667,6 +1683,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->SetPropertyDefault("OSX_ARCHITECTURES", 0);
this->SetPropertyDefault("AUTOMOC", 0);
this->SetPropertyDefault("AUTOUIC", 0);
+ this->SetPropertyDefault("AUTORCC", 0);
this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0);
this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", 0);
this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0);
diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt
index b7849c1..41a82aa 100644
--- a/Tests/QtAutogen/CMakeLists.txt
+++ b/Tests/QtAutogen/CMakeLists.txt
@@ -36,6 +36,7 @@ add_definitions(-DFOO -DSomeDefine="Barx")
set(CMAKE_AUTOMOC_RELAXED_MODE TRUE)
set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
# create an executable and two library targets, each requiring automoc:
add_library(codeeditorLib STATIC codeeditor.cpp)
@@ -43,7 +44,9 @@ add_library(codeeditorLib STATIC codeeditor.cpp)
add_library(privateSlot OBJECT private_slot.cpp)
add_executable(QtAutogen main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp
- xyz.cpp yaf.cpp gadget.cpp $<TARGET_OBJECTS:privateSlot>)
+ xyz.cpp yaf.cpp gadget.cpp $<TARGET_OBJECTS:privateSlot>
+ test.qrc resourcetester.cpp
+)
set_target_properties(QtAutogen codeeditorLib privateSlot PROPERTIES AUTOMOC TRUE)
diff --git a/Tests/QtAutogen/main.cpp b/Tests/QtAutogen/main.cpp
index 39597ba..c8a036e 100644
--- a/Tests/QtAutogen/main.cpp
+++ b/Tests/QtAutogen/main.cpp
@@ -38,7 +38,8 @@
**
****************************************************************************/
-#include <QApplication>
+#include <QCoreApplication>
+#include <QTimer>
#include "codeeditor.h"
#include "calwidget.h"
@@ -49,16 +50,11 @@
#include "xyz.h"
#include "yaf.h"
#include "libC.h"
+#include "resourcetester.h"
int main(int argv, char **args)
{
- QApplication app(argv, args);
-
- CodeEditor editor;
- editor.setWindowTitle(QObject::tr("Code Editor Example"));
-
- Window w;
- w.setWindowTitle(QObject::tr("Window Example"));
+ QCoreApplication app(argv, args);
Foo foo;
foo.doFoo();
@@ -81,5 +77,9 @@ int main(int argv, char **args)
LibC lc;
lc.foo();
+ ResourceTester rt;
+
+ QTimer::singleShot(0, &rt, SLOT(doTest()));
+
return app.exec();
}
diff --git a/Tests/QtAutogen/resourcetester.cpp b/Tests/QtAutogen/resourcetester.cpp
new file mode 100644
index 0000000..43314e1
--- /dev/null
+++ b/Tests/QtAutogen/resourcetester.cpp
@@ -0,0 +1,21 @@
+
+#include "resourcetester.h"
+
+#include <QDebug>
+#include <QApplication>
+#include <QFile>
+#include <QTimer>
+
+ResourceTester::ResourceTester(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+void ResourceTester::doTest()
+{
+ if (!QFile::exists(":/CMakeLists.txt"))
+ qApp->exit(EXIT_FAILURE);
+
+ QTimer::singleShot(0, qApp, SLOT(quit()));
+}
diff --git a/Tests/QtAutogen/resourcetester.h b/Tests/QtAutogen/resourcetester.h
new file mode 100644
index 0000000..b02cb4e
--- /dev/null
+++ b/Tests/QtAutogen/resourcetester.h
@@ -0,0 +1,17 @@
+
+#ifndef RESOURCE_TESTER_H
+#define RESOURCE_TESTER_H
+
+#include <QObject>
+
+class ResourceTester : public QObject
+{
+ Q_OBJECT
+public:
+ explicit ResourceTester(QObject *parent = 0);
+
+private slots:
+ void doTest();
+};
+
+#endif
diff --git a/Tests/QtAutogen/test.qrc b/Tests/QtAutogen/test.qrc
new file mode 100644
index 0000000..c3d4e3c
--- /dev/null
+++ b/Tests/QtAutogen/test.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>CMakeLists.txt</file>
+</qresource>
+</RCC>
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a9eafee477f367ae070c1fa4f0bd53c6bb250c06
commit a9eafee477f367ae070c1fa4f0bd53c6bb250c06
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Jul 25 09:24:53 2013 +0200
Commit: Stephen Kelly <steveire at gmail.com>
CommitDate: Sat Oct 12 10:38:50 2013 +0200
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.
diff --git a/Modules/AutogenInfo.cmake.in b/Modules/AutogenInfo.cmake.in
index 19663ff..b55397a 100644
--- a/Modules/AutogenInfo.cmake.in
+++ b/Modules/AutogenInfo.cmake.in
@@ -1,5 +1,6 @@
set(AM_SOURCES @_moc_files@ )
set(AM_SKIP_MOC @_skip_moc@ )
+set(AM_SKIP_UIC @_skip_uic@ )
set(AM_HEADERS @_moc_headers@ )
set(AM_MOC_COMPILE_DEFINITIONS @_moc_compile_defs@)
set(AM_MOC_INCLUDES @_moc_incs@)
@@ -8,8 +9,11 @@ set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJ
set(AM_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@/")
set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/")
set(AM_QT_MOC_EXECUTABLE "@_qt_moc_executable@")
+set(AM_QT_UIC_EXECUTABLE "@_qt_uic_executable@")
set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/")
set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/")
set(AM_QT_VERSION_MAJOR "@_target_qt_version@")
set(AM_TARGET_NAME @_moc_target_name@)
set(AM_RELAXED_MODE "@_moc_relaxed_mode@")
+set(AM_UIC_OPTIONS_FILES @_qt_uic_options_files@)
+set(AM_UIC_OPTIONS_OPTIONS @_qt_uic_options_options@)
diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx
index 58634ea..2f4d154 100644
--- a/Source/cmDocumentVariables.cxx
+++ b/Source/cmDocumentVariables.cxx
@@ -1336,6 +1336,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
"Variables that Control the Build");
cm->DefineProperty
+ ("CMAKE_AUTOUIC", cmProperty::VARIABLE,
+ "Whether to handle uic automatically for Qt targets.",
+ "This variable is used to initialize the "
+ "AUTOUIC property on all the targets. "
+ "See that target property for additional information.",
+ false,
+ "Variables that Control the Build");
+
+ cm->DefineProperty
("CMAKE_AUTOMOC_MOC_OPTIONS", cmProperty::VARIABLE,
"Additional options for moc when using automoc (see CMAKE_AUTOMOC).",
"This variable is used to initialize the "
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 067240c..1635eb8 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1169,7 +1169,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 40e55c2..b94740c 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -4682,3 +4682,13 @@ void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
pm[pid] = this->GetPolicyStatus(pid);
}
}
+
+void cmMakefile::AddQtUiFileWithOptions(cmSourceFile *sf)
+{
+ this->QtUiFilesWithOptions.push_back(sf);
+}
+
+std::vector<cmSourceFile*> cmMakefile::GetQtUiFilesWithOptions() const
+{
+ return this->QtUiFilesWithOptions;
+}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 362b066..dc62944 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -899,6 +899,9 @@ public:
std::set<cmStdString> const & GetSystemIncludeDirectories() const
{ return this->SystemIncludeDirectories; }
+ void AddQtUiFileWithOptions(cmSourceFile *sf);
+ std::vector<cmSourceFile*> GetQtUiFilesWithOptions() const;
+
protected:
// add link libraries and directories to the target
void AddGlobalLinkInformation(const char* name, cmTarget& target);
@@ -1074,6 +1077,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..9d886fe 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -117,6 +117,7 @@ cmQtAutoGenerators::cmQtAutoGenerators()
:Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0)
,ColorOutput(true)
,RunMocFailed(false)
+,RunUicFailed(false)
,GenerateAll(false)
{
@@ -255,7 +256,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 +338,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 +519,90 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget* target,
}
}
+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 = "";
+
+ 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());
+ bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC"));
+
+ if (skip)
+ {
+ skip_uic += sep;
+ skip_uic += absFile;
+ sep = ";";
+ }
+ }
+
+ 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 = "";
+
+ 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());
+ 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();
+ const char *qtVersion = makefile->GetDefinition("_target_qt_version");
+ if (strcmp(qtVersion, "5") == 0)
+ {
+ cmTarget *qt5Uic = makefile->FindTargetToUse("Qt5::uic");
+ if (!qt5Uic)
+ {
+ cmSystemTools::Error("Qt5::uic target not found ",
+ targetName);
+ return;
+ }
+ 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 +667,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 +701,28 @@ 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 *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 +896,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 +915,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 +957,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 +967,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 +1005,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 +1037,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 +1179,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 +1220,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 +1312,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 +1333,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 +1427,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 +1448,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 +1455,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 +1535,66 @@ 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 = uiFileName + ".ui";
+
+ 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::map<std::string, std::string>::const_iterator optionIt
+ = this->UicOptions.find(this->ProjectSourceDir + ui_input_file);
+ if (optionIt != this->UicOptions.end())
+ {
+ std::vector<std::string> opts;
+ cmSystemTools::ExpandListArgument(optionIt->second, opts);
+ 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(ui_output_file);
+ command.push_back(this->ProjectSourceDir + 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 true;
+}
std::string cmQtAutoGenerators::Join(const std::vector<std::string>& lst,
char separator)
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index fe38b05..4e8960f 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();
@@ -70,11 +82,14 @@ private:
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 +104,12 @@ private:
std::list<std::string> MocIncludes;
std::list<std::string> MocDefinitions;
std::vector<std::string> MocOptions;
+ 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 8bb7d96..5514fef 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -288,6 +288,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);
+ }
+ }
}
//----------------------------------------------------------------------------
@@ -396,6 +407,16 @@ void cmSourceFile::DefineProperties(cmake *cm)
"only used by some tools that wrap classes into other languages.");
cm->DefineProperty
+ ("AUTOUIC_OPTIONS", cmProperty::SOURCE_FILE,
+ "Additional options for uic when using autouic (see the AUTOUIC target "
+ "property)",
+ "This property holds additional command line options "
+ "which will be used when uic is executed during the build via autouic, "
+ "i.e. it is equivalent to the optional OPTIONS argument of the "
+ "qt4_wrap_ui() macro.\n"
+ "By default it is empty.");
+
+ cm->DefineProperty
("COMPILE_FLAGS", cmProperty::SOURCE_FILE,
"Additional flags to be added when compiling this source file.",
"These flags will be added to the list of compile flags when "
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 5ec0284..140fc98 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -249,6 +249,25 @@ void cmTarget::DefineProperties(cmake *cm)
"automoc targets together in an IDE, e.g. in MSVS.");
cm->DefineProperty
+ ("AUTOUIC", cmProperty::TARGET,
+ "Should the target be processed with autouic (for Qt projects).",
+ "AUTOUIC is a boolean specifying whether CMake will handle "
+ "the Qt uic code generator automatically, i.e. without having to use "
+ "the QT4_WRAP_UI() or QT5_WRAP_UI() macro. Currently Qt4 and Qt5 are "
+ "supported. "
+ "When this property is set to TRUE, CMake will scan the source files "
+ "at build time and invoke uic accordingly. "
+ "If an #include statement like #include \"ui_foo.h\" is found in "
+ "foo.cpp, a foo.ui file is expected next to foo.cpp, and uic is "
+ "run on the foo.ui file. "
+ "This property is initialized by the value of the variable "
+ "CMAKE_AUTOUIC if it is set when a target is created.\n"
+ "Additional command line options for uic can be set via the "
+ "UIC_OPTIONS source file property on the foo.ui file.\n"
+ "The global property AUTOGEN_TARGETS_FOLDER can be used to group the"
+ "autouic targets together in an IDE, e.g. in MSVS.");
+
+ cm->DefineProperty
("AUTOMOC_MOC_OPTIONS", cmProperty::TARGET,
"Additional options for moc when using automoc (see the AUTOMOC property)",
"This property is only used if the AUTOMOC property is set to TRUE for "
@@ -1647,6 +1666,7 @@ 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("LINK_DEPENDS_NO_SHARED", 0);
this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0);
diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt
index 540ba1a..b7849c1 100644
--- a/Tests/QtAutogen/CMakeLists.txt
+++ b/Tests/QtAutogen/CMakeLists.txt
@@ -35,6 +35,8 @@ add_definitions(-DFOO -DSomeDefine="Barx")
# enable relaxed mode so automoc can handle all the special cases:
set(CMAKE_AUTOMOC_RELAXED_MODE TRUE)
+set(CMAKE_AUTOUIC ON)
+
# create an executable and two library targets, each requiring automoc:
add_library(codeeditorLib STATIC codeeditor.cpp)
diff --git a/Tests/QtAutogen/calwidget.cpp b/Tests/QtAutogen/calwidget.cpp
index cbfa5a8..defde20 100644
--- a/Tests/QtAutogen/calwidget.cpp
+++ b/Tests/QtAutogen/calwidget.cpp
@@ -49,7 +49,10 @@
#include "calwidget.h"
+ #include "ui_calwidget.h"
+
Window::Window()
+ : ui(new Ui::Window)
{
createPreviewGroupBox();
createGeneralOptionsGroupBox();
diff --git a/Tests/QtAutogen/calwidget.h b/Tests/QtAutogen/calwidget.h
index 8447389..d21a473 100644
--- a/Tests/QtAutogen/calwidget.h
+++ b/Tests/QtAutogen/calwidget.h
@@ -52,6 +52,11 @@
class QGroupBox;
class QLabel;
+ namespace Ui
+ {
+ class Window;
+ }
+
class Window : public QWidget
{
Q_OBJECT
@@ -116,6 +121,8 @@
QCheckBox *firstFridayCheckBox;
QCheckBox *mayFirstCheckBox;
+
+ Ui::Window *ui;
};
#endif
diff --git a/Tests/QtAutogen/calwidget.ui b/Tests/QtAutogen/calwidget.ui
new file mode 100644
index 0000000..1c245ca
--- /dev/null
+++ b/Tests/QtAutogen/calwidget.ui
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Window</class>
+ <widget class="QWidget" name="Window">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>180</y>
+ <width>94</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
-----------------------------------------------------------------------
Summary of changes:
hooks/post-receive
--
CMake
More information about the Cmake-commits
mailing list