summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-03-02 14:26:13 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2017-03-02 14:26:13 (GMT)
commitc1fb7213edaf512774eb74adb0a89b4984f88904 (patch)
tree98b0418a4773c045e257d20eac411db6be200c01
parent6c332bd84ce320e4163130a052af7b9950b38318 (diff)
parent3bf28f5ed057b2fe4d90c601065188055bb052a1 (diff)
downloadCMake-c1fb7213edaf512774eb74adb0a89b4984f88904.zip
CMake-c1fb7213edaf512774eb74adb0a89b4984f88904.tar.gz
CMake-c1fb7213edaf512774eb74adb0a89b4984f88904.tar.bz2
Merge topic 'autogen_uic_paths'
3bf28f5e Autogen: New short InfoGet functions 154d8339 Autogen: Parse enabled feature configuration only ac77fa35 Autogen: Add missing return on error 662ad240 Autogen: Rename and merge moc related methods 5adf22bb Autogen: Add AUTOUIC_SEARCH_PATHS release notes 36fa535d Autogen: Add AUTOUIC_SEARCH_PATHS documentation 6d7c02db Autogen: Add AUTOUIC_SEARCH_PATHS test 1cdf7c1b Autogen: Add AUTOUIC_SEARCH_PATHS support 110c1bf4 Autogen: Add subDirPrefix function db431ecf Autogen: Merge FindInIncludeDirectories into FindIncludeFile
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-qt.7.rst4
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/prop_tgt/AUTOUIC.rst9
-rw-r--r--Help/prop_tgt/AUTOUIC_OPTIONS.rst2
-rw-r--r--Help/prop_tgt/AUTOUIC_SEARCH_PATHS.rst12
-rw-r--r--Help/release/dev/Autogen_uic_paths.rst10
-rw-r--r--Help/variable/CMAKE_AUTOUIC_SEARCH_PATHS.rst11
-rw-r--r--Modules/AutogenInfo.cmake.in3
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx15
-rw-r--r--Source/cmQtAutoGenerators.cxx516
-rw-r--r--Source/cmQtAutoGenerators.h18
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Tests/QtAutogen/CMakeLists.txt4
-rw-r--r--Tests/QtAutogen/uicInclude/CMakeLists.txt8
-rw-r--r--Tests/QtAutogen/uicInclude/PageC.ui24
-rw-r--r--Tests/QtAutogen/uicInclude/dirA/PageA.ui24
-rw-r--r--Tests/QtAutogen/uicInclude/dirB/sub/PageB.ui24
-rw-r--r--Tests/QtAutogen/uicInclude/main.cpp10
-rw-r--r--Tests/QtAutogen/uicInclude/main.hpp6
20 files changed, 440 insertions, 263 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 58dda2b..5bd6365 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -121,6 +121,7 @@ Properties on Targets
/prop_tgt/AUTOMOC
/prop_tgt/AUTOUIC
/prop_tgt/AUTOUIC_OPTIONS
+ /prop_tgt/AUTOUIC_SEARCH_PATHS
/prop_tgt/AUTORCC
/prop_tgt/AUTORCC_OPTIONS
/prop_tgt/BINARY_DIR
diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst
index 3b9931e..3b95b05 100644
--- a/Help/manual/cmake-qt.7.rst
+++ b/Help/manual/cmake-qt.7.rst
@@ -104,7 +104,9 @@ be run, and to create rules to execute ``uic`` at the appropriate time.
If a preprocessor ``#include`` directive is found which matches
``ui_<basename>.h``, and a ``<basename>.ui`` file exists, then ``uic`` will
-be executed to generate the appropriate file.
+be executed to generate the appropriate file. The ``<basename>.ui`` file is
+searched for first in the vicinity of including file and afterwards in the
+optional :prop_tgt:`AUTOUIC_SEARCH_PATHS` of the target.
The generated generated ``ui_*.h`` files are placed in the
``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/include`` directory which is
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index a25efe7..79c7cd8 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -264,6 +264,7 @@ Variables that Control the Build
/variable/CMAKE_AUTORCC_OPTIONS
/variable/CMAKE_AUTOUIC
/variable/CMAKE_AUTOUIC_OPTIONS
+ /variable/CMAKE_AUTOUIC_SEARCH_PATHS
/variable/CMAKE_BUILD_RPATH
/variable/CMAKE_BUILD_WITH_INSTALL_NAME_DIR
/variable/CMAKE_BUILD_WITH_INSTALL_RPATH
diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst
index fbf24c3..91d95e5 100644
--- a/Help/prop_tgt/AUTOUIC.rst
+++ b/Help/prop_tgt/AUTOUIC.rst
@@ -10,8 +10,13 @@ Qt4 and Qt5 are supported.
When this property is ``ON``, 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.
+``#include "ui_foo.h"`` is found in ``source.cpp``, a ``foo.ui`` file is
+searched for first in the vicinity of ``source.cpp`` and afterwards in the
+optional :prop_tgt:`AUTOUIC_SEARCH_PATHS` of the target.
+``uic`` is run on the ``foo.ui`` file to generate ``ui_foo.h`` in the directory
+``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/include``,
+which is added to the target's :prop_tgt:`INCLUDE_DIRECTORIES` automatically.
+
This property is initialized by the value of the :variable:`CMAKE_AUTOUIC`
variable if it is set when a target is created.
diff --git a/Help/prop_tgt/AUTOUIC_OPTIONS.rst b/Help/prop_tgt/AUTOUIC_OPTIONS.rst
index dc3bee5..9fb042e 100644
--- a/Help/prop_tgt/AUTOUIC_OPTIONS.rst
+++ b/Help/prop_tgt/AUTOUIC_OPTIONS.rst
@@ -1,7 +1,7 @@
AUTOUIC_OPTIONS
---------------
-Additional options for uic when using :prop_tgt:`AUTOUIC`
+Additional options for ``uic`` when using :prop_tgt:`AUTOUIC`
This property holds additional command line options which will be used when
``uic`` is executed during the build via :prop_tgt:`AUTOUIC`, i.e. it is
diff --git a/Help/prop_tgt/AUTOUIC_SEARCH_PATHS.rst b/Help/prop_tgt/AUTOUIC_SEARCH_PATHS.rst
new file mode 100644
index 0000000..96d9f89
--- /dev/null
+++ b/Help/prop_tgt/AUTOUIC_SEARCH_PATHS.rst
@@ -0,0 +1,12 @@
+AUTOUIC_SEARCH_PATHS
+--------------------
+
+Search path list used by :prop_tgt:`AUTOUIC` to find included
+``.ui`` files.
+
+This property is initialized by the value of the
+:variable:`CMAKE_AUTOUIC_SEARCH_PATHS` variable if it is set
+when a target is created. Otherwise it is empty.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/release/dev/Autogen_uic_paths.rst b/Help/release/dev/Autogen_uic_paths.rst
new file mode 100644
index 0000000..0893194
--- /dev/null
+++ b/Help/release/dev/Autogen_uic_paths.rst
@@ -0,0 +1,10 @@
+AutoGen uic paths
+-----------------
+
+* Variable :variable:`CMAKE_AUTOUIC_SEARCH_PATHS` was introduced to
+ allow :variable:`CMAKE_AUTOUIC` to search for ``foo.ui`` in more
+ places than the vicinity of the ``ui_foo.h`` including file.
+
+* The new target property :prop_tgt:`AUTOUIC_SEARCH_PATHS` was introduced to
+ allow :prop_tgt:`AUTOUIC` to search for ``foo.ui`` in more
+ places than the vicinity of the ``ui_foo.h`` including file.
diff --git a/Help/variable/CMAKE_AUTOUIC_SEARCH_PATHS.rst b/Help/variable/CMAKE_AUTOUIC_SEARCH_PATHS.rst
new file mode 100644
index 0000000..aa132bf
--- /dev/null
+++ b/Help/variable/CMAKE_AUTOUIC_SEARCH_PATHS.rst
@@ -0,0 +1,11 @@
+CMAKE_AUTOUIC_SEARCH_PATHS
+--------------------------
+
+Search path list used by :variable:`CMAKE_AUTOUIC` to find included
+``.ui`` files.
+
+This variable is used to initialize the :prop_tgt:`AUTOUIC_SEARCH_PATHS`
+property on all the targets. See that target property for additional
+information.
+
+By default it is empty.
diff --git a/Modules/AutogenInfo.cmake.in b/Modules/AutogenInfo.cmake.in
index fc5024f..fcecb6c 100644
--- a/Modules/AutogenInfo.cmake.in
+++ b/Modules/AutogenInfo.cmake.in
@@ -16,7 +16,7 @@ set(AM_QT_UIC_EXECUTABLE @_qt_uic_executable@)
set(AM_QT_RCC_EXECUTABLE @_qt_rcc_executable@)
# MOC settings
set(AM_MOC_SKIP @_moc_skip@)
-set(AM_MOC_COMPILE_DEFINITIONS @_moc_compile_defs@)
+set(AM_MOC_DEFINITIONS @_moc_compile_defs@)
set(AM_MOC_INCLUDES @_moc_incs@)
set(AM_MOC_OPTIONS @_moc_options@)
set(AM_MOC_RELAXED_MODE @_moc_relaxed_mode@)
@@ -26,6 +26,7 @@ set(AM_UIC_SKIP @_uic_skip@)
set(AM_UIC_TARGET_OPTIONS @_uic_target_options@)
set(AM_UIC_OPTIONS_FILES @_qt_uic_options_files@)
set(AM_UIC_OPTIONS_OPTIONS @_qt_uic_options_options@)
+set(AM_UIC_SEARCH_PATHS @_uic_search_paths@)
# RCC settings
set(AM_RCC_SOURCES @_rcc_files@ )
set(AM_RCC_INPUTS @_rcc_inputs@)
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index de18265..a45b3d5 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -306,6 +306,19 @@ static void UicSetupAutoTarget(
AddDefinitionEscaped(makefile, "_uic_skip", uicSkipList);
+ // Uic search paths
+ {
+ std::vector<std::string> uicSearchPaths;
+ cmSystemTools::ExpandListArgument(
+ GetSafeProperty(target, "AUTOUIC_SEARCH_PATHS"), uicSearchPaths);
+ const std::string srcDir = makefile->GetCurrentSourceDirectory();
+ for (std::vector<std::string>::iterator it = uicSearchPaths.begin();
+ it != uicSearchPaths.end(); ++it) {
+ *it = cmSystemTools::CollapseFullPath(*it, srcDir);
+ }
+ AddDefinitionEscaped(makefile, "_uic_search_paths", uicSearchPaths);
+ }
+
// Uic target options
{
std::string _uic_opts;
@@ -959,7 +972,7 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
it = configMocDefines.begin(),
end = configMocDefines.end();
it != end; ++it) {
- infoFile << "set(AM_MOC_COMPILE_DEFINITIONS_" << it->first << " "
+ infoFile << "set(AM_MOC_DEFINITIONS_" << it->first << " "
<< it->second << ")\n";
}
}
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index e7e456a..c83f9a9 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -55,20 +55,38 @@ static std::string Quoted(const std::string& text)
return res;
}
-static std::string GetConfigDefinition(cmMakefile* makefile,
- const std::string& key,
- const std::string& config)
+static void InfoGet(cmMakefile* makefile, const char* key, std::string& value)
{
- std::string keyConf = key;
- if (!config.empty()) {
- keyConf += "_";
- keyConf += config;
+ value = makefile->GetSafeDefinition(key);
+}
+
+static void InfoGet(cmMakefile* makefile, const char* key, bool& value)
+{
+ value = makefile->IsOn(key);
+}
+
+static void InfoGet(cmMakefile* makefile, const char* key,
+ std::vector<std::string>& list)
+{
+ cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list);
+}
+
+static void InfoGet(cmMakefile* makefile, const char* key,
+ const std::string& config, std::vector<std::string>& list)
+{
+ const char* valueConf = CM_NULLPTR;
+ {
+ std::string keyConf = key;
+ if (!config.empty()) {
+ keyConf += "_";
+ keyConf += config;
+ }
+ valueConf = makefile->GetDefinition(keyConf);
}
- const char* valueConf = makefile->GetDefinition(keyConf);
- if (valueConf != CM_NULLPTR) {
- return valueConf;
+ if (valueConf == CM_NULLPTR) {
+ valueConf = makefile->GetSafeDefinition(key);
}
- return makefile->GetSafeDefinition(key);
+ cmSystemTools::ExpandListArgument(valueConf, list);
}
static std::string SettingsFile(const std::string& targetDirectory)
@@ -94,6 +112,15 @@ static void SettingWrite(std::ostream& ostr, const char* key,
}
}
+std::string subDirPrefix(const std::string& fileName)
+{
+ std::string res(cmsys::SystemTools::GetFilenamePath(fileName));
+ if (!res.empty()) {
+ res += '/';
+ }
+ return res;
+}
+
static bool FileNameIsUnique(const std::string& filePath,
const std::map<std::string, std::string>& fileMap)
{
@@ -319,24 +346,27 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
}
// - Target names
- this->OriginTargetName =
- makefile->GetSafeDefinition("AM_ORIGIN_TARGET_NAME");
- this->AutogenTargetName = makefile->GetSafeDefinition("AM_TARGET_NAME");
-
- // - Directories
- this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR");
- this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR");
- this->CurrentSourceDir =
- makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR");
- this->CurrentBinaryDir =
- makefile->GetSafeDefinition("AM_CMAKE_CURRENT_BINARY_DIR");
+ InfoGet(makefile, "AM_TARGET_NAME", this->AutogenTargetName);
+ InfoGet(makefile, "AM_ORIGIN_TARGET_NAME", this->OriginTargetName);
+
+ // - Files and directories
+ InfoGet(makefile, "AM_CMAKE_SOURCE_DIR", this->ProjectSourceDir);
+ InfoGet(makefile, "AM_CMAKE_BINARY_DIR", this->ProjectBinaryDir);
+ InfoGet(makefile, "AM_CMAKE_CURRENT_SOURCE_DIR", this->CurrentSourceDir);
+ InfoGet(makefile, "AM_CMAKE_CURRENT_BINARY_DIR", this->CurrentBinaryDir);
+ InfoGet(makefile, "AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE",
+ this->IncludeProjectDirsBefore);
+ InfoGet(makefile, "AM_SOURCES", this->Sources);
+ InfoGet(makefile, "AM_HEADERS", this->Headers);
// - Qt environment
- this->QtMajorVersion = makefile->GetSafeDefinition("AM_QT_VERSION_MAJOR");
- if (this->QtMajorVersion == "") {
- this->QtMajorVersion =
- makefile->GetSafeDefinition("AM_Qt5Core_VERSION_MAJOR");
+ InfoGet(makefile, "AM_QT_VERSION_MAJOR", this->QtMajorVersion);
+ if (this->QtMajorVersion.empty()) {
+ InfoGet(makefile, "AM_Qt5Core_VERSION_MAJOR", this->QtMajorVersion);
}
+ InfoGet(makefile, "AM_QT_MOC_EXECUTABLE", this->MocExecutable);
+ InfoGet(makefile, "AM_QT_UIC_EXECUTABLE", this->UicExecutable);
+ InfoGet(makefile, "AM_QT_RCC_EXECUTABLE", this->RccExecutable);
// Check Qt version
if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) {
this->LogError("AutoGen: Error: Unsupported Qt version: " +
@@ -344,132 +374,115 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
return false;
}
- this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE");
- this->UicExecutable = makefile->GetSafeDefinition("AM_QT_UIC_EXECUTABLE");
- this->RccExecutable = makefile->GetSafeDefinition("AM_QT_RCC_EXECUTABLE");
-
- // - File Lists
- cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition("AM_SOURCES"),
- this->Sources);
- cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition("AM_HEADERS"),
- this->Headers);
-
// - Moc
- cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition("AM_MOC_SKIP"),
- this->MocSkipList);
- cmSystemTools::ExpandListArgument(
- GetConfigDefinition(makefile, "AM_MOC_COMPILE_DEFINITIONS", config),
- this->MocDefinitions);
- cmSystemTools::ExpandListArgument(
- GetConfigDefinition(makefile, "AM_MOC_INCLUDES", config),
- this->MocIncludePaths);
- cmSystemTools::ExpandListArgument(
- makefile->GetSafeDefinition("AM_MOC_OPTIONS"), this->MocOptions);
- {
- std::vector<std::string> mocDependFilters;
- cmSystemTools::ExpandListArgument(
- makefile->GetSafeDefinition("AM_MOC_DEPEND_FILTERS"), mocDependFilters);
- // Insert Q_PLUGIN_METADATA dependency filter
- if (this->QtMajorVersion != "4") {
- this->MocDependFilterPush("Q_PLUGIN_METADATA",
- "[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\("
- "[^\\)]*FILE[ \t]*\"([^\"]+)\"");
- }
- // Insert user defined dependency filters
- if ((mocDependFilters.size() % 2) == 0) {
- for (std::vector<std::string>::const_iterator dit =
- mocDependFilters.begin();
- dit != mocDependFilters.end(); dit += 2) {
- if (!this->MocDependFilterPush(*dit, *(dit + 1))) {
- return false;
+ if (this->MocEnabled()) {
+ InfoGet(makefile, "AM_MOC_SKIP", this->MocSkipList);
+ InfoGet(makefile, "AM_MOC_DEFINITIONS", config, this->MocDefinitions);
+ InfoGet(makefile, "AM_MOC_INCLUDES", config, this->MocIncludePaths);
+ InfoGet(makefile, "AM_MOC_OPTIONS", this->MocOptions);
+ InfoGet(makefile, "AM_MOC_RELAXED_MODE", this->MocRelaxedMode);
+ {
+ std::vector<std::string> mocDependFilters;
+ InfoGet(makefile, "AM_MOC_DEPEND_FILTERS", mocDependFilters);
+ // Insert Q_PLUGIN_METADATA dependency filter
+ if (this->QtMajorVersion != "4") {
+ this->MocDependFilterPush("Q_PLUGIN_METADATA",
+ "[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\("
+ "[^\\)]*FILE[ \t]*\"([^\"]+)\"");
+ }
+ // Insert user defined dependency filters
+ if ((mocDependFilters.size() % 2) == 0) {
+ for (std::vector<std::string>::const_iterator dit =
+ mocDependFilters.begin();
+ dit != mocDependFilters.end(); dit += 2) {
+ if (!this->MocDependFilterPush(*dit, *(dit + 1))) {
+ return false;
+ }
}
+ } else {
+ this->LogError(
+ "AutoMoc: Error: AUTOMOC_DEPEND_FILTERS list size is not "
+ "a multiple of 2");
+ return false;
}
- } else {
- this->LogError("AutoMoc: Error: AUTOMOC_DEPEND_FILTERS list size is not "
- "a multiple of 2");
}
}
// - Uic
- cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition("AM_UIC_SKIP"),
- this->UicSkipList);
- cmSystemTools::ExpandListArgument(
- GetConfigDefinition(makefile, "AM_UIC_TARGET_OPTIONS", config),
- this->UicTargetOptions);
- {
- std::vector<std::string> uicFilesVec;
- std::vector<std::string> uicOptionsVec;
- cmSystemTools::ExpandListArgument(
- makefile->GetSafeDefinition("AM_UIC_OPTIONS_FILES"), uicFilesVec);
- cmSystemTools::ExpandListArgument(
- makefile->GetSafeDefinition("AM_UIC_OPTIONS_OPTIONS"), uicOptionsVec);
- if (uicFilesVec.size() != uicOptionsVec.size()) {
- this->LogError(
- "AutoGen: Error: Uic files/options lists size missmatch in: " +
- filename);
- 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;
+ if (this->UicEnabled()) {
+ InfoGet(makefile, "AM_UIC_SKIP", this->UicSkipList);
+ InfoGet(makefile, "AM_UIC_SEARCH_PATHS", this->UicSearchPaths);
+ InfoGet(makefile, "AM_UIC_TARGET_OPTIONS", config, this->UicTargetOptions);
+ {
+ std::vector<std::string> uicFilesVec;
+ std::vector<std::string> uicOptionsVec;
+ InfoGet(makefile, "AM_UIC_OPTIONS_FILES", uicFilesVec);
+ InfoGet(makefile, "AM_UIC_OPTIONS_OPTIONS", uicOptionsVec);
+ // Compare list sizes
+ if (uicFilesVec.size() == uicOptionsVec.size()) {
+ 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;
+ }
+ } else {
+ this->LogError(
+ "AutoGen: Error: Uic files/options lists size missmatch in: " +
+ filename);
+ return false;
+ }
}
}
// - Rcc
- cmSystemTools::ExpandListArgument(
- makefile->GetSafeDefinition("AM_RCC_SOURCES"), this->RccSources);
- {
- std::vector<std::string> rccFilesVec;
- std::vector<std::string> rccOptionsVec;
- cmSystemTools::ExpandListArgument(
- makefile->GetSafeDefinition("AM_RCC_OPTIONS_FILES"), rccFilesVec);
- cmSystemTools::ExpandListArgument(
- makefile->GetSafeDefinition("AM_RCC_OPTIONS_OPTIONS"), rccOptionsVec);
- if (rccFilesVec.size() != rccOptionsVec.size()) {
- this->LogError(
- "AutoGen: Error: RCC files/options lists size missmatch in: " +
- filename);
- 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;
- }
- }
- {
- std::vector<std::string> rccInputLists;
- cmSystemTools::ExpandListArgument(
- makefile->GetSafeDefinition("AM_RCC_INPUTS"), rccInputLists);
-
- // qrc files in the end of the list may have been empty
- if (rccInputLists.size() < this->RccSources.size()) {
- rccInputLists.resize(this->RccSources.size());
- }
- if (this->RccSources.size() != rccInputLists.size()) {
- this->LogError(
- "AutoGen: Error: RCC sources/inputs lists size missmatch in: " +
- filename);
- return false;
+ if (this->RccEnabled()) {
+ InfoGet(makefile, "AM_RCC_SOURCES", this->RccSources);
+ {
+ std::vector<std::string> rccFilesVec;
+ std::vector<std::string> rccOptionsVec;
+ InfoGet(makefile, "AM_RCC_OPTIONS_FILES", rccFilesVec);
+ InfoGet(makefile, "AM_RCC_OPTIONS_OPTIONS", rccOptionsVec);
+ if (rccFilesVec.size() != rccOptionsVec.size()) {
+ this->LogError(
+ "AutoGen: Error: RCC files/options lists size missmatch in: " +
+ filename);
+ 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;
+ }
}
- for (std::vector<std::string>::iterator fileIt = this->RccSources.begin(),
- inputIt = rccInputLists.begin();
- fileIt != this->RccSources.end(); ++fileIt, ++inputIt) {
- cmSystemTools::ReplaceString(*inputIt, "@list_sep@", ";");
- std::vector<std::string> rccInputFiles;
- cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles);
- this->RccInputs[*fileIt] = rccInputFiles;
+ {
+ std::vector<std::string> rccInputLists;
+ InfoGet(makefile, "AM_RCC_INPUTS", rccInputLists);
+
+ // qrc files in the end of the list may have been empty
+ if (rccInputLists.size() < this->RccSources.size()) {
+ rccInputLists.resize(this->RccSources.size());
+ }
+ if (this->RccSources.size() != rccInputLists.size()) {
+ this->LogError(
+ "AutoGen: Error: RCC sources/inputs lists size missmatch in: " +
+ filename);
+ return false;
+ }
+ for (std::vector<std::string>::iterator
+ fileIt = this->RccSources.begin(),
+ inputIt = rccInputLists.begin();
+ fileIt != this->RccSources.end(); ++fileIt, ++inputIt) {
+ cmSystemTools::ReplaceString(*inputIt, "@list_sep@", ";");
+ std::vector<std::string> rccInputFiles;
+ cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles);
+ this->RccInputs[*fileIt] = rccInputFiles;
+ }
}
}
- // - Flags
- this->IncludeProjectDirsBefore =
- makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
- this->MocRelaxedMode = makefile->IsOn("AM_MOC_RELAXED_MODE");
-
return true;
}
@@ -727,15 +740,15 @@ void cmQtAutoGenerators::MocFindDepends(
// regular expression check
if (contentText.find(filter.key) != std::string::npos) {
// Run regular expression check loop
+ const std::string sourcePath = subDirPrefix(absFilename);
const char* contentChars = contentText.c_str();
while (filter.regExp.find(contentChars)) {
// Evaluate match
const std::string match = filter.regExp.match(1);
if (!match.empty()) {
// Find the dependency file
- const std::string incFile =
- this->FindIncludedFile(absFilename, match);
- if (!incFile.empty()) {
+ std::string incFile;
+ if (this->MocFindIncludedFile(incFile, sourcePath, match)) {
mocDepends[absFilename].insert(incFile);
if (this->Verbose) {
this->LogInfo("AutoMoc: Found dependency:\n " +
@@ -823,12 +836,7 @@ void cmQtAutoGenerators::UicParseContent(
const char* contentChars = contentText.c_str();
if (strstr(contentChars, "ui_") != CM_NULLPTR) {
while (this->RegExpUicInclude.find(contentChars)) {
- const std::string currentUi = this->RegExpUicInclude.match(1);
- const 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
- uisIncluded[absFilename].push_back(basename.substr(3));
+ uisIncluded[absFilename].push_back(this->RegExpUicInclude.match(1));
contentChars += this->RegExpUicInclude.end();
}
}
@@ -846,8 +854,7 @@ bool cmQtAutoGenerators::MocParseSourceContent(
this->LogInfo("AutoMoc: Checking " + absFilename);
}
- const std::string scannedFileAbsPath =
- cmsys::SystemTools::GetFilenamePath(absFilename) + '/';
+ const std::string scannedFileAbsPath = subDirPrefix(absFilename);
const std::string scannedFileBasename =
cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename);
@@ -866,13 +873,9 @@ bool cmQtAutoGenerators::MocParseSourceContent(
while (this->RegExpMocInclude.find(contentChars)) {
const std::string incString = this->RegExpMocInclude.match(1);
// Basename of the moc include
+ const std::string incSubDir(subDirPrefix(incString));
const std::string incBasename =
cmsys::SystemTools::GetFilenameWithoutLastExtension(incString);
- std::string incSubDir;
- if (incString.find_first_of('/') != std::string::npos) {
- incSubDir = cmsys::SystemTools::GetFilenamePath(incString);
- incSubDir += '/';
- }
// If the moc include is of the moc_foo.cpp style we expect
// the Q_OBJECT class declaration in a header file.
@@ -884,7 +887,7 @@ bool cmQtAutoGenerators::MocParseSourceContent(
// Remove the moc_ part
const std::string incRealBasename = incBasename.substr(4);
const std::string headerToMoc =
- this->FindMocHeader(scannedFileAbsPath, incRealBasename, incSubDir);
+ this->MocFindHeader(scannedFileAbsPath, incSubDir + incRealBasename);
if (!headerToMoc.empty()) {
// Register moc job
mocsIncluded[headerToMoc] = incString;
@@ -917,7 +920,7 @@ bool cmQtAutoGenerators::MocParseSourceContent(
} else {
// In relaxed mode try to find a header instead but issue a warning
const std::string headerToMoc =
- this->FindMocHeader(scannedFileAbsPath, incBasename, incSubDir);
+ this->MocFindHeader(scannedFileAbsPath, incSubDir + incBasename);
if (!headerToMoc.empty()) {
// This is for KDE4 compatibility:
fileToMoc = headerToMoc;
@@ -1056,8 +1059,7 @@ void cmQtAutoGenerators::SearchHeadersForSourceFile(
{
std::string basepaths[2];
{
- std::string bpath = cmsys::SystemTools::GetFilenamePath(absFilename);
- bpath += '/';
+ std::string bpath = subDirPrefix(absFilename);
bpath += cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename);
// search for default header files and private header files
basepaths[0] = bpath;
@@ -1235,14 +1237,14 @@ bool cmQtAutoGenerators::MocGenerateAll(
*/
bool cmQtAutoGenerators::MocGenerateFile(
const std::string& sourceFile, const std::string& mocFileName,
- const std::string& subDirPrefix,
+ const std::string& subDir,
const std::map<std::string, std::set<std::string> >& mocDepends)
{
bool mocGenerated = false;
bool generateMoc = this->GenerateAllMoc;
const std::string mocFileRel =
- this->AutogenBuildSubDir + subDirPrefix + mocFileName;
+ this->AutogenBuildSubDir + subDir + mocFileName;
const std::string mocFileAbs = this->CurrentBinaryDir + mocFileRel;
if (!generateMoc) {
@@ -1323,6 +1325,36 @@ bool cmQtAutoGenerators::MocGenerateFile(
return mocGenerated;
}
+bool cmQtAutoGenerators::UicFindIncludedFile(std::string& absFile,
+ const std::string& sourceFile,
+ const std::string& includeString)
+{
+ bool success = false;
+ // Search in vicinity of the source
+ {
+ std::string testPath = subDirPrefix(sourceFile);
+ testPath += includeString;
+ if (cmsys::SystemTools::FileExists(testPath.c_str())) {
+ absFile = cmsys::SystemTools::GetRealPath(testPath);
+ success = true;
+ }
+ }
+ // Search in include directories
+ if (!success) {
+ for (std::vector<std::string>::const_iterator iit =
+ this->UicSearchPaths.begin();
+ iit != this->UicSearchPaths.end(); ++iit) {
+ const std::string fullPath = ((*iit) + '/' + includeString);
+ if (cmsys::SystemTools::FileExists(fullPath.c_str())) {
+ absFile = cmsys::SystemTools::GetRealPath(fullPath);
+ success = true;
+ break;
+ }
+ }
+ }
+ return success;
+}
+
bool cmQtAutoGenerators::UicGenerateAll(
const std::map<std::string, std::vector<std::string> >& uisIncluded)
{
@@ -1331,46 +1363,57 @@ bool cmQtAutoGenerators::UicGenerateAll(
}
// single map with input / output names
- std::map<std::string, std::map<std::string, std::string> > uiGenMap;
- std::map<std::string, std::string> testMap;
- for (std::map<std::string, std::vector<std::string> >::const_iterator it =
- uisIncluded.begin();
- it != uisIncluded.end(); ++it) {
- // source file path
- std::string sourcePath = cmsys::SystemTools::GetFilenamePath(it->first);
- sourcePath += '/';
- // insert new map for source file an use new reference
- uiGenMap[it->first] = std::map<std::string, std::string>();
- std::map<std::string, std::string>& sourceMap = uiGenMap[it->first];
- for (std::vector<std::string>::const_iterator sit = it->second.begin();
- sit != it->second.end(); ++sit) {
- const std::string& uiFileName = *sit;
- const std::string uiInputFile = sourcePath + uiFileName + ".ui";
- const std::string uiOutputFile = "ui_" + uiFileName + ".h";
- sourceMap[uiInputFile] = uiOutputFile;
- testMap[uiInputFile] = uiOutputFile;
- }
- }
-
- // look for name collisions
+ std::map<std::string, std::map<std::string, std::string> > sourceGenMap;
{
- std::multimap<std::string, std::string> collisions;
- if (this->NameCollisionTest(testMap, collisions)) {
- std::ostringstream ost;
- ost << "AutoUic: Error: The same ui_NAME.h file will be generated "
- "from different sources.\n"
- "To avoid this error rename the source files.\n";
- this->LogErrorNameCollision(ost.str(), collisions);
- return false;
+ // Collision lookup map
+ std::map<std::string, std::string> testMap;
+ // Compile maps
+ for (std::map<std::string, std::vector<std::string> >::const_iterator sit =
+ uisIncluded.begin();
+ sit != uisIncluded.end(); ++sit) {
+ const std::string& source(sit->first);
+ const std::vector<std::string>& sourceIncs(sit->second);
+ // insert new source/destination map
+ std::map<std::string, std::string>& uiGenMap = sourceGenMap[source];
+ for (std::vector<std::string>::const_iterator uit = sourceIncs.begin();
+ uit != sourceIncs.end(); ++uit) {
+ // Remove ui_ from the begin filename by substr()
+ const std::string uiBasePath = subDirPrefix(*uit);
+ const std::string uiBaseName =
+ cmsys::SystemTools::GetFilenameWithoutLastExtension(*uit).substr(3);
+ const std::string searchFileName = uiBasePath + uiBaseName + ".ui";
+ std::string uiInputFile;
+ if (UicFindIncludedFile(uiInputFile, source, searchFileName)) {
+ std::string uiOutputFile = uiBasePath + "ui_" + uiBaseName + ".h";
+ cmSystemTools::ReplaceString(uiOutputFile, "..", "__");
+ uiGenMap[uiInputFile] = uiOutputFile;
+ testMap[uiInputFile] = uiOutputFile;
+ } else {
+ this->LogError("AutoUic: Error: " + Quoted(sit->first) +
+ "\nCould not find " + Quoted(searchFileName));
+ return false;
+ }
+ }
+ }
+ // look for name collisions
+ {
+ std::multimap<std::string, std::string> collisions;
+ if (this->NameCollisionTest(testMap, collisions)) {
+ std::ostringstream ost;
+ ost << "AutoUic: Error: The same ui_NAME.h file will be generated "
+ "from different sources.\n"
+ "To avoid this error rename the source files.\n";
+ this->LogErrorNameCollision(ost.str(), collisions);
+ return false;
+ }
}
}
- testMap.clear();
// generate ui files
for (std::map<std::string,
std::map<std::string, std::string> >::const_iterator it =
- uiGenMap.begin();
- it != uiGenMap.end(); ++it) {
+ sourceGenMap.begin();
+ it != sourceGenMap.end(); ++it) {
for (std::map<std::string, std::string>::const_iterator sit =
it->second.begin();
sit != it->second.end(); ++sit) {
@@ -1413,15 +1456,15 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName,
std::vector<std::string> cmd;
cmd.push_back(this->UicExecutable);
{
- std::vector<std::string> opts = this->UicTargetOptions;
+ std::vector<std::string> allOpts = this->UicTargetOptions;
std::map<std::string, std::string>::const_iterator optionIt =
this->UicOptions.find(uiInputFile);
if (optionIt != this->UicOptions.end()) {
std::vector<std::string> fileOpts;
cmSystemTools::ExpandListArgument(optionIt->second, fileOpts);
- UicMergeOptions(opts, fileOpts, (this->QtMajorVersion == "5"));
+ UicMergeOptions(allOpts, fileOpts, (this->QtMajorVersion == "5"));
}
- cmd.insert(cmd.end(), opts.begin(), opts.end());
+ cmd.insert(cmd.end(), allOpts.begin(), allOpts.end());
}
cmd.push_back("-o");
cmd.push_back(uicFileAbs);
@@ -1740,39 +1783,22 @@ bool cmQtAutoGenerators::FindHeader(std::string& header,
return false;
}
-bool cmQtAutoGenerators::FindHeaderGlobal(
- std::string& header, const std::string& testBasePath) const
-{
- for (std::vector<std::string>::const_iterator iit =
- this->MocIncludePaths.begin();
- iit != this->MocIncludePaths.end(); ++iit) {
- const std::string fullPath = ((*iit) + '/' + testBasePath);
- if (FindHeader(header, fullPath)) {
- return true;
- }
- }
- return false;
-}
-
-std::string cmQtAutoGenerators::FindMocHeader(const std::string& basePath,
- const std::string& baseName,
- const std::string& subDir) const
+std::string cmQtAutoGenerators::MocFindHeader(
+ const std::string& sourcePath, const std::string& includeBase) const
{
std::string header;
- do {
- if (!subDir.empty()) {
- if (this->FindHeader(header, basePath + subDir + baseName)) {
+ // Search in vicinity of the source
+ if (!this->FindHeader(header, sourcePath + includeBase)) {
+ // Search in include directories
+ for (std::vector<std::string>::const_iterator iit =
+ this->MocIncludePaths.begin();
+ iit != this->MocIncludePaths.end(); ++iit) {
+ const std::string fullPath = ((*iit) + '/' + includeBase);
+ if (FindHeader(header, fullPath)) {
break;
}
}
- if (this->FindHeader(header, basePath + baseName)) {
- break;
- }
- // Try include directories
- if (this->FindHeaderGlobal(header, subDir + baseName)) {
- break;
- }
- } while (false);
+ }
// Sanitize
if (!header.empty()) {
header = cmsys::SystemTools::GetRealPath(header);
@@ -1780,40 +1806,34 @@ std::string cmQtAutoGenerators::FindMocHeader(const std::string& basePath,
return header;
}
-std::string cmQtAutoGenerators::FindIncludedFile(
- const std::string& sourceFile, const std::string& includeString) const
+bool cmQtAutoGenerators::MocFindIncludedFile(
+ std::string& absFile, const std::string& sourcePath,
+ const std::string& includeString) const
{
+ bool success = false;
// Search in vicinity of the source
{
- std::string testPath = cmSystemTools::GetFilenamePath(sourceFile);
- testPath += '/';
+ std::string testPath = sourcePath;
testPath += includeString;
if (cmsys::SystemTools::FileExists(testPath.c_str())) {
- return cmsys::SystemTools::GetRealPath(testPath);
+ absFile = cmsys::SystemTools::GetRealPath(testPath);
+ success = true;
}
}
- // Search globally
- return FindInIncludeDirectories(includeString);
-}
-
-/**
- * @brief Tries to find a file in the include directories
- * @return True on success
- */
-std::string cmQtAutoGenerators::FindInIncludeDirectories(
- const std::string& includeString) const
-{
- std::string res;
- for (std::vector<std::string>::const_iterator iit =
- this->MocIncludePaths.begin();
- iit != this->MocIncludePaths.end(); ++iit) {
- const std::string fullPath = ((*iit) + '/' + includeString);
- if (cmsys::SystemTools::FileExists(fullPath.c_str())) {
- res = cmsys::SystemTools::GetRealPath(fullPath);
- break;
+ // Search in include directories
+ if (!success) {
+ for (std::vector<std::string>::const_iterator iit =
+ this->MocIncludePaths.begin();
+ iit != this->MocIncludePaths.end(); ++iit) {
+ const std::string fullPath = ((*iit) + '/' + includeString);
+ if (cmsys::SystemTools::FileExists(fullPath.c_str())) {
+ absFile = cmsys::SystemTools::GetRealPath(fullPath);
+ success = true;
+ break;
+ }
}
}
- return res;
+ return success;
}
/**
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index e4b7f60..3bff2b2 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -107,10 +107,12 @@ private:
const std::map<std::string, std::set<std::string> >& mocDepends);
bool MocGenerateFile(
const std::string& sourceFile, const std::string& mocFileName,
- const std::string& subDirPrefix,
+ const std::string& subDir,
const std::map<std::string, std::set<std::string> >& mocDepends);
// - Uic file generation
+ bool UicFindIncludedFile(std::string& absFile, const std::string& sourceFile,
+ const std::string& includeString);
bool UicGenerateAll(
const std::map<std::string, std::vector<std::string> >& includedUis);
bool UicGenerateFile(const std::string& realName,
@@ -142,14 +144,11 @@ private:
bool MakeParentDirectory(const std::string& filename) const;
bool FindHeader(std::string& header, const std::string& testBasePath) const;
- bool FindHeaderGlobal(std::string& header,
- const std::string& testBasePath) const;
- std::string FindMocHeader(const std::string& basePath,
- const std::string& baseName,
- const std::string& subDir) const;
- std::string FindIncludedFile(const std::string& sourceFile,
- const std::string& includeString) const;
- std::string FindInIncludeDirectories(const std::string& includeString) const;
+
+ std::string MocFindHeader(const std::string& sourcePath,
+ const std::string& includeBase) const;
+ bool MocFindIncludedFile(std::string& absFile, const std::string& sourceFile,
+ const std::string& includeString) const;
// - Target names
std::string OriginTargetName;
@@ -185,6 +184,7 @@ private:
std::vector<std::string> UicSkipList;
std::vector<std::string> UicTargetOptions;
std::map<std::string, std::string> UicOptions;
+ std::vector<std::string> UicSearchPaths;
// - Rcc
std::vector<std::string> RccSources;
std::map<std::string, std::string> RccOptions;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 0f3d91b..c360c19 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -248,6 +248,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
this->SetPropertyDefault("AUTOMOC_DEPEND_FILTERS", CM_NULLPTR);
this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", CM_NULLPTR);
this->SetPropertyDefault("AUTOUIC_OPTIONS", CM_NULLPTR);
+ this->SetPropertyDefault("AUTOUIC_SEARCH_PATHS", CM_NULLPTR);
this->SetPropertyDefault("AUTORCC_OPTIONS", CM_NULLPTR);
this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", CM_NULLPTR);
this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", CM_NULLPTR);
diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt
index dc631c6..4960472 100644
--- a/Tests/QtAutogen/CMakeLists.txt
+++ b/Tests/QtAutogen/CMakeLists.txt
@@ -287,5 +287,9 @@ if (NOT QT_TEST_VERSION STREQUAL 4)
endif()
# -- Test
+# Tests various .ui include directories
+add_subdirectory(uicInclude)
+
+# -- Test
# Complex test case
add_subdirectory(complex)
diff --git a/Tests/QtAutogen/uicInclude/CMakeLists.txt b/Tests/QtAutogen/uicInclude/CMakeLists.txt
new file mode 100644
index 0000000..f62ebb0
--- /dev/null
+++ b/Tests/QtAutogen/uicInclude/CMakeLists.txt
@@ -0,0 +1,8 @@
+# Test moc include patterns
+
+set(CMAKE_AUTOUIC_SEARCH_PATHS "dirA")
+
+add_executable(uicInclude main.cpp)
+target_link_libraries(uicInclude ${QT_LIBRARIES})
+set_target_properties(uicInclude PROPERTIES AUTOUIC ON)
+set_property(TARGET uicInclude APPEND PROPERTY AUTOUIC_SEARCH_PATHS "dirB")
diff --git a/Tests/QtAutogen/uicInclude/PageC.ui b/Tests/QtAutogen/uicInclude/PageC.ui
new file mode 100644
index 0000000..bb2fb5e
--- /dev/null
+++ b/Tests/QtAutogen/uicInclude/PageC.ui
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PageC</class>
+ <widget class="QWidget" name="PageC">
+ <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>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QTreeView" name="treeView"/>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutogen/uicInclude/dirA/PageA.ui b/Tests/QtAutogen/uicInclude/dirA/PageA.ui
new file mode 100644
index 0000000..dd81802
--- /dev/null
+++ b/Tests/QtAutogen/uicInclude/dirA/PageA.ui
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PageA</class>
+ <widget class="QWidget" name="PageA">
+ <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>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QTreeView" name="treeView"/>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutogen/uicInclude/dirB/sub/PageB.ui b/Tests/QtAutogen/uicInclude/dirB/sub/PageB.ui
new file mode 100644
index 0000000..fa6dfa6
--- /dev/null
+++ b/Tests/QtAutogen/uicInclude/dirB/sub/PageB.ui
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PageB</class>
+ <widget class="QWidget" name="PageB">
+ <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>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QTreeView" name="treeView"/>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutogen/uicInclude/main.cpp b/Tests/QtAutogen/uicInclude/main.cpp
new file mode 100644
index 0000000..4ca66a7
--- /dev/null
+++ b/Tests/QtAutogen/uicInclude/main.cpp
@@ -0,0 +1,10 @@
+
+#include "main.hpp"
+
+int main(int argv, char** args)
+{
+ return 0;
+}
+
+#include "sub/ui_PageB.h"
+#include "ui_PageC.h"
diff --git a/Tests/QtAutogen/uicInclude/main.hpp b/Tests/QtAutogen/uicInclude/main.hpp
new file mode 100644
index 0000000..58ddc26
--- /dev/null
+++ b/Tests/QtAutogen/uicInclude/main.hpp
@@ -0,0 +1,6 @@
+#ifndef MAIN_HPP
+#define MAIN_HPP
+
+#include "ui_PageA.h"
+
+#endif