From 513eb014eb691373dc06b76a441f45074ec9afbf Mon Sep 17 00:00:00 2001
From: Sebastian Holtermann <sebholt@xwmw.org>
Date: Wed, 10 Jan 2018 15:00:23 +0100
Subject: Autogen: Ignore not existing source files in cmMakefile

Until CMake 3.10 a list of source files that had the AUTOUIC_OPTIONS property
populated was kept in `cmMakefile::QtUiFilesWithOptions`.  In the process to
remove all AUTOUIC related code from `cmMakefile` for CMake 3.10, the pre
filtered list was replaced by a loop in `cmQtAutoGeneratorInitializer` over
all source files in the `cmMakefile`.  This loop introduced the problem that
file paths were computed for source files that weren't in the target's sources
and that might not even have existed.  If the path for an unused and not
existing file was computed a `cmake::FATAL_ERROR` with the error message
"Cannot find source file:" was thrown nevertheless.
This caused some projects to fail in CMake 3.10.

This patch adds a test for path errors in the loops in
`cmQtAutoGeneratorInitializer` that iterate over all source files in a
`cmMakefile`. If a path error appears, the file is silently ignored.
If the file is part of the target's sources, the path error will still be
caught in the loop over all the target's sources.

Closes #17573
Closes #17589
---
 Source/cmQtAutoGeneratorInitializer.cxx | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index 14743de..de0ba4f 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -475,10 +475,16 @@ void cmQtAutoGeneratorInitializer::InitCustomTargets()
   }
   // Read skip files from makefile sources
   if (this->MocEnabled || this->UicEnabled) {
-    const std::vector<cmSourceFile*>& allSources = makefile->GetSourceFiles();
-    for (cmSourceFile* sf : allSources) {
+    std::string pathError;
+    for (cmSourceFile* sf : makefile->GetSourceFiles()) {
       // sf->GetExtension() is only valid after sf->GetFullPath() ...
-      std::string const& fPath = sf->GetFullPath();
+      // 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 const& fPath = sf->GetFullPath(&pathError);
+      if (!pathError.empty()) {
+        pathError.clear();
+        continue;
+      }
       cmSystemTools::FileFormat const fileType =
         cmSystemTools::GetFileFormat(sf->GetExtension().c_str());
       if (!(fileType == cmSystemTools::CXX_FILE_FORMAT) &&
@@ -1188,9 +1194,16 @@ void cmQtAutoGeneratorInitializer::SetupCustomTargetsUic()
     std::vector<std::vector<std::string>> uiFileOptions;
     {
       std::string const uiExt = "ui";
+      std::string pathError;
       for (cmSourceFile* sf : makefile->GetSourceFiles()) {
         // sf->GetExtension() is only valid after sf->GetFullPath() ...
-        std::string const& fPath = sf->GetFullPath();
+        // 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 const& fPath = sf->GetFullPath(&pathError);
+        if (!pathError.empty()) {
+          pathError.clear();
+          continue;
+        }
         if (sf->GetExtension() == uiExt) {
           std::string const absFile = cmSystemTools::GetRealPath(fPath);
           // Check if the .ui file should be skipped
-- 
cgit v0.12


From d592bfc9f5f616249d85bbea94d8e76a666591a8 Mon Sep 17 00:00:00 2001
From: Sebastian Holtermann <sebholt@xwmw.org>
Date: Wed, 10 Jan 2018 15:17:02 +0100
Subject: Autogen: Ignore not existing source files in cmMakefile

Until CMake 3.10 a list of source files that had the AUTOUIC_OPTIONS property
populated was kept in `cmMakefile::QtUiFilesWithOptions`.  In the process to
remove all AUTOUIC related code from `cmMakefile` for CMake 3.10, the pre
filtered list was replaced by a loop in `cmQtAutoGeneratorInitializer` over
all source files in the `cmMakefile`.  This loop introduced the problem that
file paths were computed for source files that weren't in the target's sources
and that might not even have existed.  If the path for an unused and not
existing file was computed a `cmake::FATAL_ERROR` with the error message
"Cannot find source file:" was thrown nevertheless.
This caused some projects to fail in CMake 3.10.

This patch adds a test for path errors in the loops in
`cmQtAutoGeneratorInitializer` that iterate over all source files in a
`cmMakefile`. If a path error appears, the file is silently ignored.
If the file is part of the target's sources, the path error will still be
caught in the loop over all the target's sources.

This is the fix for CMake 3.10.1.
---
 Source/cmQtAutoGeneratorInitializer.cxx | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index b02d872..89568c3 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -361,11 +361,16 @@ static void SetupAcquireSkipFiles(cmQtAutoGenDigest const& digest,
 {
   // Read skip files from makefile sources
   {
-    const std::vector<cmSourceFile*>& allSources =
-      digest.Target->Makefile->GetSourceFiles();
-    for (cmSourceFile* sf : allSources) {
+    std::string pathError;
+    for (cmSourceFile* sf : digest.Target->Makefile->GetSourceFiles()) {
       // sf->GetExtension() is only valid after sf->GetFullPath() ...
-      std::string const& fPath = sf->GetFullPath();
+      // 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 const& fPath = sf->GetFullPath(&pathError);
+      if (!pathError.empty()) {
+        pathError.clear();
+        continue;
+      }
       cmSystemTools::FileFormat const fileType =
         cmSystemTools::GetFileFormat(sf->GetExtension().c_str());
       if (!(fileType == cmSystemTools::CXX_FILE_FORMAT) &&
@@ -540,9 +545,16 @@ static void SetupAutoTargetUic(cmQtAutoGenDigest const& digest,
     std::vector<std::vector<std::string>> uiFileOptions;
     {
       std::string const uiExt = "ui";
+      std::string pathError;
       for (cmSourceFile* sf : makefile->GetSourceFiles()) {
         // sf->GetExtension() is only valid after sf->GetFullPath() ...
-        std::string const& fPath = sf->GetFullPath();
+        // 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 const& fPath = sf->GetFullPath(&pathError);
+        if (!pathError.empty()) {
+          pathError.clear();
+          continue;
+        }
         if (sf->GetExtension() == uiExt) {
           std::string const absFile = cmSystemTools::GetRealPath(fPath);
           // Check if the file should be skipped
-- 
cgit v0.12