瀏覽代碼

Autogen: Initializer file type scanning optimizations

Sebastian Holtermann 8 年之前
父節點
當前提交
54ec2a8bcf
共有 1 個文件被更改,包括 91 次插入73 次删除
  1. 91 73
      Source/cmQtAutoGeneratorInitializer.cxx

+ 91 - 73
Source/cmQtAutoGeneratorInitializer.cxx

@@ -720,8 +720,6 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
   const std::string autogenBuildDir = GetAutogenTargetBuildDir(target);
   const std::string workingDirectory =
     cmSystemTools::CollapseFullPath("", makefile->GetCurrentBinaryDirectory());
-  const std::string qtMajorVersion = GetQtMajorVersion(target);
-  const std::string rccCommand = RccGetExecutable(target, qtMajorVersion);
   const std::vector<std::string> suffixes = GetConfigurationSuffixes(makefile);
   std::set<std::string> autogenDependsSet;
   std::vector<std::string> autogenProvides;
@@ -837,99 +835,119 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
       }
     }
   }
+
+  // Extract relevant source files
+  std::vector<std::string> generatedSources;
+  std::vector<std::pair<std::string, bool> > qrcSources;
   {
-    cmFilePathChecksum fpathCheckSum(makefile);
-    // Iterate over all source files
+    const std::string qrcExt = "qrc";
     std::vector<cmSourceFile*> srcFiles;
     target->GetConfigCommonSourceFiles(srcFiles);
     for (std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
          fileIt != srcFiles.end(); ++fileIt) {
       cmSourceFile* sf = *fileIt;
-      if (!sf->GetPropertyAsBool("SKIP_AUTOGEN")) {
-        std::string const& ext = sf->GetExtension();
-        // Add generated file that will be scanned by moc or uic to
-        // the dependencies
-        if (mocEnabled || uicEnabled) {
-          const cmSystemTools::FileFormat fileType =
-            cmSystemTools::GetFileFormat(ext.c_str());
-          if ((fileType == cmSystemTools::CXX_FILE_FORMAT) ||
-              (fileType == cmSystemTools::HEADER_FILE_FORMAT)) {
-            if (sf->GetPropertyAsBool("GENERATED")) {
-              if ((mocEnabled && !sf->GetPropertyAsBool("SKIP_AUTOMOC")) ||
-                  (uicEnabled && !sf->GetPropertyAsBool("SKIP_AUTOUIC"))) {
-                autogenDependsSet.insert(
-                  cmsys::SystemTools::GetRealPath(sf->GetFullPath()));
-#if defined(_WIN32) && !defined(__CYGWIN__)
-                // Cannot use PRE_BUILD with generated files
-                usePRE_BUILD = false;
-#endif
-              }
+      if (sf->GetPropertyAsBool("SKIP_AUTOGEN")) {
+        continue;
+      }
+      // sf->GetExtension() is only valid after sf->GetFullPath() ...
+      const std::string& fPath = sf->GetFullPath();
+      const std::string& ext = sf->GetExtension();
+      // Register generated files that will be scanned by moc or uic
+      if (mocEnabled || uicEnabled) {
+        const cmSystemTools::FileFormat fileType =
+          cmSystemTools::GetFileFormat(ext.c_str());
+        if ((fileType == cmSystemTools::CXX_FILE_FORMAT) ||
+            (fileType == cmSystemTools::HEADER_FILE_FORMAT)) {
+          if (sf->GetPropertyAsBool("GENERATED")) {
+            if ((mocEnabled && !sf->GetPropertyAsBool("SKIP_AUTOMOC")) ||
+                (uicEnabled && !sf->GetPropertyAsBool("SKIP_AUTOUIC"))) {
+              generatedSources.push_back(
+                cmsys::SystemTools::GetRealPath(fPath));
             }
           }
         }
-        // Process rcc enabled files
-        if (rccEnabled && (ext == "qrc") &&
-            !sf->GetPropertyAsBool("SKIP_AUTORCC")) {
-          const std::string absFile =
-            cmsys::SystemTools::GetRealPath(sf->GetFullPath());
+      }
+      // Register rcc enabled files
+      if (rccEnabled && (ext == qrcExt) &&
+          !sf->GetPropertyAsBool("SKIP_AUTORCC")) {
+        qrcSources.push_back(
+          std::pair<std::string, bool>(cmsys::SystemTools::GetRealPath(fPath),
+                                       sf->GetPropertyAsBool("GENERATED")));
+      }
+    }
+    // cmGeneratorTarget::GetConfigCommonSourceFiles computes the target's
+    // 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.
+    target->ClearSourcesCache();
+  }
 
-          // Compose rcc output file name
-          {
-            std::string rccBuildFile = autogenBuildDir + "/";
-            rccBuildFile += fpathCheckSum.getPart(absFile);
-            rccBuildFile += "/qrc_";
-            rccBuildFile +=
-              cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile);
-            rccBuildFile += ".cpp";
-
-            // Register rcc ouput file as generated
-            AddGeneratedSource(target, rccBuildFile,
-                               cmQtAutoGeneratorCommon::RCC);
-            // Register rcc ouput file as generated by the _autogen target
-            autogenProvides.push_back(rccBuildFile);
-          }
+  if (!generatedSources.empty()) {
+    for (std::vector<std::string>::const_iterator it =
+           generatedSources.begin();
+         it != generatedSources.end(); ++it) {
+      autogenDependsSet.insert(*it);
+    }
+  }
 
-          if (sf->GetPropertyAsBool("GENERATED")) {
-            // Add generated qrc file to the dependencies
-            autogenDependsSet.insert(absFile);
+  if (!qrcSources.empty()) {
+    const std::string qtMajorVersion = GetQtMajorVersion(target);
+    const std::string rccCommand = RccGetExecutable(target, qtMajorVersion);
+    const cmFilePathChecksum fpathCheckSum(makefile);
+    for (std::vector<std::pair<std::string, bool> >::const_iterator it =
+           qrcSources.begin();
+         it != qrcSources.end(); ++it) {
+      const std::string& absFile = it->first;
+
+      // Compose rcc output file name
+      {
+        std::string rccBuildFile = autogenBuildDir + "/";
+        rccBuildFile += fpathCheckSum.getPart(absFile);
+        rccBuildFile += "/qrc_";
+        rccBuildFile +=
+          cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile);
+        rccBuildFile += ".cpp";
+
+        // Register rcc ouput file as generated
+        AddGeneratedSource(target, rccBuildFile, cmQtAutoGeneratorCommon::RCC);
+        // Register rcc ouput file as generated by the _autogen target
+        autogenProvides.push_back(rccBuildFile);
+      }
+
+      if (it->second) {
+        // Add generated qrc file to the dependencies
+        autogenDependsSet.insert(absFile);
+      } else {
+        // Run cmake again when .qrc file changes
+        makefile->AddCMakeDependFile(absFile);
+        // Add the qrc input files to the dependencies
+        {
+          std::string error;
+          std::vector<std::string> extraDepends;
+          if (cmQtAutoGeneratorCommon::RccListInputs(
+                qtMajorVersion, rccCommand, absFile, extraDepends, &error)) {
+            autogenDependsSet.insert(extraDepends.begin(), extraDepends.end());
           } else {
-            // Run cmake again when .qrc file changes
-            makefile->AddCMakeDependFile(absFile);
-            // Add the qrc input files to the dependencies
-            {
-              std::string error;
-              std::vector<std::string> extraDepends;
-              if (cmQtAutoGeneratorCommon::RccListInputs(
-                    qtMajorVersion, rccCommand, absFile, extraDepends,
-                    &error)) {
-                autogenDependsSet.insert(extraDepends.begin(),
-                                         extraDepends.end());
-              } else {
-                cmSystemTools::Error(error.c_str());
-              }
-            }
+            cmSystemTools::Error(error.c_str());
           }
-#if defined(_WIN32) && !defined(__CYGWIN__)
-          // Cannot use PRE_BUILD because the resource files themselves
-          // may not be sources within the target so VS may not know the
-          // target needs to re-build at all.
-          usePRE_BUILD = false;
-#endif
         }
       }
     }
   }
 
-  // cmGeneratorTarget::GetConfigCommonSourceFiles computes the target's
-  // 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.
-  target->ClearSourcesCache();
-
   // Convert std::set to std::vector
   const std::vector<std::string> autogenDepends(autogenDependsSet.begin(),
                                                 autogenDependsSet.end());
 #if defined(_WIN32) && !defined(__CYGWIN__)
+  if (usePRE_BUILD) {
+    if (!generatedSources.empty() || !qrcSources.empty()) {
+      // - Cannot use PRE_BUILD with generated files
+      // - Cannot use PRE_BUILD because the resource files themselves
+      // may not be sources within the target so VS may not know the
+      // target needs to re-build at all.
+      usePRE_BUILD = false;
+    }
+  }
   if (usePRE_BUILD) {
     // If the autogen target depends on an other target don't use PRE_BUILD
     for (std::vector<std::string>::const_iterator it = autogenDepends.begin();