瀏覽代碼

Merge topic 'autogen_path_prefix'

cc0900d9cd Help: Add release notes for AUTOMOC_PATH_PREFIX
692d8e3492 Help: Add documentation for AUTOMOC_PATH_PREFIX
1933ade9f1 Tests: At QtAutogen.MocIncludeSymlink test
706d9738a6 Tests: Merge QtAutogen.MocIncludeStrict and MocIncludeRelaxed
d018d27c10 Autogen: Add moc path prefix generation (AUTOMOC_PATH_PREFIX)
77983c8147 Autogen: Add IsHeader flag to SourceFileT class
f9e5441eb4 Autogen: Abbreviate file paths in messages
51676cf655 Autogen: Split JobEvalCacheT job into separate moc and uic jobs
...

Acked-by: Kitware Robot <[email protected]>
Merge-request: !3818
Brad King 6 年之前
父節點
當前提交
9c31d83aa2
共有 100 個文件被更改,包括 1830 次插入1286 次删除
  1. 1 0
      Help/manual/cmake-properties.7.rst
  2. 1 0
      Help/manual/cmake-variables.7.rst
  3. 32 0
      Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
  4. 13 0
      Help/release/dev/automoc_path_prefix.rst
  5. 11 0
      Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst
  6. 1 0
      Modules/CMakeGenericSystem.cmake
  7. 9 0
      Source/cmQtAutoGen.cxx
  8. 3 0
      Source/cmQtAutoGen.h
  9. 196 170
      Source/cmQtAutoGenInitializer.cxx
  10. 12 6
      Source/cmQtAutoGenInitializer.h
  11. 15 16
      Source/cmQtAutoGenerator.cxx
  12. 17 7
      Source/cmQtAutoGenerator.h
  13. 328 316
      Source/cmQtAutoMocUic.cxx
  14. 109 122
      Source/cmQtAutoMocUic.h
  15. 71 47
      Source/cmQtAutoRcc.cxx
  16. 1 0
      Source/cmTarget.cxx
  17. 112 0
      Tests/QtAutogen/MocInclude/CMakeLists.txt
  18. 11 0
      Tests/QtAutogen/MocInclude/Common/DualSub/Second/Second.cpp
  19. 14 0
      Tests/QtAutogen/MocInclude/Common/DualSub/Second/Second.hpp
  20. 9 0
      Tests/QtAutogen/MocInclude/Common/DualSubMocked.cpp
  21. 15 0
      Tests/QtAutogen/MocInclude/Common/DualSubMocked.hpp
  22. 11 0
      Tests/QtAutogen/MocInclude/Common/ExternDot.cpp
  23. 5 5
      Tests/QtAutogen/MocInclude/Common/ExternDot.hpp
  24. 11 0
      Tests/QtAutogen/MocInclude/Common/ExternDotGenerated.cpp.in
  25. 15 0
      Tests/QtAutogen/MocInclude/Common/ExternDotGenerated.hpp.in
  26. 43 0
      Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot.cpp
  27. 17 0
      Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot.hpp
  28. 18 0
      Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot_p.hpp
  29. 4 0
      Tests/QtAutogen/MocInclude/Common/InIncludesMoc.cpp
  30. 32 0
      Tests/QtAutogen/MocInclude/Common/MixedCustom.cpp
  31. 20 0
      Tests/QtAutogen/MocInclude/Common/MixedCustom.hpp
  32. 39 0
      Tests/QtAutogen/MocInclude/Common/MixedSkipped.cpp
  33. 17 0
      Tests/QtAutogen/MocInclude/Common/MixedSkipped.hpp
  34. 20 0
      Tests/QtAutogen/MocInclude/Common/None.cpp
  35. 19 0
      Tests/QtAutogen/MocInclude/Common/None.hpp
  36. 14 0
      Tests/QtAutogen/MocInclude/Common/None_p.h
  37. 44 0
      Tests/QtAutogen/MocInclude/Common/OtherUnderscore.cpp
  38. 19 0
      Tests/QtAutogen/MocInclude/Common/OtherUnderscore.hpp
  39. 20 0
      Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra.cpp
  40. 18 0
      Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra.hpp
  41. 14 0
      Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra_p.hpp
  42. 45 0
      Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub.cpp
  43. 19 0
      Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub.hpp
  44. 20 0
      Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra.cpp
  45. 18 0
      Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra.hpp
  46. 14 0
      Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra_p.hpp
  47. 14 0
      Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub_p.hpp
  48. 14 0
      Tests/QtAutogen/MocInclude/Common/OtherUnderscore_p.hpp
  49. 39 0
      Tests/QtAutogen/MocInclude/Common/OwnDot.cpp
  50. 19 0
      Tests/QtAutogen/MocInclude/Common/OwnDot.hpp
  51. 40 0
      Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore.cpp
  52. 19 0
      Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore.hpp
  53. 14 0
      Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore_p.h
  54. 14 0
      Tests/QtAutogen/MocInclude/Common/OwnDot_p.h
  55. 22 0
      Tests/QtAutogen/MocInclude/Common/OwnUnderscore.cpp
  56. 19 0
      Tests/QtAutogen/MocInclude/Common/OwnUnderscore.hpp
  57. 14 0
      Tests/QtAutogen/MocInclude/Common/OwnUnderscore_p.h
  58. 32 0
      Tests/QtAutogen/MocInclude/Common/common.cpp.in
  59. 5 0
      Tests/QtAutogen/MocInclude/Common/moc_MixedCustom.cpp.in
  60. 0 44
      Tests/QtAutogen/MocInclude/EObjA.cpp
  61. 0 19
      Tests/QtAutogen/MocInclude/EObjA.hpp
  62. 0 20
      Tests/QtAutogen/MocInclude/EObjAExtra.cpp
  63. 0 18
      Tests/QtAutogen/MocInclude/EObjAExtra.hpp
  64. 0 14
      Tests/QtAutogen/MocInclude/EObjAExtra_p.hpp
  65. 0 14
      Tests/QtAutogen/MocInclude/EObjA_p.hpp
  66. 0 45
      Tests/QtAutogen/MocInclude/EObjB.cpp
  67. 0 19
      Tests/QtAutogen/MocInclude/EObjB.hpp
  68. 0 14
      Tests/QtAutogen/MocInclude/EObjB_p.hpp
  69. 0 39
      Tests/QtAutogen/MocInclude/LObjA.cpp
  70. 0 19
      Tests/QtAutogen/MocInclude/LObjA.hpp
  71. 0 14
      Tests/QtAutogen/MocInclude/LObjA_p.h
  72. 0 40
      Tests/QtAutogen/MocInclude/LObjB.cpp
  73. 0 19
      Tests/QtAutogen/MocInclude/LObjB.hpp
  74. 0 14
      Tests/QtAutogen/MocInclude/LObjB_p.h
  75. 0 20
      Tests/QtAutogen/MocInclude/ObjA.cpp
  76. 0 19
      Tests/QtAutogen/MocInclude/ObjA.hpp
  77. 0 14
      Tests/QtAutogen/MocInclude/ObjA_p.h
  78. 0 22
      Tests/QtAutogen/MocInclude/ObjB.cpp
  79. 0 19
      Tests/QtAutogen/MocInclude/ObjB.hpp
  80. 0 14
      Tests/QtAutogen/MocInclude/ObjB_p.h
  81. 17 0
      Tests/QtAutogen/MocInclude/Relaxed/CMakeLists.txt
  82. 0 0
      Tests/QtAutogen/MocInclude/Relaxed/RObjA.cpp
  83. 0 0
      Tests/QtAutogen/MocInclude/Relaxed/RObjA.hpp
  84. 0 0
      Tests/QtAutogen/MocInclude/Relaxed/RObjB.cpp
  85. 0 0
      Tests/QtAutogen/MocInclude/Relaxed/RObjB.hpp
  86. 0 0
      Tests/QtAutogen/MocInclude/Relaxed/RObjBExtra.hpp
  87. 0 0
      Tests/QtAutogen/MocInclude/Relaxed/RObjC.cpp
  88. 0 0
      Tests/QtAutogen/MocInclude/Relaxed/RObjC.hpp
  89. 21 0
      Tests/QtAutogen/MocInclude/Relaxed/relaxed.cpp
  90. 0 11
      Tests/QtAutogen/MocInclude/SObjA.cpp
  91. 0 11
      Tests/QtAutogen/MocInclude/SObjB.cpp.in
  92. 0 15
      Tests/QtAutogen/MocInclude/SObjB.hpp.in
  93. 0 35
      Tests/QtAutogen/MocInclude/SObjC.cpp
  94. 0 15
      Tests/QtAutogen/MocInclude/SObjC.hpp
  95. 0 31
      Tests/QtAutogen/MocInclude/SObjCExtra.cpp
  96. 0 15
      Tests/QtAutogen/MocInclude/SObjCExtra.hpp
  97. 0 4
      Tests/QtAutogen/MocInclude/SObjCExtra.moc.in
  98. 14 0
      Tests/QtAutogen/MocInclude/Strict/CMakeLists.txt
  99. 7 0
      Tests/QtAutogen/MocInclude/Strict/strict.cpp
  100. 9 0
      Tests/QtAutogen/MocInclude/main.cpp

+ 1 - 0
Help/manual/cmake-properties.7.rst

@@ -134,6 +134,7 @@ Properties on Targets
    /prop_tgt/AUTOMOC_EXECUTABLE
    /prop_tgt/AUTOMOC_MACRO_NAMES
    /prop_tgt/AUTOMOC_MOC_OPTIONS
+   /prop_tgt/AUTOMOC_PATH_PREFIX
    /prop_tgt/AUTOMOC
    /prop_tgt/AUTOUIC
    /prop_tgt/AUTOUIC_EXECUTABLE

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -342,6 +342,7 @@ Variables that Control the Build
    /variable/CMAKE_AUTOMOC_DEPEND_FILTERS
    /variable/CMAKE_AUTOMOC_MACRO_NAMES
    /variable/CMAKE_AUTOMOC_MOC_OPTIONS
+   /variable/CMAKE_AUTOMOC_PATH_PREFIX
    /variable/CMAKE_AUTORCC
    /variable/CMAKE_AUTORCC_OPTIONS
    /variable/CMAKE_AUTOUIC

+ 32 - 0
Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst

@@ -0,0 +1,32 @@
+AUTOMOC_PATH_PREFIX
+-------------------
+
+When this property is ``ON``, CMake will generate the ``-p`` path prefix
+option for ``moc`` on :prop_tgt:`AUTOMOC` enabled Qt targets.
+
+To generate the path prefix, CMake tests if the header compiled by ``moc``
+is in any of the target
+:command:`include directories <target_include_directories>`.  If so, CMake will
+compute the relative path accordingly.  If the header is not in the
+:command:`include directories <target_include_directories>`, CMake will omit
+the ``-p`` path prefix option.  ``moc`` usually generates a
+relative include path in that case.
+
+:prop_tgt:`AUTOMOC_PATH_PREFIX` is initialized from the variable
+:variable:`CMAKE_AUTOMOC_PATH_PREFIX`, which is ``ON`` by default.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
+
+Reproducible builds
+^^^^^^^^^^^^^^^^^^^
+
+For reproducible builds is is recommended to keep headers that are ``moc``
+compiled in one of the target
+:command:`include directories <target_include_directories>` and set
+:prop_tgt:`AUTOMOC_PATH_PREFIX` to ``ON`` (which is the default).  This ensures
+that
+
+- ``moc`` output files are identical on different build setups,
+- ``moc`` output files will compile correctly when the source and/or
+  build directory is a symbolic link.

+ 13 - 0
Help/release/dev/automoc_path_prefix.rst

@@ -0,0 +1,13 @@
+automoc_path_prefix
+-------------------
+
+* When using :prop_tgt:`AUTOMOC`, CMake now generates the ``-p`` path prefix
+  option for ``moc``.  This ensures that ``moc`` output files are identical
+  on different build setups (given, that the headers compiled by ``moc`` are
+  in an :command:`include directory <target_include_directories>`).
+  Also it ensures that ``moc`` output files will compile correctly when the
+  source and/or build directory is a symbolic link.
+
+  The ``moc`` path prefix generation behavior can be configured by setting
+  the new :variable:`CMAKE_AUTOMOC_PATH_PREFIX` variable and/or
+  :prop_tgt:`AUTOMOC_PATH_PREFIX` target property.

+ 11 - 0
Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst

@@ -0,0 +1,11 @@
+CMAKE_AUTOMOC_PATH_PREFIX
+-------------------------
+
+Whether to generate the ``-p`` path prefix option for ``moc`` on
+:prop_tgt:`AUTOMOC` enabled Qt targets.
+
+This variable is used to initialize the :prop_tgt:`AUTOMOC_PATH_PREFIX`
+property on all the targets.  See that target property for additional
+information.
+
+The default value is ``ON``.

+ 1 - 0
Modules/CMakeGenericSystem.cmake

@@ -26,6 +26,7 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
 
 set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON)
 set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON)
+set(CMAKE_AUTOMOC_PATH_PREFIX ON)
 set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE")
 
 # basically all general purpose OSs support shared libs

+ 9 - 0
Source/cmQtAutoGen.cxx

@@ -162,6 +162,15 @@ std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command)
   return res;
 }
 
+std::string cmQtAutoGen::ParentDir(cm::string_view filename)
+{
+  auto slashPos = filename.rfind('/');
+  if (slashPos == cm::string_view::npos) {
+    return std::string();
+  }
+  return std::string(filename.substr(0, slashPos));
+}
+
 std::string cmQtAutoGen::SubDirPrefix(cm::string_view filename)
 {
   auto slashPos = filename.rfind('/');

+ 3 - 0
Source/cmQtAutoGen.h

@@ -80,6 +80,9 @@ public:
 
   static std::string QuotedCommand(std::vector<std::string> const& command);
 
+  /// @brief Returns the parent directory of the file (thread safe)
+  static std::string ParentDir(cm::string_view filename);
+
   /// @brief Returns the parent directory of the file with a "/" suffix
   static std::string SubDirPrefix(cm::string_view filename);
 

+ 196 - 170
Source/cmQtAutoGenInitializer.cxx

@@ -1,9 +1,11 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmQtAutoGenInitializer.h"
+
 #include "cmQtAutoGen.h"
 #include "cmQtAutoGenGlobalInitializer.h"
 
+#include "cmAlgorithms.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandLines.h"
 #include "cmFilePathChecksum.h"
@@ -41,7 +43,9 @@
 
 #include "cm_memory.hxx"
 
-static std::size_t GetParallelCPUCount()
+namespace {
+
+std::size_t GetParallelCPUCount()
 {
   static std::size_t count = 0;
   // Detect only on the first call
@@ -55,8 +59,8 @@ static std::size_t GetParallelCPUCount()
   return count;
 }
 
-static std::string FileProjectRelativePath(cmMakefile* makefile,
-                                           std::string const& fileName)
+std::string FileProjectRelativePath(cmMakefile* makefile,
+                                    std::string const& fileName)
 {
   std::string res;
   {
@@ -80,9 +84,9 @@ static std::string FileProjectRelativePath(cmMakefile* makefile,
  * recursive STATIC_LIBRARY dependencies depends on targetOrigin
  * (STATIC_LIBRARY cycle).
  */
-static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin,
-                               cmGeneratorTarget const* targetDepend,
-                               std::string const& config)
+bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin,
+                        cmGeneratorTarget const* targetDepend,
+                        std::string const& config)
 {
   bool cycle = false;
   if ((targetOrigin->GetType() == cmStateEnums::STATIC_LIBRARY) &&
@@ -120,6 +124,42 @@ static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin,
   return cycle;
 }
 
+/** Sanitizes file search paths */
+class SearchPathSanitizer
+{
+public:
+  SearchPathSanitizer(cmMakefile* makefile)
+    : SourcePath_(makefile->GetCurrentSourceDirectory())
+  {
+  }
+  std::vector<std::string> operator()(
+    std::vector<std::string> const& paths) const;
+
+private:
+  std::string SourcePath_;
+};
+
+std::vector<std::string> SearchPathSanitizer::operator()(
+  std::vector<std::string> const& paths) const
+{
+  std::vector<std::string> res;
+  res.reserve(paths.size());
+  for (std::string const& srcPath : paths) {
+    // Collapse relative paths
+    std::string path = cmSystemTools::CollapseFullPath(srcPath, SourcePath_);
+    // Remove suffix slashes
+    while (cmHasSuffix(path, '/')) {
+      path.pop_back();
+    }
+    // Accept only non empty paths
+    if (!path.empty()) {
+      res.emplace_back(std::move(path));
+    }
+  }
+  return res;
+}
+} // End of unnamed namespace
+
 cmQtAutoGenInitializer::InfoWriter::InfoWriter(std::string const& filename)
 {
   Ofs_.SetCopyIfDifferent(true);
@@ -213,11 +253,15 @@ void cmQtAutoGenInitializer::InfoWriter::WriteNestedLists(
 };
 
 cmQtAutoGenInitializer::cmQtAutoGenInitializer(
-  cmQtAutoGenGlobalInitializer* globalInitializer, cmGeneratorTarget* target,
-  IntegerVersion const& qtVersion, bool mocEnabled, bool uicEnabled,
-  bool rccEnabled, bool globalAutogenTarget, bool globalAutoRccTarget)
+  cmQtAutoGenGlobalInitializer* globalInitializer,
+  cmGeneratorTarget* genTarget, IntegerVersion const& qtVersion,
+  bool mocEnabled, bool uicEnabled, bool rccEnabled, bool globalAutogenTarget,
+  bool globalAutoRccTarget)
   : GlobalInitializer(globalInitializer)
-  , Target(target)
+  , GenTarget(genTarget)
+  , GlobalGen(genTarget->GetGlobalGenerator())
+  , LocalGen(genTarget->GetLocalGenerator())
+  , Makefile(genTarget->Makefile)
   , QtVersion(qtVersion)
 {
   AutogenTarget.GlobalTarget = globalAutogenTarget;
@@ -229,19 +273,15 @@ cmQtAutoGenInitializer::cmQtAutoGenInitializer(
 
 bool cmQtAutoGenInitializer::InitCustomTargets()
 {
-  cmMakefile* makefile = this->Target->Target->GetMakefile();
-  cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
-  cmGlobalGenerator* globalGen = localGen->GetGlobalGenerator();
-
   // Configurations
-  this->MultiConfig = globalGen->IsMultiConfig();
-  this->ConfigDefault = makefile->GetConfigurations(this->ConfigsList);
+  this->MultiConfig = this->GlobalGen->IsMultiConfig();
+  this->ConfigDefault = this->Makefile->GetConfigurations(this->ConfigsList);
   if (this->ConfigsList.empty()) {
     this->ConfigsList.push_back(this->ConfigDefault);
   }
 
   // Verbosity
-  this->Verbosity = makefile->GetSafeDefinition("CMAKE_AUTOGEN_VERBOSE");
+  this->Verbosity = this->Makefile->GetSafeDefinition("CMAKE_AUTOGEN_VERBOSE");
   if (!this->Verbosity.empty()) {
     unsigned long iVerb = 0;
     if (!cmStrToULong(this->Verbosity, &iVerb)) {
@@ -253,14 +293,14 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
   // Targets FOLDER
   {
     const char* folder =
-      makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
+      this->Makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
     if (folder == nullptr) {
-      folder =
-        makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");
+      folder = this->Makefile->GetState()->GetGlobalProperty(
+        "AUTOGEN_TARGETS_FOLDER");
     }
     // Inherit FOLDER property from target (#13688)
     if (folder == nullptr) {
-      folder = this->Target->GetProperty("FOLDER");
+      folder = this->GenTarget->GetProperty("FOLDER");
     }
     if (folder != nullptr) {
       this->TargetsFolder = folder;
@@ -270,7 +310,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
   // Check status of policy CMP0071
   {
     cmPolicies::PolicyStatus const CMP0071_status =
-      makefile->GetPolicyStatus(cmPolicies::CMP0071);
+      this->Makefile->GetPolicyStatus(cmPolicies::CMP0071);
     switch (CMP0071_status) {
       case cmPolicies::WARN:
         this->CMP0071Warn = true;
@@ -291,18 +331,18 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
   {
     // Collapsed current binary directory
     std::string const cbd = cmSystemTools::CollapseFullPath(
-      std::string(), makefile->GetCurrentBinaryDirectory());
+      std::string(), this->Makefile->GetCurrentBinaryDirectory());
 
     // Info directory
-    this->Dir.Info =
-      cmStrCat(cbd, "/CMakeFiles/", this->Target->GetName(), "_autogen.dir");
+    this->Dir.Info = cmStrCat(cbd, "/CMakeFiles/", this->GenTarget->GetName(),
+                              "_autogen.dir");
     cmSystemTools::ConvertToUnixSlashes(this->Dir.Info);
 
     // Build directory
-    this->Dir.Build = this->Target->GetSafeProperty("AUTOGEN_BUILD_DIR");
+    this->Dir.Build = this->GenTarget->GetSafeProperty("AUTOGEN_BUILD_DIR");
     if (this->Dir.Build.empty()) {
       this->Dir.Build =
-        cmStrCat(cbd, '/', this->Target->GetName(), "_autogen");
+        cmStrCat(cbd, '/', this->GenTarget->GetName(), "_autogen");
     }
     cmSystemTools::ConvertToUnixSlashes(this->Dir.Build);
     // Cleanup build directory
@@ -339,11 +379,12 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
     }
 
     // Autogen target name
-    this->AutogenTarget.Name = cmStrCat(this->Target->GetName(), "_autogen");
+    this->AutogenTarget.Name =
+      cmStrCat(this->GenTarget->GetName(), "_autogen");
 
     // Autogen target parallel processing
     this->AutogenTarget.Parallel =
-      this->Target->GetSafeProperty("AUTOGEN_PARALLEL");
+      this->GenTarget->GetSafeProperty("AUTOGEN_PARALLEL");
     if (this->AutogenTarget.Parallel.empty() ||
         (this->AutogenTarget.Parallel == "AUTO")) {
       // Autodetect number of CPUs
@@ -377,15 +418,14 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
     // Autogen target: Compute user defined dependencies
     {
       this->AutogenTarget.DependOrigin =
-        this->Target->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS");
+        this->GenTarget->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS");
 
       std::string const deps =
-        this->Target->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
+        this->GenTarget->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
       if (!deps.empty()) {
-        std::vector<std::string> extraDeps = cmExpandedList(deps);
-        for (std::string const& depName : extraDeps) {
+        for (std::string const& depName : cmExpandedList(deps)) {
           // Allow target and file dependencies
-          auto* depTarget = makefile->FindTargetToUse(depName);
+          auto* depTarget = this->Makefile->FindTargetToUse(depName);
           if (depTarget != nullptr) {
             this->AutogenTarget.DependTargets.insert(depTarget);
           } else {
@@ -397,13 +437,13 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
 
     // CMAKE_AUTOMOC_RELAXED_MODE deprecation warning
     if (this->Moc.Enabled) {
-      if (makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE")) {
-        makefile->IssueMessage(
+      if (this->Makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE")) {
+        this->Makefile->IssueMessage(
           MessageType::AUTHOR_WARNING,
           cmStrCat("AUTOMOC: CMAKE_AUTOMOC_RELAXED_MODE is "
                    "deprecated an will be removed in the future.  Consider "
                    "disabling it and converting the target ",
-                   this->Target->GetName(), " to regular mode."));
+                   this->GenTarget->GetName(), " to regular mode."));
       }
     }
   }
@@ -415,7 +455,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
 
   // Add autogen include directory to the origin target INCLUDE_DIRECTORIES
   if (this->MocOrUicEnabled() || (this->Rcc.Enabled && this->MultiConfig)) {
-    this->Target->AddIncludeDirectory(this->Dir.Include, true);
+    this->GenTarget->AddIncludeDirectory(this->Dir.Include, true);
   }
 
   // Scan files
@@ -438,33 +478,29 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
 
 bool cmQtAutoGenInitializer::InitMoc()
 {
-  cmMakefile* makefile = this->Target->Target->GetMakefile();
-  cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
-
   // Mocs compilation file
   this->Moc.MocsCompilation =
     cmStrCat(this->Dir.Build, "/mocs_compilation.cpp");
 
   // Moc predefs command
-  if (this->Target->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
+  if (this->GenTarget->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
       (this->QtVersion >= IntegerVersion(5, 8))) {
-    this->Moc.PredefsCmd =
-      makefile->GetSafeDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND");
+    this->Moc.PredefsCmd = this->Makefile->GetSafeDefinition(
+      "CMAKE_CXX_COMPILER_PREDEFINES_COMMAND");
   }
 
   // Moc includes
   {
-    bool const appendImplicit = (this->QtVersion.Major >= 5);
+    SearchPathSanitizer sanitizer(this->Makefile);
     auto GetIncludeDirs =
-      [this, localGen,
-       appendImplicit](std::string const& cfg) -> std::vector<std::string> {
+      [this, &sanitizer](std::string const& cfg) -> std::vector<std::string> {
       // Get the include dirs for this target, without stripping the implicit
-      // include dirs off, see
-      // https://gitlab.kitware.com/cmake/cmake/issues/13667
+      // include dirs off, see issue #13667.
       std::vector<std::string> dirs;
-      localGen->GetIncludeDirectoriesImplicit(dirs, this->Target, "CXX", cfg,
-                                              false, appendImplicit);
-      return dirs;
+      bool const appendImplicit = (this->QtVersion.Major >= 5);
+      this->LocalGen->GetIncludeDirectoriesImplicit(
+        dirs, this->GenTarget, "CXX", cfg, false, appendImplicit);
+      return sanitizer(dirs);
     };
 
     // Default configuration include directories
@@ -483,9 +519,9 @@ bool cmQtAutoGenInitializer::InitMoc()
   // Moc compile definitions
   {
     auto GetCompileDefinitions =
-      [this, localGen](std::string const& cfg) -> std::set<std::string> {
+      [this](std::string const& cfg) -> std::set<std::string> {
       std::set<std::string> defines;
-      localGen->GetTargetDefines(this->Target, cfg, "CXX", defines);
+      this->LocalGen->GetTargetDefines(this->GenTarget, cfg, "CXX", defines);
 #ifdef _WIN32
       if (this->Moc.PredefsCmd.empty()) {
         // Add WIN32 definition if we don't have a moc_predefs.h
@@ -525,18 +561,13 @@ bool cmQtAutoGenInitializer::InitMoc()
 
 bool cmQtAutoGenInitializer::InitUic()
 {
-  cmMakefile* makefile = this->Target->Target->GetMakefile();
-
   // Uic search paths
   {
     std::string const usp =
-      this->Target->GetSafeProperty("AUTOUIC_SEARCH_PATHS");
+      this->GenTarget->GetSafeProperty("AUTOUIC_SEARCH_PATHS");
     if (!usp.empty()) {
-      cmExpandList(usp, this->Uic.SearchPaths);
-      std::string const& srcDir = makefile->GetCurrentSourceDirectory();
-      for (std::string& path : this->Uic.SearchPaths) {
-        path = cmSystemTools::CollapseFullPath(path, srcDir);
-      }
+      this->Uic.SearchPaths =
+        SearchPathSanitizer(this->Makefile)(cmExpandedList(usp));
     }
   }
   // Uic target options
@@ -544,7 +575,7 @@ bool cmQtAutoGenInitializer::InitUic()
     auto UicGetOpts =
       [this](std::string const& cfg) -> std::vector<std::string> {
       std::vector<std::string> opts;
-      this->Target->GetAutoUicOptions(opts, cfg);
+      this->GenTarget->GetAutoUicOptions(opts, cfg);
       return opts;
     };
 
@@ -605,14 +636,13 @@ bool cmQtAutoGenInitializer::InitRcc()
 
 bool cmQtAutoGenInitializer::InitScanFiles()
 {
-  cmMakefile* makefile = this->Target->Target->GetMakefile();
-  cmake const* cm = makefile->GetCMakeInstance();
+  cmake const* cm = this->Makefile->GetCMakeInstance();
   auto const& kw = this->GlobalInitializer->kw();
 
   auto makeMUFile = [this, &kw](cmSourceFile* sf, std::string const& fullPath,
                                 bool muIt) -> MUFileHandle {
     MUFileHandle muf = cm::make_unique<MUFile>();
-    muf->RealPath = cmSystemTools::GetRealPath(fullPath);
+    muf->FullPath = fullPath;
     muf->SF = sf;
     muf->Generated = sf->GetIsGenerated();
     bool const skipAutogen = sf->GetPropertyAsBool(kw.SKIP_AUTOGEN);
@@ -642,9 +672,9 @@ bool cmQtAutoGenInitializer::InitScanFiles()
   {
     // Scan through target files
     std::vector<cmSourceFile*> srcFiles;
-    this->Target->GetConfigCommonSourceFiles(srcFiles);
+    this->GenTarget->GetConfigCommonSourceFiles(srcFiles);
     for (cmSourceFile* sf : srcFiles) {
-      // sf->GetExtension() is only valid after sf->GetFullPath() ...
+      // sf->GetExtension() is only valid after sf->ResolveFullPath() ...
       // Since we're iterating over source files that might be not in the
       // target we need to check for path errors (not existing files).
       std::string pathError;
@@ -670,7 +700,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
             !sf->GetPropertyAsBool(kw.SKIP_AUTORCC)) {
           // Register qrc file
           Qrc qrc;
-          qrc.QrcFile = cmSystemTools::GetRealPath(fullPath);
+          qrc.QrcFile = fullPath;
           qrc.QrcName =
             cmSystemTools::GetFilenameWithoutLastExtension(qrc.QrcFile);
           qrc.Generated = sf->GetIsGenerated();
@@ -690,7 +720,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
   // sources meta data cache. Clear it so that OBJECT library targets that
   // are AUTOGEN initialized after this target get their added
   // mocs_compilation.cpp source acknowledged by this target.
-  this->Target->ClearSourcesCache();
+  this->GenTarget->ClearSourcesCache();
 
   // For source files find additional headers and private headers
   if (this->MocOrUicEnabled()) {
@@ -704,21 +734,21 @@ bool cmQtAutoGenInitializer::InitScanFiles()
       MUFile const& muf = *pair.second;
       if (muf.MocIt || muf.UicIt) {
         // Search for the default header file and a private header
-        std::string const& srcPath = muf.SF->ResolveFullPath();
-        std::string basePath =
-          cmStrCat(cmQtAutoGen::SubDirPrefix(srcPath),
-                   cmSystemTools::GetFilenameWithoutLastExtension(srcPath));
+        std::string const& srcFullPath = muf.SF->ResolveFullPath();
+        std::string basePath = cmStrCat(
+          cmQtAutoGen::SubDirPrefix(srcFullPath),
+          cmSystemTools::GetFilenameWithoutLastExtension(srcFullPath));
         for (auto const& suffix : suffixes) {
           std::string const suffixedPath = cmStrCat(basePath, suffix);
           for (auto const& ext : exts) {
             std::string fullPath = cmStrCat(suffixedPath, '.', ext);
 
             auto constexpr locationKind = cmSourceFileLocationKind::Known;
-            cmSourceFile* sf = makefile->GetSource(fullPath, locationKind);
+            cmSourceFile* sf =
+              this->Makefile->GetSource(fullPath, locationKind);
             if (sf != nullptr) {
               // Check if we know about this header already
-              if (this->AutogenTarget.Headers.find(sf) !=
-                  this->AutogenTarget.Headers.end()) {
+              if (cmContains(this->AutogenTarget.Headers, sf)) {
                 continue;
               }
               // We only accept not-GENERATED files that do exist.
@@ -728,7 +758,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
               }
             } else if (cmSystemTools::FileExists(fullPath)) {
               // Create a new source file for the existing file
-              sf = makefile->CreateSource(fullPath, false, locationKind);
+              sf = this->Makefile->CreateSource(fullPath, false, locationKind);
             }
 
             if (sf != nullptr) {
@@ -757,8 +787,8 @@ bool cmQtAutoGenInitializer::InitScanFiles()
   // The reason is that their file names might be discovered from source files
   // at generation time.
   if (this->MocOrUicEnabled()) {
-    for (cmSourceFile* sf : makefile->GetSourceFiles()) {
-      // sf->GetExtension() is only valid after sf->GetFullPath() ...
+    for (cmSourceFile* sf : this->Makefile->GetSourceFiles()) {
+      // sf->GetExtension() is only valid after sf->ResolveFullPath() ...
       // Since we're iterating over source files that might be not in the
       // target we need to check for path errors (not existing files).
       std::string pathError;
@@ -770,16 +800,14 @@ bool cmQtAutoGenInitializer::InitScanFiles()
         cmSystemTools::LowerCase(sf->GetExtension());
 
       if (cm->IsHeaderExtension(extLower)) {
-        if (this->AutogenTarget.Headers.find(sf) ==
-            this->AutogenTarget.Headers.end()) {
+        if (!cmContains(this->AutogenTarget.Headers, sf)) {
           auto muf = makeMUFile(sf, fullPath, false);
           if (muf->SkipMoc || muf->SkipUic) {
             this->AutogenTarget.Headers.emplace(sf, std::move(muf));
           }
         }
       } else if (cm->IsSourceExtension(extLower)) {
-        if (this->AutogenTarget.Sources.find(sf) ==
-            this->AutogenTarget.Sources.end()) {
+        if (!cmContains(this->AutogenTarget.Headers, sf)) {
           auto muf = makeMUFile(sf, fullPath, false);
           if (muf->SkipMoc || muf->SkipUic) {
             this->AutogenTarget.Sources.emplace(sf, std::move(muf));
@@ -787,7 +815,6 @@ bool cmQtAutoGenInitializer::InitScanFiles()
         }
       } else if (this->Uic.Enabled && (extLower == kw.ui)) {
         // .ui file
-        std::string realPath = cmSystemTools::GetRealPath(fullPath);
         bool const skipAutogen = sf->GetPropertyAsBool(kw.SKIP_AUTOGEN);
         bool const skipUic =
           (skipAutogen || sf->GetPropertyAsBool(kw.SKIP_AUTOUIC));
@@ -795,13 +822,12 @@ bool cmQtAutoGenInitializer::InitScanFiles()
           // Check if the .ui file has uic options
           std::string const uicOpts = sf->GetSafeProperty(kw.AUTOUIC_OPTIONS);
           if (!uicOpts.empty()) {
-            this->Uic.FileFiles.push_back(std::move(realPath));
-            std::vector<std::string> optsVec = cmExpandedList(uicOpts);
-            this->Uic.FileOptions.push_back(std::move(optsVec));
+            this->Uic.FileFiles.push_back(fullPath);
+            this->Uic.FileOptions.push_back(cmExpandedList(uicOpts));
           }
         } else {
           // Register skipped .ui file
-          this->Uic.SkipUi.insert(std::move(realPath));
+          this->Uic.SkipUi.insert(fullPath);
         }
       }
     }
@@ -812,7 +838,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
     if (this->CMP0071Accept) {
       // Let the autogen target depend on the GENERATED files
       for (MUFile* muf : this->AutogenTarget.FilesGenerated) {
-        this->AutogenTarget.DependFiles.insert(muf->RealPath);
+        this->AutogenTarget.DependFiles.insert(muf->FullPath);
       }
     } else if (this->CMP0071Warn) {
       cm::string_view property;
@@ -825,9 +851,9 @@ bool cmQtAutoGenInitializer::InitScanFiles()
       }
       std::string files;
       for (MUFile* muf : this->AutogenTarget.FilesGenerated) {
-        files += cmStrCat("  ", Quoted(muf->RealPath), '\n');
+        files += cmStrCat("  ", Quoted(muf->FullPath), '\n');
       }
-      makefile->IssueMessage(
+      this->Makefile->IssueMessage(
         MessageType::AUTHOR_WARNING,
         cmStrCat(
           cmPolicies::GetPolicyWarning(cmPolicies::CMP0071), '\n',
@@ -848,7 +874,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
     const bool modernQt = (this->QtVersion.Major >= 5);
     // Target rcc options
     std::vector<std::string> optionsTarget =
-      cmExpandedList(this->Target->GetSafeProperty(kw.AUTORCC_OPTIONS));
+      cmExpandedList(this->GenTarget->GetSafeProperty(kw.AUTORCC_OPTIONS));
 
     // Check if file name is unique
     for (Qrc& qrc : this->Rcc.Qrcs) {
@@ -862,7 +888,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
     }
     // Path checksum and file names
     {
-      cmFilePathChecksum const fpathCheckSum(makefile);
+      cmFilePathChecksum const fpathCheckSum(this->Makefile);
       for (Qrc& qrc : this->Rcc.Qrcs) {
         qrc.PathChecksum = fpathCheckSum.getPart(qrc.QrcFile);
         // RCC output file name
@@ -925,12 +951,8 @@ bool cmQtAutoGenInitializer::InitScanFiles()
 
 bool cmQtAutoGenInitializer::InitAutogenTarget()
 {
-  cmMakefile* makefile = this->Target->Target->GetMakefile();
-  cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
-  cmGlobalGenerator* globalGen = localGen->GetGlobalGenerator();
-
   // Register info file as generated by CMake
-  makefile->AddCMakeOutputFile(this->AutogenTarget.InfoFile);
+  this->Makefile->AddCMakeOutputFile(this->AutogenTarget.InfoFile);
 
   // Files provided by the autogen target
   std::vector<std::string> autogenProvides;
@@ -952,8 +974,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
       }
       tools += "UIC";
     }
-    autogenComment =
-      cmStrCat("Automatic ", tools, " for target ", this->Target->GetName());
+    autogenComment = cmStrCat("Automatic ", tools, " for target ",
+                              this->GenTarget->GetName());
   }
 
   // Compose command lines
@@ -963,7 +985,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
 
   // Use PRE_BUILD on demand
   bool usePRE_BUILD = false;
-  if (globalGen->GetName().find("Visual Studio") != std::string::npos) {
+  if (this->GlobalGen->GetName().find("Visual Studio") != std::string::npos) {
     // Under VS use a PRE_BUILD event instead of a separate target to
     // reduce the number of targets loaded into the IDE.
     // This also works around a VS 11 bug that may skip updating the target:
@@ -985,7 +1007,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
   if (usePRE_BUILD) {
     // Add additional autogen target dependencies to origin target
     for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
-      this->Target->Target->AddUtility(depTarget->GetName(), makefile);
+      this->GenTarget->Target->AddUtility(depTarget->GetName(),
+                                          this->Makefile);
     }
 
     // Add the pre-build command directly to bypass the OBJECT_LIBRARY
@@ -995,12 +1018,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
     // PRE_BUILD does not support file dependencies!
     const std::vector<std::string> no_output;
     const std::vector<std::string> no_deps;
-    cmCustomCommand cc(makefile, no_output, autogenProvides, no_deps,
+    cmCustomCommand cc(this->Makefile, no_output, autogenProvides, no_deps,
                        commandLines, autogenComment.c_str(),
                        this->Dir.Work.c_str());
     cc.SetEscapeOldStyle(false);
     cc.SetEscapeAllowMakeVars(true);
-    this->Target->Target->AddPreBuildCommand(cc);
+    this->GenTarget->Target->AddPreBuildCommand(cc);
   } else {
 
     // Add link library target dependencies to the autogen target
@@ -1011,12 +1034,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
       std::map<cmGeneratorTarget const*, std::size_t> commonTargets;
       for (std::string const& config : this->ConfigsList) {
         cmLinkImplementationLibraries const* libs =
-          this->Target->GetLinkImplementationLibraries(config);
+          this->GenTarget->GetLinkImplementationLibraries(config);
         if (libs != nullptr) {
           for (cmLinkItem const& item : libs->Libraries) {
             cmGeneratorTarget const* libTarget = item.Target;
             if ((libTarget != nullptr) &&
-                !StaticLibraryCycle(this->Target, libTarget, config)) {
+                !StaticLibraryCycle(this->GenTarget, libTarget, config)) {
               // Increment target config count
               commonTargets[libTarget]++;
             }
@@ -1031,25 +1054,25 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
     }
 
     // Create autogen target
-    cmTarget* autogenTarget = makefile->AddUtilityCommand(
+    cmTarget* autogenTarget = this->Makefile->AddUtilityCommand(
       this->AutogenTarget.Name, cmMakefile::TargetOrigin::Generator, true,
       this->Dir.Work.c_str(), /*byproducts=*/autogenProvides,
       std::vector<std::string>(this->AutogenTarget.DependFiles.begin(),
                                this->AutogenTarget.DependFiles.end()),
       commandLines, false, autogenComment.c_str());
     // Create autogen generator target
-    localGen->AddGeneratorTarget(
-      new cmGeneratorTarget(autogenTarget, localGen));
+    this->LocalGen->AddGeneratorTarget(
+      new cmGeneratorTarget(autogenTarget, this->LocalGen));
 
     // Forward origin utilities to autogen target
     if (this->AutogenTarget.DependOrigin) {
-      for (BT<std::string> const& depName : this->Target->GetUtilities()) {
-        autogenTarget->AddUtility(depName.Value, makefile);
+      for (BT<std::string> const& depName : this->GenTarget->GetUtilities()) {
+        autogenTarget->AddUtility(depName.Value, this->Makefile);
       }
     }
     // Add additional autogen target dependencies to autogen target
     for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
-      autogenTarget->AddUtility(depTarget->GetName(), makefile);
+      autogenTarget->AddUtility(depTarget->GetName(), this->Makefile);
     }
 
     // Set FOLDER property in autogen target
@@ -1058,11 +1081,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
     }
 
     // Add autogen target to the origin target dependencies
-    this->Target->Target->AddUtility(this->AutogenTarget.Name, makefile);
+    this->GenTarget->Target->AddUtility(this->AutogenTarget.Name,
+                                        this->Makefile);
 
     // Add autogen target to the global autogen target dependencies
     if (this->AutogenTarget.GlobalTarget) {
-      this->GlobalInitializer->AddToGlobalAutoGen(localGen,
+      this->GlobalInitializer->AddToGlobalAutoGen(this->LocalGen,
                                                   this->AutogenTarget.Name);
     }
   }
@@ -1072,12 +1096,9 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
 
 bool cmQtAutoGenInitializer::InitRccTargets()
 {
-  cmMakefile* makefile = this->Target->Target->GetMakefile();
-  cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
-
   for (Qrc const& qrc : this->Rcc.Qrcs) {
     // Register info file as generated by CMake
-    makefile->AddCMakeOutputFile(qrc.InfoFile);
+    this->Makefile->AddCMakeOutputFile(qrc.InfoFile);
     // Register file at target
     this->AddGeneratedSource(qrc.RccFile, this->Rcc);
 
@@ -1102,41 +1123,43 @@ bool cmQtAutoGenInitializer::InitRccTargets()
         cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E",
                             "cmake_autorcc", qrc.InfoFile, "$<CONFIG>" }));
     }
-    std::string ccComment = cmStrCat(
-      "Automatic RCC for ", FileProjectRelativePath(makefile, qrc.QrcFile));
+    std::string ccComment =
+      cmStrCat("Automatic RCC for ",
+               FileProjectRelativePath(this->Makefile, qrc.QrcFile));
 
     if (qrc.Generated || this->Rcc.GlobalTarget) {
       // Create custom rcc target
       std::string ccName;
       {
-        ccName = cmStrCat(this->Target->GetName(), "_arcc_", qrc.QrcName);
+        ccName = cmStrCat(this->GenTarget->GetName(), "_arcc_", qrc.QrcName);
         if (!qrc.Unique) {
           ccName += cmStrCat('_', qrc.PathChecksum);
         }
 
-        cmTarget* autoRccTarget = makefile->AddUtilityCommand(
+        cmTarget* autoRccTarget = this->Makefile->AddUtilityCommand(
           ccName, cmMakefile::TargetOrigin::Generator, true,
           this->Dir.Work.c_str(), ccOutput, ccDepends, commandLines, false,
           ccComment.c_str());
 
         // Create autogen generator target
-        localGen->AddGeneratorTarget(
-          new cmGeneratorTarget(autoRccTarget, localGen));
+        this->LocalGen->AddGeneratorTarget(
+          new cmGeneratorTarget(autoRccTarget, this->LocalGen));
 
         // Set FOLDER property in autogen target
         if (!this->TargetsFolder.empty()) {
           autoRccTarget->SetProperty("FOLDER", this->TargetsFolder.c_str());
         }
         if (!this->Rcc.ExecutableTargetName.empty()) {
-          autoRccTarget->AddUtility(this->Rcc.ExecutableTargetName, makefile);
+          autoRccTarget->AddUtility(this->Rcc.ExecutableTargetName,
+                                    this->Makefile);
         }
       }
       // Add autogen target to the origin target dependencies
-      this->Target->Target->AddUtility(ccName, makefile);
+      this->GenTarget->Target->AddUtility(ccName, this->Makefile);
 
       // Add autogen target to the global autogen target dependencies
       if (this->Rcc.GlobalTarget) {
-        this->GlobalInitializer->AddToGlobalAutoRcc(localGen, ccName);
+        this->GlobalInitializer->AddToGlobalAutoRcc(this->LocalGen, ccName);
       }
     } else {
       // Create custom rcc command
@@ -1153,13 +1176,13 @@ bool cmQtAutoGenInitializer::InitRccTargets()
         }
         std::string no_main_dependency;
         cmImplicitDependsList no_implicit_depends;
-        makefile->AddCustomCommandToOutput(
+        this->Makefile->AddCustomCommandToOutput(
           ccOutput, ccByproducts, ccDepends, no_main_dependency,
           no_implicit_depends, commandLines, ccComment.c_str(),
           this->Dir.Work.c_str());
       }
       // Reconfigure when .qrc file changes
-      makefile->AddCMakeDependFile(qrc.QrcFile);
+      this->Makefile->AddCMakeDependFile(qrc.QrcFile);
     }
   }
 
@@ -1192,9 +1215,8 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
   InfoWriter ofs(this->AutogenTarget.InfoFile);
   if (ofs) {
     // Utility lambdas
-    cmMakefile* makefile = this->Target->Target->GetMakefile();
-    auto MfDef = [makefile](const char* key) {
-      return makefile->GetSafeDefinition(key);
+    auto MfDef = [this](const char* key) {
+      return this->Makefile->GetSafeDefinition(key);
     };
 
     // Write common settings
@@ -1210,8 +1232,6 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
               MfDef("CMAKE_CURRENT_SOURCE_DIR"));
     ofs.Write("AM_CMAKE_CURRENT_BINARY_DIR",
               MfDef("CMAKE_CURRENT_BINARY_DIR"));
-    ofs.Write("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE",
-              MfDef("CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE"));
     ofs.Write("AM_BUILD_DIR", this->Dir.Build);
     ofs.Write("AM_INCLUDE_DIR", this->Dir.Include);
     ofs.WriteConfig("AM_INCLUDE_DIR", this->Dir.ConfigInclude);
@@ -1238,7 +1258,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
         }
         std::sort(sortedHeaders.begin(), sortedHeaders.end(),
                   [](MUFile const* a, MUFile const* b) {
-                    return (a->RealPath < b->RealPath);
+                    return (a->FullPath < b->FullPath);
                   });
       }
 
@@ -1247,13 +1267,13 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
           continue;
         }
         if (muf->SkipMoc) {
-          moc_skip.insert(muf->RealPath);
+          moc_skip.insert(muf->FullPath);
         }
         if (muf->SkipUic) {
-          uic_skip.insert(muf->RealPath);
+          uic_skip.insert(muf->FullPath);
         }
         if (muf->MocIt || muf->UicIt) {
-          headers.emplace_back(muf->RealPath);
+          headers.emplace_back(muf->FullPath);
           headersFlags.emplace_back(
             cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u'));
         }
@@ -1261,7 +1281,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
     }
     // Header build paths
     {
-      cmFilePathChecksum const fpathCheckSum(makefile);
+      cmFilePathChecksum const fpathCheckSum(this->Makefile);
       std::unordered_set<std::string> emitted;
       for (std::string const& hdr : headers) {
         std::string const basePath =
@@ -1292,7 +1312,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
       }
       std::sort(sorted.begin(), sorted.end(),
                 [](MUFile const* a, MUFile const* b) {
-                  return (a->RealPath < b->RealPath);
+                  return (a->FullPath < b->FullPath);
                 });
 
       for (MUFile const* const muf : sorted) {
@@ -1300,13 +1320,13 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
           continue;
         }
         if (muf->SkipMoc) {
-          moc_skip.insert(muf->RealPath);
+          moc_skip.insert(muf->FullPath);
         }
         if (muf->SkipUic) {
-          uic_skip.insert(muf->RealPath);
+          uic_skip.insert(muf->FullPath);
         }
         if (muf->MocIt || muf->UicIt) {
-          sources.emplace_back(muf->RealPath);
+          sources.emplace_back(muf->FullPath);
           sourcesFlags.emplace_back(
             cmStrCat(muf->MocIt ? 'M' : 'm', muf->UicIt ? 'U' : 'u'));
         }
@@ -1339,12 +1359,14 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
       ofs.WriteStrings("AM_MOC_INCLUDES", this->Moc.Includes);
       ofs.WriteConfigStrings("AM_MOC_INCLUDES", this->Moc.ConfigIncludes);
       ofs.Write("AM_MOC_OPTIONS",
-                this->Target->GetSafeProperty("AUTOMOC_MOC_OPTIONS"));
+                this->GenTarget->GetSafeProperty("AUTOMOC_MOC_OPTIONS"));
       ofs.Write("AM_MOC_RELAXED_MODE", MfDef("CMAKE_AUTOMOC_RELAXED_MODE"));
+      ofs.Write("AM_MOC_PATH_PREFIX",
+                this->GenTarget->GetSafeProperty("AUTOMOC_PATH_PREFIX"));
       ofs.Write("AM_MOC_MACRO_NAMES",
-                this->Target->GetSafeProperty("AUTOMOC_MACRO_NAMES"));
+                this->GenTarget->GetSafeProperty("AUTOMOC_MACRO_NAMES"));
       ofs.Write("AM_MOC_DEPEND_FILTERS",
-                this->Target->GetSafeProperty("AUTOMOC_DEPEND_FILTERS"));
+                this->GenTarget->GetSafeProperty("AUTOMOC_DEPEND_FILTERS"));
       ofs.Write("AM_MOC_PREDEFS_CMD", this->Moc.PredefsCmd);
     }
 
@@ -1375,6 +1397,11 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo()
   for (Qrc const& qrc : this->Rcc.Qrcs) {
     InfoWriter ofs(qrc.InfoFile);
     if (ofs) {
+      // Utility lambdas
+      auto MfDef = [this](const char* key) {
+        return this->Makefile->GetSafeDefinition(key);
+      };
+
       // Write
       ofs.Write("# Configurations\n");
       ofs.Write("ARCC_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE");
@@ -1384,6 +1411,8 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo()
       ofs.WriteConfig("ARCC_SETTINGS_FILE", qrc.ConfigSettingsFile);
 
       ofs.Write("# Directories\n");
+      ofs.Write("ARCC_CMAKE_SOURCE_DIR", MfDef("CMAKE_SOURCE_DIR"));
+      ofs.Write("ARCC_CMAKE_BINARY_DIR", MfDef("CMAKE_BINARY_DIR"));
       ofs.Write("ARCC_BUILD_DIR", this->Dir.Build);
       ofs.Write("ARCC_INCLUDE_DIR", this->Dir.Include);
       ofs.WriteConfig("ARCC_INCLUDE_DIR", this->Dir.ConfigInclude);
@@ -1414,8 +1443,7 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo()
 void cmQtAutoGenInitializer::RegisterGeneratedSource(
   std::string const& filename)
 {
-  cmMakefile* makefile = this->Target->Target->GetMakefile();
-  cmSourceFile* gFile = makefile->GetOrCreateSource(filename, true);
+  cmSourceFile* gFile = this->Makefile->GetOrCreateSource(filename, true);
   gFile->SetProperty("GENERATED", "1");
   gFile->SetProperty("SKIP_AUTOGEN", "1");
 }
@@ -1427,7 +1455,7 @@ bool cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename,
   // Register source at makefile
   this->RegisterGeneratedSource(filename);
   // Add source file to target
-  this->Target->AddSource(filename, prepend);
+  this->GenTarget->AddSource(filename, prepend);
   // Add source file to source group
   return this->AddToSourceGroup(filename, genVars.GenNameUpper);
 }
@@ -1435,7 +1463,6 @@ bool cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename,
 bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
                                               cm::string_view genNameUpper)
 {
-  cmMakefile* makefile = this->Target->Target->GetMakefile();
   cmSourceGroup* sourceGroup = nullptr;
   // Acquire source group
   {
@@ -1447,7 +1474,8 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
         cmStrCat(genNameUpper, "_SOURCE_GROUP"), "AUTOGEN_SOURCE_GROUP"
       };
       for (std::string const& prop : props) {
-        const char* propName = makefile->GetState()->GetGlobalProperty(prop);
+        const char* propName =
+          this->Makefile->GetState()->GetGlobalProperty(prop);
         if ((propName != nullptr) && (*propName != '\0')) {
           groupName = propName;
           property = prop;
@@ -1457,7 +1485,7 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
     }
     // Generate a source group on demand
     if (!groupName.empty()) {
-      sourceGroup = makefile->GetOrCreateSourceGroup(groupName);
+      sourceGroup = this->Makefile->GetOrCreateSourceGroup(groupName);
       if (sourceGroup == nullptr) {
         cmSystemTools::Error(
           cmStrCat(genNameUpper, " error in ", property,
@@ -1475,8 +1503,8 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
 
 void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName)
 {
-  Target->Target->AppendProperty("ADDITIONAL_CLEAN_FILES", fileName.c_str(),
-                                 false);
+  this->GenTarget->Target->AppendProperty("ADDITIONAL_CLEAN_FILES",
+                                          fileName.c_str(), false);
 }
 
 static unsigned int CharPtrToUInt(const char* const input)
@@ -1489,7 +1517,7 @@ static unsigned int CharPtrToUInt(const char* const input)
 }
 
 static std::vector<cmQtAutoGen::IntegerVersion> GetKnownQtVersions(
-  cmGeneratorTarget const* target)
+  cmGeneratorTarget const* genTarget)
 {
   // Qt version variable prefixes
   static std::initializer_list<
@@ -1511,7 +1539,7 @@ static std::vector<cmQtAutoGen::IntegerVersion> GetKnownQtVersions(
     }
   };
 
-  cmMakefile* makefile = target->Target->GetMakefile();
+  cmMakefile* makefile = genTarget->Makefile;
 
   // Read versions from variables
   for (auto const& keyPair : keys) {
@@ -1561,22 +1589,20 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
 {
   auto print_err = [this, &genVars](std::string const& err) {
     cmSystemTools::Error(cmStrCat(genVars.GenNameUpper, " for target ",
-                                  this->Target->GetName(), ": ", err));
+                                  this->GenTarget->GetName(), ": ", err));
   };
 
   // Custom executable
   {
     std::string const prop = cmStrCat(genVars.GenNameUpper, "_EXECUTABLE");
-    std::string const val = this->Target->Target->GetSafeProperty(prop);
+    std::string const val = this->GenTarget->Target->GetSafeProperty(prop);
     if (!val.empty()) {
       // Evaluate generator expression
       {
-        cmListFileBacktrace lfbt =
-          this->Target->Target->GetMakefile()->GetBacktrace();
+        cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
         cmGeneratorExpression ge(lfbt);
         std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(val);
-        genVars.Executable =
-          cge->Evaluate(this->Target->GetLocalGenerator(), "");
+        genVars.Executable = cge->Evaluate(this->LocalGen, "");
       }
       if (genVars.Executable.empty() && !ignoreMissingTarget) {
         print_err(prop + " evaluates to an empty value");
@@ -1604,15 +1630,15 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
     std::string const targetName = cmStrCat(prefix, executable);
 
     // Find target
-    cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
-    cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(targetName);
-    if (target != nullptr) {
+    cmGeneratorTarget* genTarget =
+      this->LocalGen->FindGeneratorTargetToUse(targetName);
+    if (genTarget != nullptr) {
       genVars.ExecutableTargetName = targetName;
-      genVars.ExecutableTarget = target;
-      if (target->IsImported()) {
-        genVars.Executable = target->ImportedGetLocation("");
+      genVars.ExecutableTarget = genTarget;
+      if (genTarget->IsImported()) {
+        genVars.Executable = genTarget->ImportedGetLocation("");
       } else {
-        genVars.Executable = target->GetLocation("");
+        genVars.Executable = genTarget->GetLocation("");
       }
     } else {
       if (ignoreMissingTarget) {

+ 12 - 6
Source/cmQtAutoGenInitializer.h

@@ -18,9 +18,12 @@
 #include <vector>
 
 class cmGeneratorTarget;
-class cmTarget;
+class cmGlobalGenerator;
+class cmLocalGenerator;
+class cmMakefile;
 class cmQtAutoGenGlobalInitializer;
 class cmSourceFile;
+class cmTarget;
 
 /// @brief Initializes the QtAutoGen generators
 class cmQtAutoGenInitializer : public cmQtAutoGen
@@ -47,7 +50,7 @@ public:
   /// @brief Moc/Uic file
   struct MUFile
   {
-    std::string RealPath;
+    std::string FullPath;
     cmSourceFile* SF = nullptr;
     bool Generated = false;
     bool SkipMoc = false;
@@ -112,10 +115,10 @@ public:
 public:
   /// @return The detected Qt version and the required Qt major version
   static std::pair<IntegerVersion, unsigned int> GetQtVersion(
-    cmGeneratorTarget const* target);
+    cmGeneratorTarget const* genTarget);
 
   cmQtAutoGenInitializer(cmQtAutoGenGlobalInitializer* globalInitializer,
-                         cmGeneratorTarget* target,
+                         cmGeneratorTarget* genTarget,
                          IntegerVersion const& qtVersion, bool mocEnabled,
                          bool uicEnabled, bool rccEnabled,
                          bool globalAutogenTarget, bool globalAutoRccTarget);
@@ -152,8 +155,11 @@ private:
                        bool ignoreMissingTarget) const;
 
 private:
-  cmQtAutoGenGlobalInitializer* GlobalInitializer;
-  cmGeneratorTarget* Target;
+  cmQtAutoGenGlobalInitializer* GlobalInitializer = nullptr;
+  cmGeneratorTarget* GenTarget = nullptr;
+  cmGlobalGenerator* GlobalGen = nullptr;
+  cmLocalGenerator* LocalGen = nullptr;
+  cmMakefile* Makefile = nullptr;
 
   // Configuration
   IntegerVersion QtVersion;

+ 15 - 16
Source/cmQtAutoGenerator.cxx

@@ -93,32 +93,18 @@ void cmQtAutoGenerator::Logger::Warning(GenT genType,
   }
 }
 
-void cmQtAutoGenerator::Logger::WarningFile(GenT genType,
-                                            cm::string_view filename,
-                                            cm::string_view message) const
-{
-  Warning(genType, cmStrCat("  ", Quoted(filename), '\n', message));
-}
-
 void cmQtAutoGenerator::Logger::Error(GenT genType,
                                       cm::string_view message) const
 {
   std::string msg =
-    cmStrCat(HeadLine(cmStrCat(GeneratorName(genType), " error")), message,
-             cmHasSuffix(message, '\n') ? "\n" : "\n\n");
+    cmStrCat('\n', HeadLine(cmStrCat(GeneratorName(genType), " error")),
+             message, cmHasSuffix(message, '\n') ? "\n" : "\n\n");
   {
     std::lock_guard<std::mutex> lock(Mutex_);
     cmSystemTools::Stderr(msg);
   }
 }
 
-void cmQtAutoGenerator::Logger::ErrorFile(GenT genType,
-                                          cm::string_view filename,
-                                          cm::string_view message) const
-{
-  Error(genType, cmStrCat("  ", Quoted(filename), '\n', message));
-}
-
 void cmQtAutoGenerator::Logger::ErrorCommand(
   GenT genType, cm::string_view message,
   std::vector<std::string> const& command, std::string const& output) const
@@ -286,3 +272,16 @@ std::string cmQtAutoGenerator::SettingsFind(std::string const& content,
   }
   return std::string();
 }
+
+std::string cmQtAutoGenerator::MessagePath(cm::string_view path) const
+{
+  std::string res;
+  if (cmHasPrefix(path, ProjectDirs().Source)) {
+    res = cmStrCat("SRC:", path.substr(ProjectDirs().Source.size()));
+  } else if (cmHasPrefix(path, ProjectDirs().Binary)) {
+    res = cmStrCat("BIN:", path.substr(ProjectDirs().Binary.size()));
+  } else {
+    res = std::string(path);
+  }
+  return cmQtAutoGen::Quoted(res);
+}

+ 17 - 7
Source/cmQtAutoGenerator.h

@@ -23,9 +23,7 @@ class cmQtAutoGenerator : public cmQtAutoGen
 public:
   // -- Types
 
-  /**
-   * Thread safe logger
-   */
+  /** Thread safe logger.  */
   class Logger
   {
   public:
@@ -45,12 +43,8 @@ public:
     void Info(GenT genType, cm::string_view message) const;
     // -- Log warning
     void Warning(GenT genType, cm::string_view message) const;
-    void WarningFile(GenT genType, cm::string_view filename,
-                     cm::string_view message) const;
     // -- Log error
     void Error(GenT genType, cm::string_view message) const;
-    void ErrorFile(GenT genType, cm::string_view filename,
-                   cm::string_view message) const;
     void ErrorCommand(GenT genType, cm::string_view message,
                       std::vector<std::string> const& command,
                       std::string const& output) const;
@@ -64,6 +58,15 @@ public:
     bool ColorOutput_ = false;
   };
 
+  /** Project directories.  */
+  struct ProjectDirsT
+  {
+    std::string Source;
+    std::string Binary;
+    std::string CurrentSource;
+    std::string CurrentBinary;
+  };
+
   // -- File system methods
   static bool MakeParentDirectory(std::string const& filename);
   static bool FileRead(std::string& content, std::string const& filename,
@@ -91,13 +94,18 @@ public:
   std::string const& InfoDir() const { return InfoDir_; }
   std::string const& InfoConfig() const { return InfoConfig_; }
 
+  // -- Directories
+  ProjectDirsT const& ProjectDirs() const { return ProjectDirs_; }
+
   // -- Utility
   static std::string SettingsFind(std::string const& content, const char* key);
+  std::string MessagePath(cm::string_view path) const;
 
 protected:
   // -- Abstract processing interface
   virtual bool Init(cmMakefile* makefile) = 0;
   virtual bool Process() = 0;
+  ProjectDirsT& ProjectDirsRef() { return ProjectDirs_; }
 
 private:
   // -- Info settings
@@ -105,6 +113,8 @@ private:
   cmFileTime InfoFileTime_;
   std::string InfoDir_;
   std::string InfoConfig_;
+  // -- Directories
+  ProjectDirsT ProjectDirs_;
 };
 
 #endif

File diff suppressed because it is too large
+ 328 - 316
Source/cmQtAutoMocUic.cxx


+ 109 - 122
Source/cmQtAutoMocUic.h

@@ -16,6 +16,7 @@
 #include <cstddef>
 #include <map>
 #include <memory>
+#include <mutex>
 #include <set>
 #include <string>
 #include <unordered_map>
@@ -40,9 +41,7 @@ public:
 public:
   // -- Types
 
-  /**
-   * Search key plus regular expression pair
-   */
+  /** Search key plus regular expression pair.  */
   struct KeyExpT
   {
     KeyExpT() = default;
@@ -63,9 +62,7 @@ public:
     cmsys::RegularExpression Exp;
   };
 
-  /**
-   * Include string with sub parts
-   */
+  /** Include string with sub parts.  */
   struct IncludeKeyT
   {
     IncludeKeyT(std::string const& key, std::size_t basePrefixLength);
@@ -75,9 +72,7 @@ public:
     std::string Base; // Base part of the include file name
   };
 
-  /**
-   * Source file parsing cache
-   */
+  /** Source file parsing cache.  */
   class ParseCacheT
   {
   public:
@@ -127,9 +122,7 @@ public:
     std::unordered_map<std::string, FileHandleT> Map_;
   };
 
-  /**
-   * Source file data
-   */
+  /** Source file data.  */
   class SourceFileT
   {
   public:
@@ -143,15 +136,14 @@ public:
     cmFileTime FileTime;
     ParseCacheT::FileHandleT ParseData;
     std::string BuildPath;
+    bool IsHeader = false;
     bool Moc = false;
     bool Uic = false;
   };
   using SourceFileHandleT = std::shared_ptr<SourceFileT>;
   using SourceFileMapT = std::map<std::string, SourceFileHandleT>;
 
-  /**
-   * Meta compiler file mapping information
-   */
+  /** Meta compiler file mapping information.  */
   struct MappingT
   {
     SourceFileHandleT SourceFile;
@@ -162,9 +154,7 @@ public:
   using MappingHandleT = std::shared_ptr<MappingT>;
   using MappingMapT = std::map<std::string, MappingHandleT>;
 
-  /**
-   * Common settings
-   */
+  /** Common settings.  */
   class BaseSettingsT
   {
   public:
@@ -178,13 +168,8 @@ public:
     // -- Attributes
     // - Config
     bool MultiConfig = false;
-    bool IncludeProjectDirsBefore = false;
     unsigned int QtVersionMajor = 4;
     // - Directories
-    std::string ProjectSourceDir;
-    std::string ProjectBinaryDir;
-    std::string CurrentSourceDir;
-    std::string CurrentBinaryDir;
     std::string AutogenBuildDir;
     std::string AutogenIncludeDir;
     // - Files
@@ -194,9 +179,7 @@ public:
     std::vector<std::string> HeaderExtensions;
   };
 
-  /**
-   * Shared common variables
-   */
+  /** Shared common variables.  */
   class BaseEvalT
   {
   public:
@@ -210,9 +193,7 @@ public:
     SourceFileMapT Sources;
   };
 
-  /**
-   * Moc settings
-   */
+  /** Moc settings.  */
   class MocSettingsT
   {
   public:
@@ -231,26 +212,24 @@ public:
     bool Enabled = false;
     bool SettingsChanged = false;
     bool RelaxedMode = false;
+    bool PathPrefix = false;
     cmFileTime ExecutableTime;
     std::string Executable;
     std::string CompFileAbs;
-    std::string PredefsFileRel;
     std::string PredefsFileAbs;
     std::unordered_set<std::string> SkipList;
     std::vector<std::string> IncludePaths;
-    std::vector<std::string> Includes;
     std::vector<std::string> Definitions;
-    std::vector<std::string> Options;
-    std::vector<std::string> AllOptions;
+    std::vector<std::string> OptionsIncludes;
+    std::vector<std::string> OptionsDefinitions;
+    std::vector<std::string> OptionsExtra;
     std::vector<std::string> PredefsCmd;
     std::vector<KeyExpT> DependFilters;
     std::vector<KeyExpT> MacroFilters;
     cmsys::RegularExpression RegExpInclude;
   };
 
-  /**
-   * Moc shared variables
-   */
+  /** Moc shared variables.  */
   class MocEvalT
   {
   public:
@@ -262,14 +241,14 @@ public:
     MappingMapT Includes;
     // -- Discovered files
     SourceFileMapT HeadersDiscovered;
+    // -- Output directories
+    std::unordered_set<std::string> OutputDirs;
     // -- Mocs compilation
     bool CompUpdated = false;
     std::vector<std::string> CompFiles;
   };
 
-  /**
-   * Uic settings
-   */
+  /** Uic settings.  */
   class UicSettingsT
   {
   public:
@@ -294,25 +273,23 @@ public:
     cmsys::RegularExpression RegExpInclude;
   };
 
-  /**
-   * Uic shared variables
-   */
+  /** Uic shared variables.  */
   class UicEvalT
   {
   public:
+    // -- Discovered files
     SourceFileMapT UiFiles;
+    // -- Mappings
     MappingMapT Includes;
+    // -- Output directories
+    std::unordered_set<std::string> OutputDirs;
   };
 
-  /**
-   * Abstract job class for concurrent job processing
-   */
+  /** Abstract job class for concurrent job processing.  */
   class JobT : public cmWorkerPool::JobT
   {
   protected:
-    /**
-     * @brief Protected default constructor
-     */
+    /** Protected default constructor.  */
     JobT(bool fence = false)
       : cmWorkerPool::JobT(fence)
     {
@@ -333,25 +310,24 @@ public:
     UicSettingsT const& UicConst() const { return Gen()->UicConst(); }
     UicEvalT& UicEval() const { return Gen()->UicEval(); }
 
-    // -- Error logging with automatic abort
+    // -- Logging
+    std::string MessagePath(cm::string_view path) const
+    {
+      return Gen()->MessagePath(path);
+    }
+    // - Error logging with automatic abort
     void LogError(GenT genType, cm::string_view message) const;
-    void LogFileError(GenT genType, cm::string_view filename,
-                      cm::string_view message) const;
     void LogCommandError(GenT genType, cm::string_view message,
                          std::vector<std::string> const& command,
                          std::string const& output) const;
 
-    /**
-     * @brief Run an external process. Use only during Process() call!
-     */
+    /** @brief Run an external process. Use only during Process() call!  */
     bool RunProcess(GenT genType, cmWorkerPool::ProcessResultT& result,
                     std::vector<std::string> const& command,
                     std::string* infoMessage = nullptr);
   };
 
-  /**
-   * Fence job utility class
-   */
+  /** Fence job utility class.  */
   class JobFenceT : public JobT
   {
   public:
@@ -362,18 +338,14 @@ public:
     void Process() override{};
   };
 
-  /**
-   * Generate moc_predefs.h
-   */
+  /** Generate moc_predefs.h.  */
   class JobMocPredefsT : public JobFenceT
   {
     void Process() override;
     bool Update(std::string* reason) const;
   };
 
-  /**
-   * File parse job base class
-   */
+  /** File parse job base class.  */
   class JobParseT : public JobT
   {
   public:
@@ -397,9 +369,7 @@ public:
     std::string Content;
   };
 
-  /**
-   * Header file parse job
-   */
+  /** Header file parse job.  */
   class JobParseHeaderT : public JobParseT
   {
   public:
@@ -407,9 +377,7 @@ public:
     void Process() override;
   };
 
-  /**
-   * Source file parse job
-   */
+  /** Source file parse job.  */
   class JobParseSourceT : public JobParseT
   {
   public:
@@ -417,57 +385,79 @@ public:
     void Process() override;
   };
 
-  /**
-   * Evaluate parsed files
-   */
-  class JobEvaluateT : public JobFenceT
+  /** Evaluate cached file parse data - moc.  */
+  class JobEvalCacheT : public JobT
+  {
+  protected:
+    std::string MessageSearchLocations() const;
+    std::vector<std::string> SearchLocations;
+  };
+
+  /** Evaluate cached file parse data - moc.  */
+  class JobEvalCacheMocT : public JobEvalCacheT
+  {
+    void Process() override;
+    bool EvalHeader(SourceFileHandleT source);
+    bool EvalSource(SourceFileHandleT const& source);
+    bool FindIncludedHeader(SourceFileHandleT& headerHandle,
+                            cm::string_view includerDir,
+                            cm::string_view includeBase);
+    bool RegisterIncluded(std::string const& includeString,
+                          SourceFileHandleT includerFileHandle,
+                          SourceFileHandleT sourceFileHandle) const;
+    void RegisterMapping(MappingHandleT mappingHandle) const;
+    std::string MessageHeader(cm::string_view headerBase) const;
+  };
+
+  /** Evaluate cached file parse data - uic.  */
+  class JobEvalCacheUicT : public JobEvalCacheT
+  {
+    void Process() override;
+    bool EvalFile(SourceFileHandleT const& sourceFileHandle);
+    bool FindIncludedUi(cm::string_view sourceDirPrefix,
+                        cm::string_view includePrefix);
+    bool RegisterMapping(std::string const& includeString,
+                         SourceFileHandleT includerFileHandle);
+
+    std::string UiName;
+    SourceFileHandleT UiFileHandle;
+  };
+
+  /** Evaluate cached file parse data - finish  */
+  class JobEvalCacheFinishT : public JobFenceT
   {
     void Process() override;
+  };
 
-    // -- Moc
-    bool MocEvalHeader(SourceFileHandleT source);
-    bool MocEvalSource(SourceFileHandleT const& source);
-    SourceFileHandleT MocFindIncludedHeader(
-      std::string const& includerDir, std::string const& includeBase) const;
-    SourceFileHandleT MocFindHeader(std::string const& basePath) const;
-    std::string MocMessageTestHeaders(cm::string_view fileBase) const;
-    bool MocRegisterIncluded(std::string const& includeString,
-                             SourceFileHandleT includerFileHandle,
-                             SourceFileHandleT sourceFileHandle,
-                             bool sourceIsHeader) const;
-    void MocRegisterMapping(MappingHandleT mappingHandle,
-                            bool sourceIsHeader) const;
-
-    // -- Uic
-    bool UicEval(SourceFileMapT const& fileMap);
-    bool UicEvalFile(SourceFileHandleT const& sourceFileHandle);
-    SourceFileHandleT UicFindIncludedUi(std::string const& sourceFile,
-                                        std::string const& sourceDir,
-                                        IncludeKeyT const& incKey) const;
-    bool UicRegisterMapping(std::string const& includeString,
-                            SourceFileHandleT uiFileHandle,
-                            SourceFileHandleT includerFileHandle);
+  /** Dependency probing base job.  */
+  class JobProbeDepsT : public JobT
+  {
   };
 
-  /**
-   * Generates moc/uic jobs
-   */
-  class JobGenerateT : public JobFenceT
+  /** Probes file dependencies and generates moc compile jobs.  */
+  class JobProbeDepsMocT : public JobProbeDepsT
   {
     void Process() override;
-    // -- Moc
-    bool MocGenerate(MappingHandleT const& mapping, bool compFile) const;
-    bool MocUpdate(MappingT const& mapping, std::string* reason) const;
-    std::pair<std::string, cmFileTime> MocFindDependency(
+    bool Generate(MappingHandleT const& mapping, bool compFile) const;
+    bool Probe(MappingT const& mapping, std::string* reason) const;
+    std::pair<std::string, cmFileTime> FindDependency(
       std::string const& sourceDir, std::string const& includeString) const;
-    // -- Uic
-    bool UicGenerate(MappingHandleT const& mapping) const;
-    bool UicUpdate(MappingT const& mapping, std::string* reason) const;
   };
 
-  /**
-   * File compiling base job
-   */
+  /** Probes file dependencies and generates uic compile jobs.  */
+  class JobProbeDepsUicT : public JobProbeDepsT
+  {
+    void Process() override;
+    bool Probe(MappingT const& mapping, std::string* reason) const;
+  };
+
+  /** Dependency probing finish job.  */
+  class JobProbeDepsFinishT : public JobFenceT
+  {
+    void Process() override;
+  };
+
+  /** Meta compiler base job.  */
   class JobCompileT : public JobT
   {
   public:
@@ -482,36 +472,30 @@ public:
     std::unique_ptr<std::string> Reason;
   };
 
-  /**
-   * moc compiles a file
-   */
-  class JobMocT : public JobCompileT
+  /** moc compiles a file.  */
+  class JobCompileMocT : public JobCompileT
   {
   public:
     using JobCompileT::JobCompileT;
     void Process() override;
   };
 
-  /**
-   * uic compiles a file
-   */
-  class JobUicT : public JobCompileT
+  /** uic compiles a file.  */
+  class JobCompileUicT : public JobCompileT
   {
   public:
     using JobCompileT::JobCompileT;
     void Process() override;
   };
 
-  /// @brief Generate mocs_compilation.cpp
-  ///
+  /** Generate mocs_compilation.cpp.  */
   class JobMocsCompilationT : public JobFenceT
   {
   private:
     void Process() override;
   };
 
-  /// @brief The last job
-  ///
+  /** @brief The last job.  */
   class JobFinishT : public JobFenceT
   {
   private:
@@ -536,6 +520,7 @@ public:
   std::string AbsoluteIncludePath(cm::string_view relativePath) const;
   template <class JOBTYPE>
   void CreateParseJobs(SourceFileMapT const& sourceMap);
+  std::string CollapseFullPathTS(std::string const& path) const;
 
 private:
   // -- Utility accessors
@@ -572,6 +557,8 @@ private:
   // -- Worker thread pool
   std::atomic<bool> JobError_ = ATOMIC_VAR_INIT(false);
   cmWorkerPool WorkerPool_;
+  // -- Concurrent processing
+  mutable std::mutex CMakeLibMutex_;
 };
 
 #endif

+ 71 - 47
Source/cmQtAutoRcc.cxx

@@ -16,7 +16,6 @@
 #include <algorithm>
 
 cmQtAutoRcc::cmQtAutoRcc() = default;
-
 cmQtAutoRcc::~cmQtAutoRcc() = default;
 
 bool cmQtAutoRcc::Init(cmMakefile* makefile)
@@ -41,8 +40,8 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile)
     return cmExpandedList(InfoGetConfig(key));
   };
   auto LogInfoError = [this](cm::string_view msg) -> bool {
-    this->Log().Error(GenT::RCC,
-                      cmStrCat("In ", Quoted(this->InfoFile()), ":\n", msg));
+    this->Log().Error(
+      GenT::RCC, cmStrCat("In ", MessagePath(this->InfoFile()), ":\n", msg));
     return false;
   };
 
@@ -56,6 +55,8 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile)
   MultiConfig_ = makefile->IsOn("ARCC_MULTI_CONFIG");
 
   // - Directories
+  ProjectDirsRef().Source = InfoGet("ARCC_CMAKE_SOURCE_DIR");
+  ProjectDirsRef().Binary = InfoGet("ARCC_CMAKE_BINARY_DIR");
   AutogenBuildDir_ = InfoGet("ARCC_BUILD_DIR");
   if (AutogenBuildDir_.empty()) {
     return LogInfoError("Build directory empty.");
@@ -69,8 +70,8 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile)
   // - Rcc executable
   RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE");
   if (!RccExecutableTime_.Load(RccExecutable_)) {
-    return LogInfoError(cmStrCat("The rcc executable ", Quoted(RccExecutable_),
-                                 " does not exist."));
+    return LogInfoError(cmStrCat(
+      "The rcc executable ", MessagePath(RccExecutable_), " does not exist."));
   }
   RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS");
 
@@ -185,8 +186,9 @@ bool cmQtAutoRcc::SettingsFileRead()
   if (!cmSystemTools::FileExists(SettingsFile_, true)) {
     // Touch the settings file to make sure it exists
     if (!cmSystemTools::Touch(SettingsFile_, true)) {
-      Log().ErrorFile(GenT::RCC, SettingsFile_,
-                      "Settings file creation failed.");
+      Log().Error(GenT::RCC,
+                  cmStrCat("Touching the settings file ",
+                           MessagePath(SettingsFile_), " failed."));
       return false;
     }
   }
@@ -196,7 +198,9 @@ bool cmQtAutoRcc::SettingsFileRead()
     // Make sure the lock file exists
     if (!cmSystemTools::FileExists(LockFile_, true)) {
       if (!cmSystemTools::Touch(LockFile_, true)) {
-        Log().ErrorFile(GenT::RCC, LockFile_, "Lock file creation failed.");
+        Log().Error(GenT::RCC,
+                    cmStrCat("Touching the lock file ", MessagePath(LockFile_),
+                             " failed."));
         return false;
       }
     }
@@ -204,8 +208,9 @@ bool cmQtAutoRcc::SettingsFileRead()
     cmFileLockResult lockResult =
       LockFileLock_.Lock(LockFile_, static_cast<unsigned long>(-1));
     if (!lockResult.IsOk()) {
-      Log().ErrorFile(GenT::RCC, LockFile_,
-                      "File lock failed: " + lockResult.GetOutputMessage());
+      Log().Error(GenT::RCC,
+                  cmStrCat("Locking of the lock file ", MessagePath(LockFile_),
+                           " failed.\n", lockResult.GetOutputMessage()));
       return false;
     }
   }
@@ -221,8 +226,10 @@ bool cmQtAutoRcc::SettingsFileRead()
       if (SettingsChanged_) {
         std::string error;
         if (!FileWrite(SettingsFile_, "", &error)) {
-          Log().ErrorFile(GenT::RCC, SettingsFile_,
-                          "Settings file clearing failed. " + error);
+          Log().Error(GenT::RCC,
+                      cmStrCat("Clearing of the settings file ",
+                               MessagePath(SettingsFile_), " failed.\n",
+                               error));
           return false;
         }
       }
@@ -239,14 +246,16 @@ bool cmQtAutoRcc::SettingsFileWrite()
   // Only write if any setting changed
   if (SettingsChanged_) {
     if (Log().Verbose()) {
-      Log().Info(GenT::RCC, "Writing settings file " + Quoted(SettingsFile_));
+      Log().Info(GenT::RCC,
+                 "Writing settings file " + MessagePath(SettingsFile_));
     }
     // Write settings file
     std::string content = cmStrCat("rcc:", SettingsString_, '\n');
     std::string error;
     if (!FileWrite(SettingsFile_, content, &error)) {
-      Log().ErrorFile(GenT::RCC, SettingsFile_,
-                      "Settings file writing failed. " + error);
+      Log().Error(GenT::RCC,
+                  cmStrCat("Writing of the settings file ",
+                           MessagePath(SettingsFile_), " failed.\n", error));
       // Remove old settings file to trigger a full rebuild on the next run
       cmSystemTools::RemoveFile(SettingsFile_);
       return false;
@@ -263,17 +272,18 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
 {
   // Test if the rcc input file exists
   if (!QrcFileTime_.Load(QrcFile_)) {
-    Log().ErrorFile(
-      GenT::RCC, QrcFile_,
-      cmStrCat("The resources file ", Quoted(QrcFile_), " does not exist"));
+    Log().Error(GenT::RCC,
+                cmStrCat("The resources file ", MessagePath(QrcFile_),
+                         " does not exist"));
     return false;
   }
 
   // Test if the rcc output file exists
   if (!RccFileTime_.Load(RccFileOutput_)) {
     if (Log().Verbose()) {
-      Reason = cmStrCat("Generating ", Quoted(RccFileOutput_),
-                        ", because it doesn't exist, from ", Quoted(QrcFile_));
+      Reason =
+        cmStrCat("Generating ", MessagePath(RccFileOutput_),
+                 ", because it doesn't exist, from ", MessagePath(QrcFile_));
     }
     generate = true;
     return true;
@@ -282,9 +292,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
   // Test if the settings changed
   if (SettingsChanged_) {
     if (Log().Verbose()) {
-      Reason = cmStrCat("Generating ", Quoted(RccFileOutput_),
+      Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_),
                         ", because the rcc settings changed, from ",
-                        Quoted(QrcFile_));
+                        MessagePath(QrcFile_));
     }
     generate = true;
     return true;
@@ -293,9 +303,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
   // Test if the rcc output file is older than the .qrc file
   if (RccFileTime_.Older(QrcFileTime_)) {
     if (Log().Verbose()) {
-      Reason = cmStrCat("Generating ", Quoted(RccFileOutput_),
-                        ", because it is older than ", Quoted(QrcFile_),
-                        ", from ", Quoted(QrcFile_));
+      Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_),
+                        ", because it is older than ", MessagePath(QrcFile_),
+                        ", from ", MessagePath(QrcFile_));
     }
     generate = true;
     return true;
@@ -304,9 +314,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate)
   // Test if the rcc output file is older than the rcc executable
   if (RccFileTime_.Older(RccExecutableTime_)) {
     if (Log().Verbose()) {
-      Reason = cmStrCat("Generating ", Quoted(RccFileOutput_),
+      Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_),
                         ", because it is older than the rcc executable, from ",
-                        Quoted(QrcFile_));
+                        MessagePath(QrcFile_));
     }
     generate = true;
     return true;
@@ -322,7 +332,9 @@ bool cmQtAutoRcc::TestResources(bool& generate)
     std::string error;
     RccLister const lister(RccExecutable_, RccListOptions_);
     if (!lister.list(QrcFile_, Inputs_, error, Log().Verbose())) {
-      Log().ErrorFile(GenT::RCC, QrcFile_, error);
+      Log().Error(
+        GenT::RCC,
+        cmStrCat("Listing of ", MessagePath(QrcFile_), " failed.\n", error));
       return false;
     }
   }
@@ -332,17 +344,18 @@ bool cmQtAutoRcc::TestResources(bool& generate)
     // Check if the resource file exists
     cmFileTime fileTime;
     if (!fileTime.Load(resFile)) {
-      Log().ErrorFile(GenT::RCC, QrcFile_,
-                      cmStrCat("Could not find the resource file\n  ",
-                               Quoted(resFile), '\n'));
+      Log().Error(GenT::RCC,
+                  cmStrCat("The resource file ", MessagePath(resFile),
+                           " listed in ", MessagePath(QrcFile_),
+                           " does not exist."));
       return false;
     }
     // Check if the resource file is newer than the rcc output file
     if (RccFileTime_.Older(fileTime)) {
       if (Log().Verbose()) {
-        Reason = cmStrCat("Generating ", Quoted(RccFileOutput_),
-                          ", because it is older than ", Quoted(resFile),
-                          ", from ", Quoted(QrcFile_));
+        Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_),
+                          ", because it is older than ", MessagePath(resFile),
+                          ", from ", MessagePath(QrcFile_));
       }
       generate = true;
       break;
@@ -357,12 +370,15 @@ bool cmQtAutoRcc::TestInfoFile()
   if (RccFileTime_.Older(InfoFileTime())) {
     if (Log().Verbose()) {
       Log().Info(GenT::RCC,
-                 cmStrCat("Touching ", Quoted(RccFileOutput_),
-                          " because it is older than ", Quoted(InfoFile())));
+                 cmStrCat("Touching ", MessagePath(RccFileOutput_),
+                          " because it is older than ",
+                          MessagePath(InfoFile())));
     }
     // Touch build file
     if (!cmSystemTools::Touch(RccFileOutput_, false)) {
-      Log().ErrorFile(GenT::RCC, RccFileOutput_, "Build file touch failed");
+      Log().Error(
+        GenT::RCC,
+        cmStrCat("Touching ", MessagePath(RccFileOutput_), " failed."));
       return false;
     }
     BuildFileChanged_ = true;
@@ -375,8 +391,9 @@ bool cmQtAutoRcc::GenerateRcc()
 {
   // Make parent directory
   if (!MakeParentDirectory(RccFileOutput_)) {
-    Log().ErrorFile(GenT::RCC, RccFileOutput_,
-                    "Could not create parent directory");
+    Log().Error(GenT::RCC,
+                cmStrCat("Could not create parent directory of ",
+                         MessagePath(RccFileOutput_)));
     return false;
   }
 
@@ -405,8 +422,8 @@ bool cmQtAutoRcc::GenerateRcc()
     // rcc process failed
     Log().ErrorCommand(GenT::RCC,
                        cmStrCat("The rcc process failed to compile\n  ",
-                                Quoted(QrcFile_), "\ninto\n  ",
-                                Quoted(RccFileOutput_)),
+                                MessagePath(QrcFile_), "\ninto\n  ",
+                                MessagePath(RccFileOutput_)),
                        cmd, rccStdOut + rccStdErr);
     cmSystemTools::RemoveFile(RccFileOutput_);
     return false;
@@ -443,22 +460,29 @@ bool cmQtAutoRcc::GenerateWrapper()
     if (fileDiffers) {
       // Write new wrapper file
       if (Log().Verbose()) {
-        Log().Info(GenT::RCC, "Generating RCC wrapper file " + RccFilePublic_);
+        Log().Info(GenT::RCC,
+                   cmStrCat("Generating RCC wrapper file ",
+                            MessagePath(RccFilePublic_)));
       }
       std::string error;
       if (!FileWrite(RccFilePublic_, content, &error)) {
-        Log().ErrorFile(GenT::RCC, RccFilePublic_,
-                        "RCC wrapper file writing failed. " + error);
+        Log().Error(GenT::RCC,
+                    cmStrCat("Generating RCC wrapper file ",
+                             MessagePath(RccFilePublic_), " failed.\n",
+                             error));
         return false;
       }
     } else if (BuildFileChanged_) {
       // Just touch the wrapper file
       if (Log().Verbose()) {
-        Log().Info(GenT::RCC, "Touching RCC wrapper file " + RccFilePublic_);
+        Log().Info(
+          GenT::RCC,
+          cmStrCat("Touching RCC wrapper file ", MessagePath(RccFilePublic_)));
       }
       if (!cmSystemTools::Touch(RccFilePublic_, false)) {
-        Log().ErrorFile(GenT::RCC, RccFilePublic_,
-                        "RCC wrapper file touch failed.");
+        Log().Error(GenT::RCC,
+                    cmStrCat("Touching RCC wrapper file ",
+                             MessagePath(RccFilePublic_), " failed."));
         return false;
       }
     }

+ 1 - 0
Source/cmTarget.cxx

@@ -312,6 +312,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
     initProp("AUTOMOC_MACRO_NAMES");
     initProp("AUTOMOC_MOC_OPTIONS");
     initProp("AUTOUIC_OPTIONS");
+    initProp("AUTOMOC_PATH_PREFIX");
     initProp("AUTOUIC_SEARCH_PATHS");
     initProp("AUTORCC_OPTIONS");
     initProp("LINK_DEPENDS_NO_SHARED");

+ 112 - 0
Tests/QtAutogen/MocInclude/CMakeLists.txt

@@ -0,0 +1,112 @@
+cmake_minimum_required(VERSION 3.15)
+project(MocInclude)
+get_filename_component(CS_REAL ${CMAKE_CURRENT_SOURCE_DIR} REALPATH)
+include("${CS_REAL}/../AutogenCoreTest.cmake")
+
+# Test moc include patterns
+
+set(COM_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Common")
+
+macro(addCopyCommand from to)
+    add_custom_command(
+      OUTPUT ${to}
+      COMMAND ${CMAKE_COMMAND} -E copy ${from} ${to}
+      DEPENDS ${from})
+endmacro()
+
+# Create an executable
+function(makeExecutable TARGET_NAME)
+    # Utility variables
+    set(CB_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+
+    # Copy directory
+    file(REMOVE_RECURSE "${CB_DIR}/InIncludes")
+    file(COPY "${COM_DIR}/InIncludes.in" DESTINATION "${CB_DIR}")
+    file(RENAME "${CB_DIR}/InIncludes.in" "${CB_DIR}/InIncludes")
+
+    # Generate .moc file from the header externally and
+    # enabled SKIP_AUTOMOC on the source file
+    qtx_wrap_cpp(ExternDotMOC ${COM_DIR}/ExternDot.hpp OPTIONS "-p" "./")
+    addCopyCommand(${ExternDotMOC}
+                   ${CB_DIR}/ExternDot.moc)
+    set_property(
+      SOURCE ${COM_DIR}/ExternDot.cpp
+      PROPERTY SKIP_AUTOMOC ON)
+
+    # Generate .moc file from the GENERATED header externally
+    # and enabled SKIP_AUTOMOC on the source file
+    addCopyCommand(${COM_DIR}/ExternDotGenerated.hpp.in
+                   ${CB_DIR}/ExternDotGenerated.hpp)
+    addCopyCommand(${COM_DIR}/ExternDotGenerated.cpp.in
+                   ${CB_DIR}/ExternDotGenerated.cpp)
+    qtx_wrap_cpp(ExternDotGeneratedMOC
+                 ${CB_DIR}/ExternDotGenerated.hpp
+                 OPTIONS "-p" "./")
+    addCopyCommand(${ExternDotGeneratedMOC}
+                   ${CB_DIR}/ExternDotGenerated.moc)
+    set_property(
+      SOURCE ${CB_DIR}/ExternDotGenerated.cpp
+      PROPERTY SKIP_AUTOMOC ON)
+
+    # Generate header moc file externally with a custom name
+    # and enabled SKIP_AUTOMOC on the header
+    qtx_wrap_cpp(MixedCustomMOC
+                 ${COM_DIR}/MixedCustom.hpp
+                 OPTIONS "-p" "./")
+    addCopyCommand(${MixedCustomMOC}
+                   ${CB_DIR}/MixedCustom_extMoc.cpp)
+    set_property(
+      SOURCE ${COM_DIR}/MixedCustom.hpp
+      PROPERTY SKIP_AUTOMOC ON)
+    # Custom target to depend on
+    add_custom_target("${TARGET_NAME}_MixedCustom"
+      DEPENDS ${CB_DIR}/MixedCustom_extMoc.cpp
+      BYPRODUCTS ${CB_DIR}/moc_MixedCustom.cpp
+      COMMAND ${CMAKE_COMMAND} -E copy
+        ${COM_DIR}/moc_MixedCustom.cpp.in
+        ${CB_DIR}/moc_MixedCustom.cpp)
+
+    add_executable(${TARGET_NAME}
+      # Test own "*.moc" and "moc_*.cpp" includes
+      ${COM_DIR}/None.cpp
+      ${COM_DIR}/OwnDot.cpp
+      ${COM_DIR}/OwnUnderscore.cpp
+      ${COM_DIR}/OwnDotUnderscore.cpp
+
+      # Test "moc_*.cpp" includes of other files
+      ${COM_DIR}/OtherUnderscore.cpp
+      ${COM_DIR}/OtherUnderscoreExtra.cpp
+      ${COM_DIR}/OtherUnderscoreSub.cpp
+      ${COM_DIR}/OtherUnderscoreSubDir/SubExtra.cpp
+
+      # Test relative ../../ path for moc includes
+      ${COM_DIR}/DualSub/Second/Second.cpp
+      ${COM_DIR}/DualSubMocked.cpp
+
+      # Test externally generated moc files
+      ${COM_DIR}/ExternDot.cpp
+      ${CB_DIR}/ExternDot.moc
+
+      # Test externally generated moc files for GENERATED source
+      ${CB_DIR}/ExternDotGenerated.cpp
+      ${CB_DIR}/ExternDotGenerated.moc
+
+      # Test externally generated moc files and SKIP_AUTOMOC enabled header
+      ${COM_DIR}/MixedSkipped.cpp
+      ${COM_DIR}/MixedCustom.hpp
+      ${COM_DIR}/MixedCustom.cpp
+
+      # Test sources in a subdirectory
+      ${CB_DIR}/InIncludes/SubOwnDot.cpp
+      ${COM_DIR}/InIncludesMoc.cpp
+    )
+    add_dependencies(${TARGET_NAME} "${TARGET_NAME}_MixedCustom")
+    target_include_directories(${TARGET_NAME} PRIVATE "${COM_DIR}")
+    target_include_directories(${TARGET_NAME} PRIVATE "${CB_DIR}")
+    target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
+    target_link_libraries(${TARGET_NAME} ${QT_LIBRARIES})
+    set_target_properties(${TARGET_NAME} PROPERTIES AUTOMOC ON)
+endfunction()
+
+add_subdirectory(Strict)
+add_subdirectory(Relaxed)

+ 11 - 0
Tests/QtAutogen/MocInclude/Common/DualSub/Second/Second.cpp

@@ -0,0 +1,11 @@
+#include "Second.hpp"
+
+Second::Second()
+{
+}
+
+Second::~Second()
+{
+}
+
+#include "../../moc_DualSubMocked.cpp"

+ 14 - 0
Tests/QtAutogen/MocInclude/Common/DualSub/Second/Second.hpp

@@ -0,0 +1,14 @@
+#ifndef Second_HPP
+#define Second_HPP
+
+#include <QObject>
+
+class Second : public QObject
+{
+  Q_OBJECT
+public:
+  Second();
+  ~Second();
+};
+
+#endif

+ 9 - 0
Tests/QtAutogen/MocInclude/Common/DualSubMocked.cpp

@@ -0,0 +1,9 @@
+#include "DualSubMocked.hpp"
+
+DualSubMocked::DualSubMocked()
+{
+}
+
+DualSubMocked::~DualSubMocked()
+{
+}

+ 15 - 0
Tests/QtAutogen/MocInclude/Common/DualSubMocked.hpp

@@ -0,0 +1,15 @@
+#ifndef DualSubMocked_HPP
+#define DualSubMocked_HPP
+
+#include <QObject>
+
+// Header moc file is included by DualSub/Second/Second.cpp
+class DualSubMocked : public QObject
+{
+  Q_OBJECT
+public:
+  DualSubMocked();
+  ~DualSubMocked();
+};
+
+#endif

+ 11 - 0
Tests/QtAutogen/MocInclude/Common/ExternDot.cpp

@@ -0,0 +1,11 @@
+#include "ExternDot.hpp"
+
+ExternDot::ExternDot()
+{
+}
+
+ExternDot::~ExternDot()
+{
+}
+
+#include "ExternDot.moc"

+ 5 - 5
Tests/QtAutogen/MocInclude/SObjA.hpp → Tests/QtAutogen/MocInclude/Common/ExternDot.hpp

@@ -1,15 +1,15 @@
-#ifndef SOBJA_HPP
-#define SOBJA_HPP
+#ifndef ExternDot_HPP
+#define ExternDot_HPP
 
 #include <QObject>
 
 // Object source includes externally generated .moc file
-class SObjA : public QObject
+class ExternDot : public QObject
 {
   Q_OBJECT
 public:
-  SObjA();
-  ~SObjA();
+  ExternDot();
+  ~ExternDot();
 };
 
 #endif

+ 11 - 0
Tests/QtAutogen/MocInclude/Common/ExternDotGenerated.cpp.in

@@ -0,0 +1,11 @@
+#include "ExternDotGenerated.hpp"
+
+ExternDotGenerated::ExternDotGenerated()
+{
+}
+
+ExternDotGenerated::~ExternDotGenerated()
+{
+}
+
+#include "ExternDotGenerated.moc"

+ 15 - 0
Tests/QtAutogen/MocInclude/Common/ExternDotGenerated.hpp.in

@@ -0,0 +1,15 @@
+#ifndef ExternDotGenerated_HPP
+#define ExternDotGenerated_HPP
+
+#include <QObject>
+
+// GENERATED Object source includes externally generated .moc file
+class ExternDotGenerated : public QObject
+{
+  Q_OBJECT
+public:
+  ExternDotGenerated();
+  ~ExternDotGenerated();
+};
+
+#endif

+ 43 - 0
Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot.cpp

@@ -0,0 +1,43 @@
+#include "SubOwnDot.hpp"
+#include "SubOwnDot_p.hpp"
+
+namespace InIncludes {
+
+class SubOwnDotLocal : public QObject
+{
+  Q_OBJECT
+public:
+  SubOwnDotLocal();
+  ~SubOwnDotLocal();
+};
+
+SubOwnDotLocal::SubOwnDotLocal()
+{
+}
+
+SubOwnDotLocal::~SubOwnDotLocal()
+{
+}
+
+SubOwnDotPrivate::SubOwnDotPrivate()
+{
+}
+
+SubOwnDotPrivate::~SubOwnDotPrivate()
+{
+}
+
+SubOwnDot::SubOwnDot()
+{
+  SubOwnDotPrivate privateObj;
+  SubOwnDotLocal localObj;
+}
+
+SubOwnDot::~SubOwnDot()
+{
+}
+
+} // End of namespace
+
+// For the local QObject
+#include "SubOwnDot.moc"

+ 17 - 0
Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot.hpp

@@ -0,0 +1,17 @@
+#ifndef InIncludes_SubOwnDot_HPP
+#define InIncludes_SubOwnDot_HPP
+
+#include <QObject>
+
+namespace InIncludes {
+
+class SubOwnDot : public QObject
+{
+  Q_OBJECT
+public:
+  SubOwnDot();
+  ~SubOwnDot();
+};
+}
+
+#endif

+ 18 - 0
Tests/QtAutogen/MocInclude/Common/InIncludes.in/SubOwnDot_p.hpp

@@ -0,0 +1,18 @@
+#ifndef InIncludes_SubOwnDot_P_HPP
+#define InIncludes_SubOwnDot_P_HPP
+
+#include <QObject>
+
+namespace InIncludes {
+
+class SubOwnDotPrivate : public QObject
+{
+  Q_OBJECT
+public:
+  SubOwnDotPrivate();
+  ~SubOwnDotPrivate();
+};
+
+} // End of namespace
+
+#endif

+ 4 - 0
Tests/QtAutogen/MocInclude/Common/InIncludesMoc.cpp

@@ -0,0 +1,4 @@
+
+// Moc a header that is not in the sources but in a directory that
+// is in the list of include directories.
+#include "InIncludes/moc_SubOwnDot.cpp"

+ 32 - 0
Tests/QtAutogen/MocInclude/Common/MixedCustom.cpp

@@ -0,0 +1,32 @@
+#include "MixedCustom.hpp"
+
+class MixedCustomLocal : public QObject
+{
+  Q_OBJECT
+
+public:
+  MixedCustomLocal();
+  ~MixedCustomLocal();
+};
+
+MixedCustomLocal::MixedCustomLocal()
+{
+}
+
+MixedCustomLocal::~MixedCustomLocal()
+{
+}
+
+MixedCustom::MixedCustom()
+{
+  MixedCustomLocal local;
+}
+
+MixedCustom::~MixedCustom()
+{
+}
+
+// AUTOMOC generated source moc
+#include "MixedCustom.moc"
+// Externally generated header moc
+#include "MixedCustom_extMoc.cpp"

+ 20 - 0
Tests/QtAutogen/MocInclude/Common/MixedCustom.hpp

@@ -0,0 +1,20 @@
+#ifndef MixedCustom_HPP
+#define MixedCustom_HPP
+
+#include <QObject>
+
+// Object source includes
+// - externally generated header moc file
+// - AUTOMOC generated source .moc file
+class MixedCustom : public QObject
+{
+  Q_OBJECT
+public:
+  MixedCustom();
+  ~MixedCustom();
+};
+
+// Function forward declaration
+void moc_MixedCustom(MixedCustom const& arg);
+
+#endif

+ 39 - 0
Tests/QtAutogen/MocInclude/Common/MixedSkipped.cpp

@@ -0,0 +1,39 @@
+#include "MixedSkipped.hpp"
+#include "MixedCustom.hpp"
+
+class MixedSkippedLocal : public QObject
+{
+  Q_OBJECT
+
+public:
+  MixedSkippedLocal();
+  ~MixedSkippedLocal();
+};
+
+MixedSkippedLocal::MixedSkippedLocal()
+{
+}
+
+MixedSkippedLocal::~MixedSkippedLocal()
+{
+}
+
+MixedSkipped::MixedSkipped()
+{
+  MixedSkippedLocal local;
+  MixedCustom externCutom;
+  // Call moc named function
+  moc_MixedCustom(externCutom);
+}
+
+MixedSkipped::~MixedSkipped()
+{
+}
+
+// Include AUTOMOC generated moc files
+#include "MixedSkipped.moc"
+#include "moc_MixedSkipped.cpp"
+
+// Include externally generated moc_ named file that is not a moc file
+// and for which the relevant header is SKIP_AUTOMOC enabled
+#include "moc_MixedCustom.cpp"

+ 17 - 0
Tests/QtAutogen/MocInclude/Common/MixedSkipped.hpp

@@ -0,0 +1,17 @@
+#ifndef MixedSkipped_HPP
+#define MixedSkipped_HPP
+
+#include <QObject>
+
+// Object source includes
+// - Own moc_ and .moc files.
+// - externally generated moc_ file from a SKIP_AUTOMOC enabled header
+class MixedSkipped : public QObject
+{
+  Q_OBJECT
+public:
+  MixedSkipped();
+  ~MixedSkipped();
+};
+
+#endif

+ 20 - 0
Tests/QtAutogen/MocInclude/Common/None.cpp

@@ -0,0 +1,20 @@
+#include "None.hpp"
+#include "None_p.h"
+
+NonePrivate::NonePrivate()
+{
+}
+
+NonePrivate::~NonePrivate()
+{
+}
+
+None::None()
+  : d(new NonePrivate)
+{
+}
+
+None::~None()
+{
+  delete d;
+}

+ 19 - 0
Tests/QtAutogen/MocInclude/Common/None.hpp

@@ -0,0 +1,19 @@
+#ifndef None_HPP
+#define None_HPP
+
+#include <QObject>
+
+// Object source comes without any _moc/.moc includes
+class NonePrivate;
+class None : public QObject
+{
+  Q_OBJECT
+public:
+  None();
+  ~None();
+
+private:
+  NonePrivate* const d;
+};
+
+#endif

+ 14 - 0
Tests/QtAutogen/MocInclude/Common/None_p.h

@@ -0,0 +1,14 @@
+#ifndef None_P_HPP
+#define None_P_HPP
+
+#include <QObject>
+
+class NonePrivate : public QObject
+{
+  Q_OBJECT
+public:
+  NonePrivate();
+  ~NonePrivate();
+};
+
+#endif

+ 44 - 0
Tests/QtAutogen/MocInclude/Common/OtherUnderscore.cpp

@@ -0,0 +1,44 @@
+#include "OtherUnderscore.hpp"
+#include "OtherUnderscoreExtra.hpp"
+#include "OtherUnderscore_p.hpp"
+
+class OtherUnderscoreLocal : public QObject
+{
+  Q_OBJECT
+public:
+  OtherUnderscoreLocal();
+  ~OtherUnderscoreLocal();
+};
+
+OtherUnderscoreLocal::OtherUnderscoreLocal()
+{
+}
+
+OtherUnderscoreLocal::~OtherUnderscoreLocal()
+{
+}
+
+OtherUnderscorePrivate::OtherUnderscorePrivate()
+{
+  OtherUnderscoreLocal localObj;
+  OtherUnderscoreExtra extraObj;
+}
+
+OtherUnderscorePrivate::~OtherUnderscorePrivate()
+{
+}
+
+OtherUnderscore::OtherUnderscore()
+  : d(new OtherUnderscorePrivate)
+{
+}
+
+OtherUnderscore::~OtherUnderscore()
+{
+  delete d;
+}
+
+// For OtherUnderscoreLocal
+#include "OtherUnderscore.moc"
+// - Not the own header
+#include "moc_OtherUnderscoreExtra.cpp"

+ 19 - 0
Tests/QtAutogen/MocInclude/Common/OtherUnderscore.hpp

@@ -0,0 +1,19 @@
+#ifndef OtherUnderscore_HPP
+#define OtherUnderscore_HPP
+
+#include <QObject>
+
+// Sources includes a moc_ includes of an extra object
+class OtherUnderscorePrivate;
+class OtherUnderscore : public QObject
+{
+  Q_OBJECT
+public:
+  OtherUnderscore();
+  ~OtherUnderscore();
+
+private:
+  OtherUnderscorePrivate* const d;
+};
+
+#endif

+ 20 - 0
Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra.cpp

@@ -0,0 +1,20 @@
+#include "OtherUnderscoreExtra.hpp"
+#include "OtherUnderscoreExtra_p.hpp"
+
+OtherUnderscoreExtraPrivate::OtherUnderscoreExtraPrivate()
+{
+}
+
+OtherUnderscoreExtraPrivate::~OtherUnderscoreExtraPrivate()
+{
+}
+
+OtherUnderscoreExtra::OtherUnderscoreExtra()
+  : d(new OtherUnderscoreExtraPrivate)
+{
+}
+
+OtherUnderscoreExtra::~OtherUnderscoreExtra()
+{
+  delete d;
+}

+ 18 - 0
Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra.hpp

@@ -0,0 +1,18 @@
+#ifndef OtherUnderscoreEXTRA_HPP
+#define OtherUnderscoreEXTRA_HPP
+
+#include <QObject>
+
+class OtherUnderscoreExtraPrivate;
+class OtherUnderscoreExtra : public QObject
+{
+  Q_OBJECT
+public:
+  OtherUnderscoreExtra();
+  ~OtherUnderscoreExtra();
+
+private:
+  OtherUnderscoreExtraPrivate* const d;
+};
+
+#endif

+ 14 - 0
Tests/QtAutogen/MocInclude/Common/OtherUnderscoreExtra_p.hpp

@@ -0,0 +1,14 @@
+#ifndef OtherUnderscoreEXTRA_P_HPP
+#define OtherUnderscoreEXTRA_P_HPP
+
+#include <QObject>
+
+class OtherUnderscoreExtraPrivate : public QObject
+{
+  Q_OBJECT
+public:
+  OtherUnderscoreExtraPrivate();
+  ~OtherUnderscoreExtraPrivate();
+};
+
+#endif

+ 45 - 0
Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub.cpp

@@ -0,0 +1,45 @@
+#include "OtherUnderscoreSub.hpp"
+#include "OtherUnderscoreSubDir/SubExtra.hpp"
+#include "OtherUnderscoreSub_p.hpp"
+
+class OtherUnderscoreSubLocal : public QObject
+{
+  Q_OBJECT
+public:
+  OtherUnderscoreSubLocal();
+  ~OtherUnderscoreSubLocal();
+};
+
+OtherUnderscoreSubLocal::OtherUnderscoreSubLocal()
+{
+}
+
+OtherUnderscoreSubLocal::~OtherUnderscoreSubLocal()
+{
+}
+
+OtherUnderscoreSubPrivate::OtherUnderscoreSubPrivate()
+{
+  OtherUnderscoreSubLocal localObj;
+  SubExtra extraObj;
+}
+
+OtherUnderscoreSubPrivate::~OtherUnderscoreSubPrivate()
+{
+}
+
+OtherUnderscoreSub::OtherUnderscoreSub()
+  : d(new OtherUnderscoreSubPrivate)
+{
+}
+
+OtherUnderscoreSub::~OtherUnderscoreSub()
+{
+  delete d;
+}
+
+// For OtherUnderscoreSubLocal
+#include "OtherUnderscoreSub.moc"
+// - Not the own header
+// - in a subdirectory
+#include "OtherUnderscoreSubDir/moc_SubExtra.cpp"

+ 19 - 0
Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub.hpp

@@ -0,0 +1,19 @@
+#ifndef OtherUnderscoreSub_HPP
+#define OtherUnderscoreSub_HPP
+
+#include <QObject>
+
+// Sources includes a moc_ includes of an extra object in a subdirectory
+class OtherUnderscoreSubPrivate;
+class OtherUnderscoreSub : public QObject
+{
+  Q_OBJECT
+public:
+  OtherUnderscoreSub();
+  ~OtherUnderscoreSub();
+
+private:
+  OtherUnderscoreSubPrivate* const d;
+};
+
+#endif

+ 20 - 0
Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra.cpp

@@ -0,0 +1,20 @@
+#include "SubExtra.hpp"
+#include "SubExtra_p.hpp"
+
+SubExtraPrivate::SubExtraPrivate()
+{
+}
+
+SubExtraPrivate::~SubExtraPrivate()
+{
+}
+
+SubExtra::SubExtra()
+  : d(new SubExtraPrivate)
+{
+}
+
+SubExtra::~SubExtra()
+{
+  delete d;
+}

+ 18 - 0
Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra.hpp

@@ -0,0 +1,18 @@
+#ifndef SubExtra_HPP
+#define SubExtra_HPP
+
+#include <QObject>
+
+class SubExtraPrivate;
+class SubExtra : public QObject
+{
+  Q_OBJECT
+public:
+  SubExtra();
+  ~SubExtra();
+
+private:
+  SubExtraPrivate* const d;
+};
+
+#endif

+ 14 - 0
Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSubDir/SubExtra_p.hpp

@@ -0,0 +1,14 @@
+#ifndef SubExtra_P_HPP
+#define SubExtra_P_HPP
+
+#include <QObject>
+
+class SubExtraPrivate : public QObject
+{
+  Q_OBJECT
+public:
+  SubExtraPrivate();
+  ~SubExtraPrivate();
+};
+
+#endif

+ 14 - 0
Tests/QtAutogen/MocInclude/Common/OtherUnderscoreSub_p.hpp

@@ -0,0 +1,14 @@
+#ifndef OtherUnderscoreSub_P_HPP
+#define OtherUnderscoreSub_P_HPP
+
+#include <QObject>
+
+class OtherUnderscoreSubPrivate : public QObject
+{
+  Q_OBJECT
+public:
+  OtherUnderscoreSubPrivate();
+  ~OtherUnderscoreSubPrivate();
+};
+
+#endif

+ 14 - 0
Tests/QtAutogen/MocInclude/Common/OtherUnderscore_p.hpp

@@ -0,0 +1,14 @@
+#ifndef OtherUnderscore_P_HPP
+#define OtherUnderscore_P_HPP
+
+#include <QObject>
+
+class OtherUnderscorePrivate : public QObject
+{
+  Q_OBJECT
+public:
+  OtherUnderscorePrivate();
+  ~OtherUnderscorePrivate();
+};
+
+#endif

+ 39 - 0
Tests/QtAutogen/MocInclude/Common/OwnDot.cpp

@@ -0,0 +1,39 @@
+#include "OwnDot.hpp"
+#include "OwnDot_p.h"
+
+class OwnDotLocal : public QObject
+{
+  Q_OBJECT
+public:
+  OwnDotLocal();
+  ~OwnDotLocal();
+};
+
+OwnDotLocal::OwnDotLocal()
+{
+}
+
+OwnDotLocal::~OwnDotLocal()
+{
+}
+
+OwnDotPrivate::OwnDotPrivate()
+{
+  OwnDotLocal localObj;
+}
+
+OwnDotPrivate::~OwnDotPrivate()
+{
+}
+
+OwnDot::OwnDot()
+  : d(new OwnDotPrivate)
+{
+}
+
+OwnDot::~OwnDot()
+{
+  delete d;
+}
+
+#include "OwnDot.moc"

+ 19 - 0
Tests/QtAutogen/MocInclude/Common/OwnDot.hpp

@@ -0,0 +1,19 @@
+#ifndef OwnDot_HPP
+#define OwnDot_HPP
+
+#include <QObject>
+
+// Object source comes with a .moc include
+class OwnDotPrivate;
+class OwnDot : public QObject
+{
+  Q_OBJECT
+public:
+  OwnDot();
+  ~OwnDot();
+
+private:
+  OwnDotPrivate* const d;
+};
+
+#endif

+ 40 - 0
Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore.cpp

@@ -0,0 +1,40 @@
+#include "OwnDotUnderscore.hpp"
+#include "OwnDotUnderscore_p.h"
+
+class OwnDotUnderscoreLocal : public QObject
+{
+  Q_OBJECT
+public:
+  OwnDotUnderscoreLocal();
+  ~OwnDotUnderscoreLocal();
+};
+
+OwnDotUnderscoreLocal::OwnDotUnderscoreLocal()
+{
+}
+
+OwnDotUnderscoreLocal::~OwnDotUnderscoreLocal()
+{
+}
+
+OwnDotUnderscorePrivate::OwnDotUnderscorePrivate()
+{
+  OwnDotUnderscoreLocal localObj;
+}
+
+OwnDotUnderscorePrivate::~OwnDotUnderscorePrivate()
+{
+}
+
+OwnDotUnderscore::OwnDotUnderscore()
+  : d(new OwnDotUnderscorePrivate)
+{
+}
+
+OwnDotUnderscore::~OwnDotUnderscore()
+{
+  delete d;
+}
+
+#include "OwnDotUnderscore.moc"
+#include "moc_OwnDotUnderscore.cpp"

+ 19 - 0
Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore.hpp

@@ -0,0 +1,19 @@
+#ifndef LOwnDotUnderscore_HPP
+#define LOwnDotUnderscore_HPP
+
+#include <QObject>
+
+// Object source comes with a .moc and a _moc include
+class OwnDotUnderscorePrivate;
+class OwnDotUnderscore : public QObject
+{
+  Q_OBJECT
+public:
+  OwnDotUnderscore();
+  ~OwnDotUnderscore();
+
+private:
+  OwnDotUnderscorePrivate* const d;
+};
+
+#endif

+ 14 - 0
Tests/QtAutogen/MocInclude/Common/OwnDotUnderscore_p.h

@@ -0,0 +1,14 @@
+#ifndef OwnDotUnderscore_P_HPP
+#define OwnDotUnderscore_P_HPP
+
+#include <QObject>
+
+class OwnDotUnderscorePrivate : public QObject
+{
+  Q_OBJECT
+public:
+  OwnDotUnderscorePrivate();
+  ~OwnDotUnderscorePrivate();
+};
+
+#endif

+ 14 - 0
Tests/QtAutogen/MocInclude/Common/OwnDot_p.h

@@ -0,0 +1,14 @@
+#ifndef OwnDot_P_HPP
+#define OwnDot_P_HPP
+
+#include <QObject>
+
+class OwnDotPrivate : public QObject
+{
+  Q_OBJECT
+public:
+  OwnDotPrivate();
+  ~OwnDotPrivate();
+};
+
+#endif

+ 22 - 0
Tests/QtAutogen/MocInclude/Common/OwnUnderscore.cpp

@@ -0,0 +1,22 @@
+#include "OwnUnderscore.hpp"
+#include "OwnUnderscore_p.h"
+
+OwnUnderscorePrivate::OwnUnderscorePrivate()
+{
+}
+
+OwnUnderscorePrivate::~OwnUnderscorePrivate()
+{
+}
+
+OwnUnderscore::OwnUnderscore()
+  : d(new OwnUnderscorePrivate)
+{
+}
+
+OwnUnderscore::~OwnUnderscore()
+{
+  delete d;
+}
+
+#include "moc_OwnUnderscore.cpp"

+ 19 - 0
Tests/QtAutogen/MocInclude/Common/OwnUnderscore.hpp

@@ -0,0 +1,19 @@
+#ifndef OwnUnderscore_HPP
+#define OwnUnderscore_HPP
+
+#include <QObject>
+
+// Object source comes with a _moc include
+class OwnUnderscorePrivate;
+class OwnUnderscore : public QObject
+{
+  Q_OBJECT
+public:
+  OwnUnderscore();
+  ~OwnUnderscore();
+
+private:
+  OwnUnderscorePrivate* const d;
+};
+
+#endif

+ 14 - 0
Tests/QtAutogen/MocInclude/Common/OwnUnderscore_p.h

@@ -0,0 +1,14 @@
+#ifndef OwnUnderscore_P_HPP
+#define OwnUnderscore_P_HPP
+
+#include <QObject>
+
+class OwnUnderscorePrivate : public QObject
+{
+  Q_OBJECT
+public:
+  OwnUnderscorePrivate();
+  ~OwnUnderscorePrivate();
+};
+
+#endif

+ 32 - 0
Tests/QtAutogen/MocInclude/Common/common.cpp.in

@@ -0,0 +1,32 @@
+#include "DualSub/Second/Second.hpp"
+#include "DualSubMocked.hpp"
+#include "ExternDot.hpp"
+#include "ExternDotGenerated.hpp"
+#include "None.hpp"
+#include "OtherUnderscore.hpp"
+#include "OtherUnderscoreSub.hpp"
+#include "OwnDot.hpp"
+#include "OwnDotUnderscore.hpp"
+#include "OwnUnderscore.hpp"
+#include "InIncludes/SubOwnDot.hpp"
+
+bool @COMMON_FUNCTION_NAME@()
+{
+  None objNone;
+  OwnUnderscore objOwnUnderscore;
+  OwnDot objOwnDot;
+  OwnDotUnderscore objOwnDotUnderscore;
+
+  OtherUnderscore objOtherUnderscore;
+  OtherUnderscoreSub objOtherUnderscoreSub;
+
+  Second second;
+  DualSubMocked dualSubMocked;
+
+  ExternDot objExternDot;
+  ExternDotGenerated objGeneratedExternDot;
+
+  InIncludes::SubOwnDot subOwnDot;
+
+  return true;
+}

+ 5 - 0
Tests/QtAutogen/MocInclude/Common/moc_MixedCustom.cpp.in

@@ -0,0 +1,5 @@
+
+void moc_MixedCustom(MixedCustom const & arg)
+{
+    (void)arg;
+}

+ 0 - 44
Tests/QtAutogen/MocInclude/EObjA.cpp

@@ -1,44 +0,0 @@
-#include "EObjA.hpp"
-#include "EObjAExtra.hpp"
-#include "EObjA_p.hpp"
-
-class EObjALocal : public QObject
-{
-  Q_OBJECT
-public:
-  EObjALocal();
-  ~EObjALocal();
-};
-
-EObjALocal::EObjALocal()
-{
-}
-
-EObjALocal::~EObjALocal()
-{
-}
-
-EObjAPrivate::EObjAPrivate()
-{
-  EObjALocal localObj;
-  EObjAExtra extraObj;
-}
-
-EObjAPrivate::~EObjAPrivate()
-{
-}
-
-EObjA::EObjA()
-  : d(new EObjAPrivate)
-{
-}
-
-EObjA::~EObjA()
-{
-  delete d;
-}
-
-// For EObjALocal
-#include "EObjA.moc"
-// - Not the own header
-#include "moc_EObjAExtra.cpp"

+ 0 - 19
Tests/QtAutogen/MocInclude/EObjA.hpp

@@ -1,19 +0,0 @@
-#ifndef EOBJA_HPP
-#define EOBJA_HPP
-
-#include <QObject>
-
-// Sources includes a moc_ includes of an extra object
-class EObjAPrivate;
-class EObjA : public QObject
-{
-  Q_OBJECT
-public:
-  EObjA();
-  ~EObjA();
-
-private:
-  EObjAPrivate* const d;
-};
-
-#endif

+ 0 - 20
Tests/QtAutogen/MocInclude/EObjAExtra.cpp

@@ -1,20 +0,0 @@
-#include "EObjAExtra.hpp"
-#include "EObjAExtra_p.hpp"
-
-EObjAExtraPrivate::EObjAExtraPrivate()
-{
-}
-
-EObjAExtraPrivate::~EObjAExtraPrivate()
-{
-}
-
-EObjAExtra::EObjAExtra()
-  : d(new EObjAExtraPrivate)
-{
-}
-
-EObjAExtra::~EObjAExtra()
-{
-  delete d;
-}

+ 0 - 18
Tests/QtAutogen/MocInclude/EObjAExtra.hpp

@@ -1,18 +0,0 @@
-#ifndef EOBJAEXTRA_HPP
-#define EOBJAEXTRA_HPP
-
-#include <QObject>
-
-class EObjAExtraPrivate;
-class EObjAExtra : public QObject
-{
-  Q_OBJECT
-public:
-  EObjAExtra();
-  ~EObjAExtra();
-
-private:
-  EObjAExtraPrivate* const d;
-};
-
-#endif

+ 0 - 14
Tests/QtAutogen/MocInclude/EObjAExtra_p.hpp

@@ -1,14 +0,0 @@
-#ifndef EOBJAEXTRA_P_HPP
-#define EOBJAEXTRA_P_HPP
-
-#include <QObject>
-
-class EObjAExtraPrivate : public QObject
-{
-  Q_OBJECT
-public:
-  EObjAExtraPrivate();
-  ~EObjAExtraPrivate();
-};
-
-#endif

+ 0 - 14
Tests/QtAutogen/MocInclude/EObjA_p.hpp

@@ -1,14 +0,0 @@
-#ifndef EOBJA_P_HPP
-#define EOBJA_P_HPP
-
-#include <QObject>
-
-class EObjAPrivate : public QObject
-{
-  Q_OBJECT
-public:
-  EObjAPrivate();
-  ~EObjAPrivate();
-};
-
-#endif

+ 0 - 45
Tests/QtAutogen/MocInclude/EObjB.cpp

@@ -1,45 +0,0 @@
-#include "EObjB.hpp"
-#include "EObjB_p.hpp"
-#include "subExtra/EObjBExtra.hpp"
-
-class EObjBLocal : public QObject
-{
-  Q_OBJECT
-public:
-  EObjBLocal();
-  ~EObjBLocal();
-};
-
-EObjBLocal::EObjBLocal()
-{
-}
-
-EObjBLocal::~EObjBLocal()
-{
-}
-
-EObjBPrivate::EObjBPrivate()
-{
-  EObjBLocal localObj;
-  EObjBExtra extraObj;
-}
-
-EObjBPrivate::~EObjBPrivate()
-{
-}
-
-EObjB::EObjB()
-  : d(new EObjBPrivate)
-{
-}
-
-EObjB::~EObjB()
-{
-  delete d;
-}
-
-// For EObjBLocal
-#include "EObjB.moc"
-// - Not the own header
-// - in a subdirectory
-#include "subExtra/moc_EObjBExtra.cpp"

+ 0 - 19
Tests/QtAutogen/MocInclude/EObjB.hpp

@@ -1,19 +0,0 @@
-#ifndef EOBJB_HPP
-#define EOBJB_HPP
-
-#include <QObject>
-
-// Sources includes a moc_ includes of an extra object in a subdirectory
-class EObjBPrivate;
-class EObjB : public QObject
-{
-  Q_OBJECT
-public:
-  EObjB();
-  ~EObjB();
-
-private:
-  EObjBPrivate* const d;
-};
-
-#endif

+ 0 - 14
Tests/QtAutogen/MocInclude/EObjB_p.hpp

@@ -1,14 +0,0 @@
-#ifndef EOBJB_P_HPP
-#define EOBJB_P_HPP
-
-#include <QObject>
-
-class EObjBPrivate : public QObject
-{
-  Q_OBJECT
-public:
-  EObjBPrivate();
-  ~EObjBPrivate();
-};
-
-#endif

+ 0 - 39
Tests/QtAutogen/MocInclude/LObjA.cpp

@@ -1,39 +0,0 @@
-#include "LObjA.hpp"
-#include "LObjA_p.h"
-
-class LObjALocal : public QObject
-{
-  Q_OBJECT
-public:
-  LObjALocal();
-  ~LObjALocal();
-};
-
-LObjALocal::LObjALocal()
-{
-}
-
-LObjALocal::~LObjALocal()
-{
-}
-
-LObjAPrivate::LObjAPrivate()
-{
-  LObjALocal localObj;
-}
-
-LObjAPrivate::~LObjAPrivate()
-{
-}
-
-LObjA::LObjA()
-  : d(new LObjAPrivate)
-{
-}
-
-LObjA::~LObjA()
-{
-  delete d;
-}
-
-#include "LObjA.moc"

+ 0 - 19
Tests/QtAutogen/MocInclude/LObjA.hpp

@@ -1,19 +0,0 @@
-#ifndef LOBJA_HPP
-#define LOBJA_HPP
-
-#include <QObject>
-
-// Object source comes with a .moc include
-class LObjAPrivate;
-class LObjA : public QObject
-{
-  Q_OBJECT
-public:
-  LObjA();
-  ~LObjA();
-
-private:
-  LObjAPrivate* const d;
-};
-
-#endif

+ 0 - 14
Tests/QtAutogen/MocInclude/LObjA_p.h

@@ -1,14 +0,0 @@
-#ifndef LOBJA_P_HPP
-#define LOBJA_P_HPP
-
-#include <QObject>
-
-class LObjAPrivate : public QObject
-{
-  Q_OBJECT
-public:
-  LObjAPrivate();
-  ~LObjAPrivate();
-};
-
-#endif

+ 0 - 40
Tests/QtAutogen/MocInclude/LObjB.cpp

@@ -1,40 +0,0 @@
-#include "LObjB.hpp"
-#include "LObjB_p.h"
-
-class LObjBLocal : public QObject
-{
-  Q_OBJECT
-public:
-  LObjBLocal();
-  ~LObjBLocal();
-};
-
-LObjBLocal::LObjBLocal()
-{
-}
-
-LObjBLocal::~LObjBLocal()
-{
-}
-
-LObjBPrivate::LObjBPrivate()
-{
-  LObjBLocal localObj;
-}
-
-LObjBPrivate::~LObjBPrivate()
-{
-}
-
-LObjB::LObjB()
-  : d(new LObjBPrivate)
-{
-}
-
-LObjB::~LObjB()
-{
-  delete d;
-}
-
-#include "LObjB.moc"
-#include "moc_LObjB.cpp"

+ 0 - 19
Tests/QtAutogen/MocInclude/LObjB.hpp

@@ -1,19 +0,0 @@
-#ifndef LLObjB_HPP
-#define LLObjB_HPP
-
-#include <QObject>
-
-// Object source comes with a .moc and a _moc include
-class LObjBPrivate;
-class LObjB : public QObject
-{
-  Q_OBJECT
-public:
-  LObjB();
-  ~LObjB();
-
-private:
-  LObjBPrivate* const d;
-};
-
-#endif

+ 0 - 14
Tests/QtAutogen/MocInclude/LObjB_p.h

@@ -1,14 +0,0 @@
-#ifndef LOBJB_P_HPP
-#define LOBJB_P_HPP
-
-#include <QObject>
-
-class LObjBPrivate : public QObject
-{
-  Q_OBJECT
-public:
-  LObjBPrivate();
-  ~LObjBPrivate();
-};
-
-#endif

+ 0 - 20
Tests/QtAutogen/MocInclude/ObjA.cpp

@@ -1,20 +0,0 @@
-#include "ObjA.hpp"
-#include "ObjA_p.h"
-
-ObjAPrivate::ObjAPrivate()
-{
-}
-
-ObjAPrivate::~ObjAPrivate()
-{
-}
-
-ObjA::ObjA()
-  : d(new ObjAPrivate)
-{
-}
-
-ObjA::~ObjA()
-{
-  delete d;
-}

+ 0 - 19
Tests/QtAutogen/MocInclude/ObjA.hpp

@@ -1,19 +0,0 @@
-#ifndef OBJA_HPP
-#define OBJA_HPP
-
-#include <QObject>
-
-// Object source comes without any _moc/.moc includes
-class ObjAPrivate;
-class ObjA : public QObject
-{
-  Q_OBJECT
-public:
-  ObjA();
-  ~ObjA();
-
-private:
-  ObjAPrivate* const d;
-};
-
-#endif

+ 0 - 14
Tests/QtAutogen/MocInclude/ObjA_p.h

@@ -1,14 +0,0 @@
-#ifndef OBJA_P_HPP
-#define OBJA_P_HPP
-
-#include <QObject>
-
-class ObjAPrivate : public QObject
-{
-  Q_OBJECT
-public:
-  ObjAPrivate();
-  ~ObjAPrivate();
-};
-
-#endif

+ 0 - 22
Tests/QtAutogen/MocInclude/ObjB.cpp

@@ -1,22 +0,0 @@
-#include "ObjB.hpp"
-#include "ObjB_p.h"
-
-ObjBPrivate::ObjBPrivate()
-{
-}
-
-ObjBPrivate::~ObjBPrivate()
-{
-}
-
-ObjB::ObjB()
-  : d(new ObjBPrivate)
-{
-}
-
-ObjB::~ObjB()
-{
-  delete d;
-}
-
-#include "moc_ObjB.cpp"

+ 0 - 19
Tests/QtAutogen/MocInclude/ObjB.hpp

@@ -1,19 +0,0 @@
-#ifndef ObjB_HPP
-#define ObjB_HPP
-
-#include <QObject>
-
-// Object source comes with a _moc include
-class ObjBPrivate;
-class ObjB : public QObject
-{
-  Q_OBJECT
-public:
-  ObjB();
-  ~ObjB();
-
-private:
-  ObjBPrivate* const d;
-};
-
-#endif

+ 0 - 14
Tests/QtAutogen/MocInclude/ObjB_p.h

@@ -1,14 +0,0 @@
-#ifndef OBJB_P_HPP
-#define OBJB_P_HPP
-
-#include <QObject>
-
-class ObjBPrivate : public QObject
-{
-  Q_OBJECT
-public:
-  ObjBPrivate();
-  ~ObjBPrivate();
-};
-
-#endif

+ 17 - 0
Tests/QtAutogen/MocInclude/Relaxed/CMakeLists.txt

@@ -0,0 +1,17 @@
+# Enable relaxed mode
+set(CMAKE_AUTOMOC_RELAXED_MODE TRUE)
+
+# Common test
+set(COMMON_FUNCTION_NAME commonRelaxed)
+configure_file(
+  "${COM_DIR}/common.cpp.in"
+  "${CMAKE_CURRENT_BINARY_DIR}/commonRelaxed.cpp")
+
+makeExecutable(libRelaxed)
+target_sources(libRelaxed PRIVATE
+  "${CMAKE_CURRENT_BINARY_DIR}/commonRelaxed.cpp"
+  RObjA.cpp
+  RObjB.cpp
+  RObjC.cpp
+  relaxed.cpp
+  )

+ 0 - 0
Tests/QtAutogen/MocIncludeRelaxed/RObjA.cpp → Tests/QtAutogen/MocInclude/Relaxed/RObjA.cpp


+ 0 - 0
Tests/QtAutogen/MocIncludeRelaxed/RObjA.hpp → Tests/QtAutogen/MocInclude/Relaxed/RObjA.hpp


+ 0 - 0
Tests/QtAutogen/MocIncludeRelaxed/RObjB.cpp → Tests/QtAutogen/MocInclude/Relaxed/RObjB.cpp


+ 0 - 0
Tests/QtAutogen/MocIncludeRelaxed/RObjB.hpp → Tests/QtAutogen/MocInclude/Relaxed/RObjB.hpp


+ 0 - 0
Tests/QtAutogen/MocIncludeRelaxed/RObjBExtra.hpp → Tests/QtAutogen/MocInclude/Relaxed/RObjBExtra.hpp


+ 0 - 0
Tests/QtAutogen/MocIncludeRelaxed/RObjC.cpp → Tests/QtAutogen/MocInclude/Relaxed/RObjC.cpp


+ 0 - 0
Tests/QtAutogen/MocIncludeRelaxed/RObjC.hpp → Tests/QtAutogen/MocInclude/Relaxed/RObjC.hpp


+ 21 - 0
Tests/QtAutogen/MocInclude/Relaxed/relaxed.cpp

@@ -0,0 +1,21 @@
+// AUTOMOC relaxed mode objects
+#include "RObjA.hpp"
+#include "RObjB.hpp"
+#include "RObjC.hpp"
+
+// Forward declaration
+bool commonRelaxed();
+
+int main(int argv, char** args)
+{
+  // Common tests
+  if (!commonRelaxed()) {
+    return -1;
+  }
+
+  // Relaxed tests
+  RObjA rObjA;
+  RObjB rObjB;
+  RObjC rObjC;
+  return 0;
+}

+ 0 - 11
Tests/QtAutogen/MocInclude/SObjA.cpp

@@ -1,11 +0,0 @@
-#include "SObjA.hpp"
-
-SObjA::SObjA()
-{
-}
-
-SObjA::~SObjA()
-{
-}
-
-#include "SObjA.moc"

+ 0 - 11
Tests/QtAutogen/MocInclude/SObjB.cpp.in

@@ -1,11 +0,0 @@
-#include "SObjB.hpp"
-
-SObjB::SObjB()
-{
-}
-
-SObjB::~SObjB()
-{
-}
-
-#include "SObjB.moc"

+ 0 - 15
Tests/QtAutogen/MocInclude/SObjB.hpp.in

@@ -1,15 +0,0 @@
-#ifndef SOBJB_HPP
-#define SOBJB_HPP
-
-#include <QObject>
-
-// Object source includes externally generated .moc file
-class SObjB : public QObject
-{
-  Q_OBJECT
-public:
-  SObjB();
-  ~SObjB();
-};
-
-#endif

+ 0 - 35
Tests/QtAutogen/MocInclude/SObjC.cpp

@@ -1,35 +0,0 @@
-#include "SObjC.hpp"
-
-void SObjCLocalFunction();
-
-class SObjCLocal : public QObject
-{
-  Q_OBJECT
-
-public:
-  SObjCLocal();
-  ~SObjCLocal();
-};
-
-SObjCLocal::SObjCLocal()
-{
-}
-
-SObjCLocal::~SObjCLocal()
-{
-}
-
-SObjC::SObjC()
-{
-  SObjCLocal localObject;
-  SObjCLocalFunction();
-}
-
-SObjC::~SObjC()
-{
-}
-
-#include "SObjC.moc"
-#include "moc_SObjC.cpp"
-// Include moc_ file for which the header is SKIP_AUTOMOC enabled
-#include "moc_SObjCExtra.cpp"

+ 0 - 15
Tests/QtAutogen/MocInclude/SObjC.hpp

@@ -1,15 +0,0 @@
-#ifndef SOBJC_HPP
-#define SOBJC_HPP
-
-#include <QObject>
-
-// Object source includes externally generated .moc file
-class SObjC : public QObject
-{
-  Q_OBJECT
-public:
-  SObjC();
-  ~SObjC();
-};
-
-#endif

+ 0 - 31
Tests/QtAutogen/MocInclude/SObjCExtra.cpp

@@ -1,31 +0,0 @@
-#include "SObjCExtra.hpp"
-
-class SObjCLocalExtra : public QObject
-{
-  Q_OBJECT
-
-public:
-  SObjCLocalExtra();
-  ~SObjCLocalExtra();
-};
-
-SObjCLocalExtra::SObjCLocalExtra()
-{
-}
-
-SObjCLocalExtra::~SObjCLocalExtra()
-{
-}
-
-SObjCExtra::SObjCExtra()
-{
-}
-
-SObjCExtra::~SObjCExtra()
-{
-}
-
-// Externally generated header moc
-#include "SObjCExtra_extMoc.cpp"
-// AUTOMOC generated source moc
-#include "SObjCExtra.moc"

+ 0 - 15
Tests/QtAutogen/MocInclude/SObjCExtra.hpp

@@ -1,15 +0,0 @@
-#ifndef SOBJCEXTRA_HPP
-#define SOBJCEXTRA_HPP
-
-#include <QObject>
-
-// Object source includes externally generated .moc file
-class SObjCExtra : public QObject
-{
-  Q_OBJECT
-public:
-  SObjCExtra();
-  ~SObjCExtra();
-};
-
-#endif

+ 0 - 4
Tests/QtAutogen/MocInclude/SObjCExtra.moc.in

@@ -1,4 +0,0 @@
-
-void SObjCLocalFunction()
-{
-}

+ 14 - 0
Tests/QtAutogen/MocInclude/Strict/CMakeLists.txt

@@ -0,0 +1,14 @@
+# Disable relaxed mode
+set(CMAKE_AUTOMOC_RELAXED_MODE FALSE)
+
+# Common test
+set(COMMON_FUNCTION_NAME commonStrict)
+configure_file(
+  "${COM_DIR}/common.cpp.in"
+  "${CMAKE_CURRENT_BINARY_DIR}/commonStrict.cpp")
+
+makeExecutable(libStrict)
+target_sources(libStrict PRIVATE
+  "${CMAKE_CURRENT_BINARY_DIR}/commonStrict.cpp"
+  strict.cpp
+  )

+ 7 - 0
Tests/QtAutogen/MocInclude/Strict/strict.cpp

@@ -0,0 +1,7 @@
+// Forward declaration
+bool commonStrict();
+
+int main(int argv, char** args)
+{
+  return commonStrict() ? 0 : -1;
+}

+ 9 - 0
Tests/QtAutogen/MocInclude/main.cpp

@@ -0,0 +1,9 @@
+
+// Forward declaration
+bool libStrict();
+bool libRelaxed();
+
+int main(int argv, char** args)
+{
+  return (libStrict() && libRelaxed()) ? 0 : -1;
+}

Some files were not shown because too many files changed in this diff