Просмотр исходного кода

Merge topic 'autogen-fixes'

09035319 Autogen: Pass explicit predefines header to moc if possible

Acked-by: Kitware Robot <[email protected]>
Merge-request: !671
Brad King 8 лет назад
Родитель
Сommit
2b7aecba16

+ 1 - 0
Modules/AutogenInfo.cmake.in

@@ -21,6 +21,7 @@ set(AM_MOC_INCLUDES @_moc_incs@)
 set(AM_MOC_OPTIONS @_moc_options@)
 set(AM_MOC_RELAXED_MODE @_moc_relaxed_mode@)
 set(AM_MOC_DEPEND_FILTERS @_moc_depend_filters@)
+set(AM_MOC_PREDEFS_CMD @_moc_predefs_cmd@)
 # UIC settings
 set(AM_UIC_SKIP @_uic_skip@)
 set(AM_UIC_TARGET_OPTIONS @_uic_target_options@)

+ 2 - 0
Modules/Compiler/Intel.cmake

@@ -22,5 +22,7 @@ else()
     string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Os")
     string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3")
     string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g")
+
+    set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}" "-QdM" "-P" "-Za" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
   endmacro()
 endif()

+ 1 - 0
Modules/Platform/Linux-GNU.cmake

@@ -12,4 +12,5 @@ macro(__linux_compiler_gnu lang)
   # We pass this for historical reasons.  Projects may have
   # executables that use dlopen but do not set ENABLE_EXPORTS.
   set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-rdynamic")
+  set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}" "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
 endmacro()

+ 41 - 0
Source/cmQtAutoGeneratorInitializer.cxx

@@ -96,6 +96,41 @@ static std::string GetQtMajorVersion(cmGeneratorTarget const* target)
   return qtMajorVersion;
 }
 
+static std::string GetQtMinorVersion(cmGeneratorTarget const* target,
+                                     const std::string& qtMajorVersion)
+{
+  cmMakefile* makefile = target->Target->GetMakefile();
+  std::string qtMinorVersion;
+  if (qtMajorVersion == "5") {
+    qtMinorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MINOR");
+  }
+  if (qtMinorVersion.empty()) {
+    qtMinorVersion = makefile->GetSafeDefinition("QT_VERSION_MINOR");
+  }
+
+  const char* targetQtVersion =
+    target->GetLinkInterfaceDependentStringProperty("QT_MINOR_VERSION", "");
+  if (targetQtVersion != CM_NULLPTR) {
+    qtMinorVersion = targetQtVersion;
+  }
+  return qtMinorVersion;
+}
+
+static bool QtVersionGreaterOrEqual(const std::string& major,
+                                    const std::string& minor,
+                                    unsigned long requestMajor,
+                                    unsigned long requestMinor)
+{
+  unsigned long majorUL(0);
+  unsigned long minorUL(0);
+  if (cmSystemTools::StringToULong(major.c_str(), &majorUL) &&
+      cmSystemTools::StringToULong(minor.c_str(), &minorUL)) {
+    return (majorUL > requestMajor) ||
+      (majorUL == requestMajor && minorUL >= requestMinor);
+  }
+  return false;
+}
+
 static void GetCompileDefinitionsAndDirectories(
   cmGeneratorTarget const* target, const std::string& config,
   std::string& incs, std::string& defs)
@@ -258,6 +293,12 @@ static void MocSetupAutoTarget(
   AddDefinitionEscaped(makefile, "_moc_depend_filters",
                        GetSafeProperty(target, "AUTOMOC_DEPEND_FILTERS"));
 
+  if (QtVersionGreaterOrEqual(
+        qtMajorVersion, GetQtMinorVersion(target, qtMajorVersion), 5, 8)) {
+    AddDefinitionEscaped(
+      makefile, "_moc_predefs_cmd",
+      makefile->GetSafeDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND"));
+  }
   // Moc includes and compile definitions
   {
     std::string _moc_incs;

+ 60 - 3
Source/cmQtAutoGenerators.cxx

@@ -360,6 +360,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
   InfoGet(makefile, "AM_QT_MOC_EXECUTABLE", this->MocExecutable);
   InfoGet(makefile, "AM_QT_UIC_EXECUTABLE", this->UicExecutable);
   InfoGet(makefile, "AM_QT_RCC_EXECUTABLE", this->RccExecutable);
+
+  InfoGet(makefile, "AM_MOC_PREDEFS_CMD", this->MocPredefsCmd);
   // Check Qt version
   if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) {
     this->LogError("AutoGen: Error: Unsupported Qt version: " +
@@ -579,6 +581,12 @@ void cmQtAutoGenerators::Init(cmMakefile* makefile)
 
   this->MocCppFilenameAbs = this->CurrentBinaryDir + this->MocCppFilenameRel;
 
+  // Moc predefs file
+  if (!this->MocPredefsCmd.empty()) {
+    this->MocPredefsFileRel = this->AutogenBuildSubDir + "moc_predefs.h";
+    this->MocPredefsFileAbs = this->CurrentBinaryDir + this->MocPredefsFileRel;
+  }
+
   // Init file path checksum generator
   fpathCheckSum.setupParentDirs(this->CurrentSourceDir, this->CurrentBinaryDir,
                                 this->ProjectSourceDir,
@@ -1142,6 +1150,50 @@ bool cmQtAutoGenerators::MocGenerateAll(
     return true;
   }
 
+  // Generate moc_predefs
+  if (!this->MocPredefsCmd.empty()) {
+    if (!this->MakeParentDirectory(this->MocPredefsFileAbs)) {
+      this->LogError("AutoMoc: Error creating directory for " +
+                     this->MocPredefsFileRel);
+      return false;
+    }
+    this->LogBold("Generating MOC predefs " + this->MocPredefsFileRel);
+
+    std::vector<std::string> cmd = this->MocPredefsCmd;
+    cmd.insert(cmd.end(), this->MocIncludes.begin(), this->MocIncludes.end());
+    for (std::vector<std::string>::const_iterator it =
+           this->MocDefinitions.begin();
+         it != this->MocDefinitions.end(); ++it) {
+      cmd.push_back("-D" + (*it));
+    }
+    cmd.insert(cmd.end(), this->MocOptions.begin(), this->MocOptions.end());
+
+    std::string output;
+    bool moc_predefsGenerated = this->RunCommand(cmd, output, false);
+    if (!moc_predefsGenerated) {
+      return false;
+    }
+
+    // actually write the file
+    cmsys::ofstream outfile;
+    outfile.open(this->MocPredefsFileAbs.c_str(), std::ios::trunc);
+    if (!outfile) {
+      moc_predefsGenerated = false;
+      this->LogError("AutoMoc: Error opening " + this->MocPredefsFileRel);
+    } else {
+      outfile << output;
+      // Check for write errors
+      if (!outfile.good()) {
+        moc_predefsGenerated = false;
+        this->LogError("AutoMoc: Error writing " + this->MocPredefsFileRel);
+      }
+    }
+
+    if (!moc_predefsGenerated) {
+      return false;
+    }
+  }
+
   bool mocCompFileGenerated = false;
   bool mocCompChanged = false;
 
@@ -1305,6 +1357,10 @@ bool cmQtAutoGenerators::MocGenerateFile(
         cmd.push_back("-D" + (*it));
       }
       cmd.insert(cmd.end(), this->MocOptions.begin(), this->MocOptions.end());
+      if (!this->MocPredefsFileAbs.empty()) {
+        cmd.push_back("--include");
+        cmd.push_back(this->MocPredefsFileAbs);
+      }
 #ifdef _WIN32
       cmd.push_back("-DWIN32");
 #endif
@@ -1805,7 +1861,7 @@ bool cmQtAutoGenerators::MakeParentDirectory(const std::string& filename) const
  * @return True on success
  */
 bool cmQtAutoGenerators::RunCommand(const std::vector<std::string>& command,
-                                    std::string& output) const
+                                    std::string& output, bool verbose) const
 {
   // Log command
   if (this->Verbose) {
@@ -1813,8 +1869,9 @@ bool cmQtAutoGenerators::RunCommand(const std::vector<std::string>& command,
   }
   // Execute command
   int retVal = 0;
-  bool res =
-    cmSystemTools::RunSingleCommand(command, &output, &output, &retVal);
+  bool res = cmSystemTools::RunSingleCommand(
+    command, &output, &output, &retVal, CM_NULLPTR,
+    verbose ? cmSystemTools::OUTPUT_MERGE : cmSystemTools::OUTPUT_NONE);
   return (res && (retVal == 0));
 }
 

+ 6 - 2
Source/cmQtAutoGenerators.h

@@ -143,8 +143,8 @@ private:
                              const char* basePrefix,
                              const char* baseSuffix) const;
   bool MakeParentDirectory(const std::string& filename) const;
-  bool RunCommand(const std::vector<std::string>& command,
-                  std::string& output) const;
+  bool RunCommand(const std::vector<std::string>& command, std::string& output,
+                  bool verbose = true) const;
 
   bool FindHeader(std::string& header, const std::string& testBasePath) const;
 
@@ -177,6 +177,8 @@ private:
   // - Moc
   std::string MocCppFilenameRel;
   std::string MocCppFilenameAbs;
+  std::string MocPredefsFileRel;
+  std::string MocPredefsFileAbs;
   std::vector<std::string> MocSkipList;
   std::vector<std::string> MocIncludePaths;
   std::vector<std::string> MocIncludes;
@@ -198,6 +200,8 @@ private:
   MacroFilter MacroFilters[2];
   cmsys::RegularExpression RegExpMocInclude;
   cmsys::RegularExpression RegExpUicInclude;
+  // - moc_predefs
+  std::vector<std::string> MocPredefsCmd;
   // - Flags
   bool IncludeProjectDirsBefore;
   bool Verbose;