Browse Source

Autogen: Generate rcc wrapper file on demand

For multi configuration generators remove per-config
qrc_FOO_$<CONFIG>.cpp source file support.
Instead use a single source file qrc_FOO.cpp which is a wrapper
that includes the actual rcc generated qrc_FOO_CONFIG.cpp file.

This way, after a repeated configuration change, only the wrapper file
qrc_FOO.cpp must be regenerated to include the appropriate
qrc_FOO_CONFIG.cpp file.
Sebastian Holtermann 8 years ago
parent
commit
6d83757f26
2 changed files with 45 additions and 20 deletions
  1. 10 19
      Source/cmQtAutoGeneratorInitializer.cxx
  2. 35 1
      Source/cmQtAutoGenerators.cxx

+ 10 - 19
Source/cmQtAutoGeneratorInitializer.cxx

@@ -882,29 +882,20 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
 
           // Compose rcc output file name
           {
-            std::string rccOutBase = autogenBuildDir + "/";
-            rccOutBase += fpathCheckSum.getPart(absFile);
-            rccOutBase += "/qrc_";
-            rccOutBase +=
+            std::string rccBuildFile = autogenBuildDir + "/";
+            rccBuildFile += fpathCheckSum.getPart(absFile);
+            rccBuildFile += "/qrc_";
+            rccBuildFile +=
               cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile);
+            rccBuildFile += ".cpp";
 
             // Register rcc ouput file as generated
-            for (std::vector<std::string>::const_iterator it =
-                   suffixes.begin();
-                 it != suffixes.end(); ++it) {
-              std::string rccOutCfg = rccOutBase;
-              rccOutCfg += *it;
-              rccOutCfg += ".cpp";
-              AddGeneratedSource(makefile, rccOutCfg,
-                                 cmQtAutoGeneratorCommon::RCC);
-              autogenProvides.push_back(rccOutCfg);
-            }
+            AddGeneratedSource(makefile, rccBuildFile,
+                               cmQtAutoGeneratorCommon::RCC);
             // Add rcc output file to origin target sources
-            if (multiConfig) {
-              target->AddSource(rccOutBase + "_$<CONFIG>.cpp");
-            } else {
-              target->AddSource(rccOutBase + ".cpp");
-            }
+            target->AddSource(rccBuildFile);
+            // Register rcc ouput file as generated by the _autogen target
+            autogenProvides.push_back(rccBuildFile);
           }
 
           if (PropertyEnabled(sf, "GENERATED")) {

+ 35 - 1
Source/cmQtAutoGenerators.cxx

@@ -1664,10 +1664,10 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
 {
   bool rccGenerated = false;
   bool generateRcc = this->RccSettingsChanged;
-
   const std::string rccBuildFile =
     cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, rccOutputFile);
 
+  // Check if regeneration is required
   if (!generateRcc) {
     // Test if the resources list file is newer than build file
     generateRcc = FileAbsentOrOlder(rccBuildFile, rccInputFile);
@@ -1700,6 +1700,7 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
       }
     }
   }
+  // Regenerate on demand
   if (generateRcc) {
     // Log
     this->LogBold("Generating RCC source " + rccOutputFile);
@@ -1755,6 +1756,39 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
       this->RccRunFailed = true;
     }
   }
+  // For a multi configuration generator generate a wrapper file
+  if (!this->ConfigSuffix.empty() && !this->RccRunFailed) {
+    // Wrapper file name
+    const std::string cppSuffix = ".cpp";
+    const size_t suffixLength = this->ConfigSuffix.size() + cppSuffix.size();
+    const std::string wrapperFileRel =
+      rccOutputFile.substr(0, rccOutputFile.size() - suffixLength) + cppSuffix;
+    const std::string wrapperFileAbs = cmSystemTools::CollapseCombinedPath(
+      this->AutogenBuildDir, wrapperFileRel);
+    // Wrapper file content
+    std::string content =
+      "// This is an autogenerated configuration wrapper file. Do not edit.\n"
+      "#include \"";
+    content += cmsys::SystemTools::GetFilenameName(rccBuildFile);
+    content += "\"\n";
+    // Write content to file
+    if (this->FileDiffers(wrapperFileAbs, content)) {
+      // Write new wrapper file if the content differs
+      this->LogBold("Generating RCC wrapper " + wrapperFileRel);
+      if (!this->FileWrite("AutoRcc", wrapperFileAbs, content)) {
+        // Error
+        rccGenerated = false;
+        this->RccRunFailed = true;
+      }
+    } else if (rccGenerated) {
+      // Only touch wrapper file if the content matches
+      if (this->Verbose) {
+        this->LogInfo("Touching RCC wrapper " + wrapperFileRel);
+      }
+      cmSystemTools::Touch(wrapperFileAbs, false);
+    }
+  }
+
   return rccGenerated;
 }