Browse Source

Merge topic 'fix-Qt-autogen'

f7ae1d8a QtAutogen: Short-circut some logic when moc is not available.
4b989d5f QtAutogen: Separate source file processing from AUTOMOC.
c48d877d QtAutogen: Make some methods appropriately file-static.
394e86df QtAutogen: Fix autouic target options in the presence of a config.
964d7f2a QtAutogen: Remove unused variables.
0d934efd QtAutogen: Remove read of SKIP_AUTOUIC target property.
321e348e QtAutogen: Use Qt 4 IMPORTED targets to find executable locations.
e96683b0 Qt4: Use IMPORTED executable names with custom commands.
e6182f5d Qt4: Create IMPORTED executable targets for all Qt executables.
Brad King 12 years ago
parent
commit
bbc82d85e5

+ 1 - 1
Modules/AutogenInfo.cmake.in

@@ -1,4 +1,4 @@
-set(AM_SOURCES @_moc_files@ )
+set(AM_SOURCES @_cpp_files@ )
 set(AM_RCC_SOURCES @_rcc_files@ )
 set(AM_SKIP_MOC @_skip_moc@ )
 set(AM_SKIP_UIC @_skip_uic@ )

+ 22 - 64
Modules/FindQt4.cmake

@@ -1185,71 +1185,29 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
     set(QT_LINGUIST_EXECUTABLE NOTFOUND)
   endif()
 
-  find_program(QT_MOC_EXECUTABLE
-    NAMES moc-qt4 moc moc4
-    PATHS ${QT_BINARY_DIR}
-    NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-    )
-
-  find_program(QT_UIC_EXECUTABLE
-    NAMES uic-qt4 uic uic4
-    PATHS ${QT_BINARY_DIR}
-    NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-    )
-
-  find_program(QT_UIC3_EXECUTABLE
-    NAMES uic3
-    PATHS ${QT_BINARY_DIR}
-    NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-    )
-
-  find_program(QT_RCC_EXECUTABLE
-    NAMES rcc
-    PATHS ${QT_BINARY_DIR}
-    NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-    )
-
-  find_program(QT_DBUSCPP2XML_EXECUTABLE
-    NAMES qdbuscpp2xml
-    PATHS ${QT_BINARY_DIR}
-    NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-    )
-
-  find_program(QT_DBUSXML2CPP_EXECUTABLE
-    NAMES qdbusxml2cpp
-    PATHS ${QT_BINARY_DIR}
-    NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-    )
-
-  find_program(QT_LUPDATE_EXECUTABLE
-    NAMES lupdate-qt4 lupdate lupdate4
-    PATHS ${QT_BINARY_DIR}
-    NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-    )
-
-  find_program(QT_LRELEASE_EXECUTABLE
-    NAMES lrelease-qt4 lrelease lrelease4
-    PATHS ${QT_BINARY_DIR}
-    NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-    )
-
-  find_program(QT_QCOLLECTIONGENERATOR_EXECUTABLE
-    NAMES qcollectiongenerator-qt4 qcollectiongenerator
-    PATHS ${QT_BINARY_DIR}
-    NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-    )
-
-  find_program(QT_DESIGNER_EXECUTABLE
-    NAMES designer-qt4 designer designer4
-    PATHS ${QT_BINARY_DIR}
-    NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-    )
+  macro(_find_qt4_program VAR NAME)
+    find_program(${VAR}
+      NAMES ${ARGN}
+      PATHS ${QT_BINARY_DIR}
+      NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+      )
+    if (${VAR} AND NOT TARGET ${NAME})
+      add_executable(${NAME} IMPORTED)
+      set_property(TARGET ${NAME} PROPERTY IMPORTED_LOCATION ${${VAR}})
+    endif()
+  endmacro()
 
-  find_program(QT_LINGUIST_EXECUTABLE
-    NAMES linguist-qt4 linguist linguist4
-    PATHS ${QT_BINARY_DIR}
-    NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-    )
+  _find_qt4_program(QT_MOC_EXECUTABLE Qt4::moc moc-qt4 moc moc4)
+  _find_qt4_program(QT_UIC_EXECUTABLE Qt4::uic uic-qt4 uic uic4)
+  _find_qt4_program(QT_UIC3_EXECUTABLE Qt4::uic3 uic3)
+  _find_qt4_program(QT_RCC_EXECUTABLE Qt4::rcc rcc)
+  _find_qt4_program(QT_DBUSCPP2XML_EXECUTABLE Qt4::qdbuscpp2xml qdbuscpp2xml)
+  _find_qt4_program(QT_DBUSXML2CPP_EXECUTABLE Qt4::qdbusxml2cpp qdbusxml2cpp)
+  _find_qt4_program(QT_LUPDATE_EXECUTABLE Qt4::lupdate lupdate-qt4 lupdate lupdate4)
+  _find_qt4_program(QT_LRELEASE_EXECUTABLE Qt4::lrelease lrelease-qt4 lrelease lrelease4)
+  _find_qt4_program(QT_QCOLLECTIONGENERATOR_EXECUTABLE Qt4::qcollectiongenerator qcollectiongenerator-qt4 qcollectiongenerator)
+  _find_qt4_program(QT_DESIGNER_EXECUTABLE Qt4::designer designer-qt4 designer designer4)
+  _find_qt4_program(QT_LINGUIST_EXECUTABLE Qt4::linguist linguist-qt4 linguist linguist4)
 
   if (QT_MOC_EXECUTABLE)
      set(QT_WRAP_CPP "YES")

+ 9 - 9
Modules/Qt4Macros.cmake

@@ -140,7 +140,7 @@ macro (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target)
 
   set(_moc_extra_parameters_file @${_moc_parameters_file})
   add_custom_command(OUTPUT ${outfile}
-                      COMMAND ${QT_MOC_EXECUTABLE} ${_moc_extra_parameters_file}
+                      COMMAND Qt4::moc ${_moc_extra_parameters_file}
                       DEPENDS ${infile}
                       ${_moc_working_dir}
                       VERBATIM)
@@ -191,7 +191,7 @@ macro (QT4_WRAP_UI outfiles )
     get_filename_component(infile ${it} ABSOLUTE)
     set(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.h)
     add_custom_command(OUTPUT ${outfile}
-      COMMAND ${QT_UIC_EXECUTABLE}
+      COMMAND Qt4::uic
       ARGS ${ui_options} -o ${outfile} ${infile}
       MAIN_DEPENDENCY ${infile} VERBATIM)
     set(${outfiles} ${${outfiles}} ${outfile})
@@ -238,7 +238,7 @@ macro (QT4_ADD_RESOURCES outfiles )
     endif()
 
     add_custom_command(OUTPUT ${outfile}
-      COMMAND ${QT_RCC_EXECUTABLE}
+      COMMAND Qt4::rcc
       ARGS ${rcc_options} -name ${outfilename} -o ${outfile} ${infile}
       MAIN_DEPENDENCY ${infile}
       DEPENDS ${_RC_DEPENDS} "${out_depends}" VERBATIM)
@@ -272,7 +272,7 @@ macro(QT4_ADD_DBUS_INTERFACE _sources _interface _basename)
   endif()
 
   add_custom_command(OUTPUT "${_impl}" "${_header}"
-      COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} ${_params} -p ${_basename} ${_infile}
+      COMMAND Qt4::qdbusxml2cpp ${_params} -p ${_basename} ${_infile}
       DEPENDS ${_infile} VERBATIM)
 
   set_source_files_properties("${_impl}" PROPERTIES SKIP_AUTOMOC TRUE)
@@ -318,7 +318,7 @@ macro(QT4_GENERATE_DBUS_INTERFACE _header) # _customName OPTIONS -some -options
   endif ()
 
   add_custom_command(OUTPUT ${_target}
-      COMMAND ${QT_DBUSCPP2XML_EXECUTABLE} ${_qt4_dbus_options} ${_in_file} -o ${_target}
+      COMMAND Qt4::qdbuscpp2xml ${_qt4_dbus_options} ${_in_file} -o ${_target}
       DEPENDS ${_in_file} VERBATIM
   )
 endmacro()
@@ -342,12 +342,12 @@ macro(QT4_ADD_DBUS_ADAPTOR _sources _xml_file _include _parentClass) # _optional
 
   if(_optionalClassName)
     add_custom_command(OUTPUT "${_impl}" "${_header}"
-       COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} -m -a ${_basename} -c ${_optionalClassName} -i ${_include} -l ${_parentClass} ${_infile}
+       COMMAND Qt4::qdbuscpp2xml -m -a ${_basename} -c ${_optionalClassName} -i ${_include} -l ${_parentClass} ${_infile}
        DEPENDS ${_infile} VERBATIM
     )
   else()
     add_custom_command(OUTPUT "${_impl}" "${_header}"
-       COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} -m -a ${_basename} -i ${_include} -l ${_parentClass} ${_infile}
+       COMMAND Qt4::qdbusxml2cpp -m -a ${_basename} -i ${_include} -l ${_parentClass} ${_infile}
        DEPENDS ${_infile} VERBATIM
      )
   endif()
@@ -445,7 +445,7 @@ macro(QT4_CREATE_TRANSLATION _qm_files)
        file(WRITE ${_ts_pro} "SOURCES =${_pro_srcs}\nINCLUDEPATH =${_pro_includes}\n")
      endif()
      add_custom_command(OUTPUT ${_ts_file}
-        COMMAND ${QT_LUPDATE_EXECUTABLE}
+        COMMAND Qt4::lupdate
         ARGS ${_lupdate_options} ${_ts_pro} ${_my_dirs} -ts ${_ts_file}
         DEPENDS ${_my_sources} ${_ts_pro} VERBATIM)
    endforeach()
@@ -466,7 +466,7 @@ macro(QT4_ADD_TRANSLATION _qm_files)
     endif()
 
     add_custom_command(OUTPUT ${qm}
-       COMMAND ${QT_LRELEASE_EXECUTABLE}
+       COMMAND Qt4::lrelease
        ARGS ${_abs_FILE} -qm ${qm}
        DEPENDS ${_abs_FILE} VERBATIM
     )

+ 157 - 161
Source/cmQtAutoGenerators.cxx

@@ -115,6 +115,15 @@ static void copyTargetProperty(cmTarget* destinationTarget,
 }
 
 
+static std::string ReadAll(const std::string& filename)
+{
+  cmsys::ifstream file(filename.c_str());
+  cmsys_ios::stringstream stream;
+  stream << file.rdbuf();
+  file.close();
+  return stream.str();
+}
+
 cmQtAutoGenerators::cmQtAutoGenerators()
 :Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0)
 ,ColorOutput(true)
@@ -222,7 +231,6 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target)
   if (target->GetPropertyAsBool("AUTORCC"))
     {
     toolNames.push_back("rcc");
-    this->InitializeAutoRccTarget(target);
     }
 
   std::string tools = toolNames[0];
@@ -371,6 +379,13 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target)
   std::map<std::string, std::string> configDefines;
   std::map<std::string, std::string> configUicOptions;
 
+  if (target->GetPropertyAsBool("AUTOMOC")
+      || target->GetPropertyAsBool("AUTOUIC"))
+    {
+    this->SetupSourceFiles(target);
+    }
+  makefile->AddDefinition("_cpp_files",
+          cmLocalGenerator::EscapeForCMake(this->Sources.c_str()).c_str());
   if (target->GetPropertyAsBool("AUTOMOC"))
     {
     this->SetupAutoMocTarget(target, autogenTargetName,
@@ -439,23 +454,20 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target)
     }
 }
 
-void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
-                          const std::string &autogenTargetName,
-                          std::map<std::string, std::string> &configIncludes,
-                          std::map<std::string, std::string> &configDefines)
+void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
 {
   cmMakefile* makefile = target->GetMakefile();
 
-  std::string _moc_files;
-  std::string _moc_headers;
   const char* sepFiles = "";
   const char* sepHeaders = "";
 
   std::vector<cmSourceFile*> srcFiles;
   target->GetSourceFiles(srcFiles);
 
-  std::string skip_moc;
-  const char *sep = "";
+  const char *skipMocSep = "";
+  const char *skipUicSep = "";
+
+  std::vector<cmSourceFile*> newRccFiles;
 
   for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
       fileIt != srcFiles.end();
@@ -464,48 +476,83 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
     cmSourceFile* sf = *fileIt;
     std::string absFile = cmsys::SystemTools::GetRealPath(
                                                     sf->GetFullPath().c_str());
-    bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
+    bool skipMoc = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
     bool generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"));
 
+    if(cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC")))
+      {
+      this->SkipUic += skipUicSep;
+      this->SkipUic += absFile;
+      skipUicSep = ";";
+      }
+
+    std::string ext = sf->GetExtension();
+    if (ext == "qrc"
+        && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")))
+      {
+      std::string basename = cmsys::SystemTools::
+                                    GetFilenameWithoutLastExtension(absFile);
+
+      std::string rcc_output_file = makefile->GetCurrentOutputDirectory();
+      rcc_output_file += "/qrc_" + basename + ".cpp";
+      makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
+                              rcc_output_file.c_str(), false);
+      cmSourceFile* rccCppSource
+              = makefile->GetOrCreateSource(rcc_output_file.c_str(), true);
+      newRccFiles.push_back(rccCppSource);
+      }
+
     if (!generated)
       {
-      if (skip)
+      if (skipMoc)
         {
-        skip_moc += sep;
-        skip_moc += absFile;
-        sep = ";";
+        this->SkipMoc += skipMocSep;
+        this->SkipMoc += absFile;
+        skipMocSep = ";";
         }
       else
         {
-        std::string ext = sf->GetExtension();
         cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(
                                                                 ext.c_str());
         if (fileType == cmSystemTools::CXX_FILE_FORMAT)
           {
-          _moc_files += sepFiles;
-          _moc_files += absFile;
+          this->Sources += sepFiles;
+          this->Sources += absFile;
           sepFiles = ";";
           }
         else if (fileType == cmSystemTools::HEADER_FILE_FORMAT)
           {
-          _moc_headers += sepHeaders;
-          _moc_headers += absFile;
+          this->Headers += sepHeaders;
+          this->Headers += absFile;
           sepHeaders = ";";
           }
         }
       }
     }
 
+  for(std::vector<cmSourceFile*>::const_iterator fileIt = newRccFiles.begin();
+      fileIt != newRccFiles.end();
+      ++fileIt)
+    {
+    const_cast<cmTarget*>(target)->AddSourceFile(*fileIt);
+    }
+}
+
+void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
+                          const std::string &autogenTargetName,
+                          std::map<std::string, std::string> &configIncludes,
+                          std::map<std::string, std::string> &configDefines)
+{
+  cmMakefile* makefile = target->GetMakefile();
+
   const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS");
   std::string _moc_options = (tmp!=0 ? tmp : "");
   makefile->AddDefinition("_moc_options",
           cmLocalGenerator::EscapeForCMake(_moc_options.c_str()).c_str());
-  makefile->AddDefinition("_moc_files",
-          cmLocalGenerator::EscapeForCMake(_moc_files.c_str()).c_str());
   makefile->AddDefinition("_skip_moc",
-          cmLocalGenerator::EscapeForCMake(skip_moc.c_str()).c_str());
+          cmLocalGenerator::EscapeForCMake(this->SkipMoc.c_str()).c_str());
   makefile->AddDefinition("_moc_headers",
-          cmLocalGenerator::EscapeForCMake(_moc_headers.c_str()).c_str());
+          cmLocalGenerator::EscapeForCMake(this->Headers.c_str()).c_str());
   bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE");
   makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE");
 
@@ -549,9 +596,6 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
       }
     }
 
-  const char *qtMoc = makefile->GetSafeDefinition("QT_MOC_EXECUTABLE");
-  makefile->AddDefinition("_qt_moc_executable", qtMoc);
-
   const char *qtVersion = makefile->GetDefinition("_target_qt_version");
   if (strcmp(qtVersion, "5") == 0)
     {
@@ -564,13 +608,21 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
       }
     makefile->AddDefinition("_qt_moc_executable", qt5Moc->GetLocation(0));
     }
-  else
+  else if (strcmp(qtVersion, "4") == 0)
     {
-    if (strcmp(qtVersion, "4") != 0)
+    cmTarget *qt4Moc = makefile->FindTargetToUse("Qt4::moc");
+    if (!qt4Moc)
       {
-      cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and "
-                          "Qt 5 ", autogenTargetName.c_str());
+      cmSystemTools::Error("Qt4::moc target not found ",
+                          autogenTargetName.c_str());
+      return;
       }
+    makefile->AddDefinition("_qt_moc_executable", qt4Moc->GetLocation(0));
+    }
+  else
+    {
+    cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and "
+                        "Qt 5 ", autogenTargetName.c_str());
     }
 }
 
@@ -641,50 +693,22 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
 {
   cmMakefile *makefile = target->GetMakefile();
 
-  const char *qtUic = makefile->GetSafeDefinition("QT_UIC_EXECUTABLE");
-  makefile->AddDefinition("_qt_uic_executable", qtUic);
-
-  std::vector<cmSourceFile*> srcFiles;
-  target->GetSourceFiles(srcFiles);
-
-  std::string skip_uic;
-  const char *sep = "";
-
-  bool skip  = target->GetPropertyAsBool("SKIP_AUTOUIC");
-
   std::set<cmStdString> skipped;
+  std::vector<std::string> skipVec;
+  cmSystemTools::ExpandListArgument(this->SkipUic.c_str(), skipVec);
 
-  for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
-      fileIt != srcFiles.end();
-      ++fileIt)
+  for (std::vector<std::string>::const_iterator li = skipVec.begin();
+       li != skipVec.end(); ++li)
     {
-    cmSourceFile* sf = *fileIt;
-    std::string absFile = cmsys::SystemTools::GetRealPath(
-                                                    sf->GetFullPath().c_str());
-    if (!skip)
-      {
-      skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC"));
-      }
-
-    if (skip)
-      {
-      skip_uic += sep;
-      skip_uic += absFile;
-      sep = ";";
-      skipped.insert(absFile);
-      }
+    skipped.insert(*li);
     }
 
   makefile->AddDefinition("_skip_uic",
-          cmLocalGenerator::EscapeForCMake(skip_uic.c_str()).c_str());
+          cmLocalGenerator::EscapeForCMake(this->SkipUic.c_str()).c_str());
 
   std::vector<cmSourceFile*> uiFilesWithOptions
                                         = makefile->GetQtUiFilesWithOptions();
 
-  std::string uiFileFiles;
-  std::string uiFileOptions;
-  sep = "";
-
   const char *qtVersion = makefile->GetDefinition("_target_qt_version");
 
   std::string _uic_opts;
@@ -713,6 +737,10 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
       }
     }
 
+  std::string uiFileFiles;
+  std::string uiFileOptions;
+  const char* sep = "";
+
   for(std::vector<cmSourceFile*>::const_iterator fileIt =
       uiFilesWithOptions.begin();
       fileIt != uiFilesWithOptions.end();
@@ -747,20 +775,27 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
     if (!qt5Uic)
       {
       // Project does not use Qt5Widgets, but has AUTOUIC ON anyway
-      makefile->RemoveDefinition("_qt_uic_executable");
       }
     else
       {
       makefile->AddDefinition("_qt_uic_executable", qt5Uic->GetLocation(0));
       }
     }
-  else
+  else if (strcmp(qtVersion, "4") == 0)
     {
-    if (strcmp(qtVersion, "4") != 0)
+    cmTarget *qt4Uic = makefile->FindTargetToUse("Qt4::uic");
+    if (!qt4Uic)
       {
-      cmSystemTools::Error("The CMAKE_AUTOUIC feature supports only Qt 4 and "
-                          "Qt 5 ", targetName);
+      cmSystemTools::Error("Qt4::uic target not found ",
+                          targetName);
+      return;
       }
+    makefile->AddDefinition("_qt_uic_executable", qt4Uic->GetLocation(0));
+    }
+  else
+    {
+    cmSystemTools::Error("The CMAKE_AUTOUIC feature supports only Qt 4 and "
+                        "Qt 5 ", targetName);
     }
 }
 
@@ -807,51 +842,6 @@ void cmQtAutoGenerators::MergeRccOptions(std::vector<std::string> &opts,
   opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
 }
 
-void cmQtAutoGenerators::InitializeAutoRccTarget(cmTarget* target)
-{
-  cmMakefile *makefile = target->GetMakefile();
-
-  std::vector<cmSourceFile*> srcFiles;
-  target->GetSourceFiles(srcFiles);
-
-  std::vector<cmSourceFile*> newFiles;
-
-  for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
-      fileIt != srcFiles.end();
-      ++fileIt)
-    {
-    cmSourceFile* sf = *fileIt;
-    std::string ext = sf->GetExtension();
-    if (ext == "qrc")
-      {
-      std::string absFile = cmsys::SystemTools::GetRealPath(
-                                                  sf->GetFullPath().c_str());
-      bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"));
-
-      if (!skip)
-        {
-        std::string basename = cmsys::SystemTools::
-                                      GetFilenameWithoutLastExtension(absFile);
-
-        std::string rcc_output_file = makefile->GetCurrentOutputDirectory();
-        rcc_output_file += "/qrc_" + basename + ".cpp";
-        makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
-                                rcc_output_file.c_str(), false);
-        cmSourceFile* rccCppSource
-                = makefile->GetOrCreateSource(rcc_output_file.c_str(), true);
-        newFiles.push_back(rccCppSource);
-        }
-      }
-    }
-
-  for(std::vector<cmSourceFile*>::const_iterator fileIt = newFiles.begin();
-      fileIt != newFiles.end();
-      ++fileIt)
-    {
-    target->AddSourceFile(*fileIt);
-    }
-}
-
 void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
 {
   std::string _rcc_files;
@@ -927,9 +917,6 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
   makefile->AddDefinition("_qt_rcc_options_options",
             cmLocalGenerator::EscapeForCMake(rccFileOptions.c_str()).c_str());
 
-  const char *qtRcc = makefile->GetSafeDefinition("QT_RCC_EXECUTABLE");
-  makefile->AddDefinition("_qt_rcc_executable", qtRcc);
-
   const char* targetName = target->GetName();
   if (strcmp(qtVersion, "5") == 0)
     {
@@ -942,21 +929,45 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
       }
     makefile->AddDefinition("_qt_rcc_executable", qt5Rcc->GetLocation(0));
     }
-  else
+  else if (strcmp(qtVersion, "4") == 0)
     {
-    if (strcmp(qtVersion, "4") != 0)
+    cmTarget *qt4Rcc = makefile->FindTargetToUse("Qt4::rcc");
+    if (!qt4Rcc)
       {
-      cmSystemTools::Error("The CMAKE_AUTORCC feature supports only Qt 4 and "
-                          "Qt 5 ", targetName);
+      cmSystemTools::Error("Qt4::rcc target not found ",
+                          targetName);
+      return;
       }
+    makefile->AddDefinition("_qt_rcc_executable", qt4Rcc->GetLocation(0));
+    }
+  else
+    {
+    cmSystemTools::Error("The CMAKE_AUTORCC feature supports only Qt 4 and "
+                        "Qt 5 ", targetName);
     }
 }
 
+static cmGlobalGenerator* CreateGlobalGenerator(cmake* cm,
+                                                  const char* targetDirectory)
+{
+  cmGlobalGenerator* gg = new cmGlobalGenerator();
+  gg->SetCMakeInstance(cm);
+
+  cmLocalGenerator* lg = gg->CreateLocalGenerator();
+  lg->GetMakefile()->SetHomeOutputDirectory(targetDirectory);
+  lg->GetMakefile()->SetStartOutputDirectory(targetDirectory);
+  lg->GetMakefile()->SetHomeDirectory(targetDirectory);
+  lg->GetMakefile()->SetStartDirectory(targetDirectory);
+  gg->SetCurrentLocalGenerator(lg);
+
+  return gg;
+}
+
 bool cmQtAutoGenerators::Run(const char* targetDirectory, const char *config)
 {
   bool success = true;
   cmake cm;
-  cmGlobalGenerator* gg = this->CreateGlobalGenerator(&cm, targetDirectory);
+  cmGlobalGenerator* gg = CreateGlobalGenerator(&cm, targetDirectory);
   cmMakefile* makefile = gg->GetCurrentLocalGenerator()->GetMakefile();
 
   this->ReadAutogenInfoFile(makefile, targetDirectory, config);
@@ -977,24 +988,6 @@ bool cmQtAutoGenerators::Run(const char* targetDirectory, const char *config)
   return success;
 }
 
-
-cmGlobalGenerator* cmQtAutoGenerators::CreateGlobalGenerator(cmake* cm,
-                                                  const char* targetDirectory)
-{
-  cmGlobalGenerator* gg = new cmGlobalGenerator();
-  gg->SetCMakeInstance(cm);
-
-  cmLocalGenerator* lg = gg->CreateLocalGenerator();
-  lg->GetMakefile()->SetHomeOutputDirectory(targetDirectory);
-  lg->GetMakefile()->SetStartOutputDirectory(targetDirectory);
-  lg->GetMakefile()->SetHomeDirectory(targetDirectory);
-  lg->GetMakefile()->SetStartDirectory(targetDirectory);
-  gg->SetCurrentLocalGenerator(lg);
-
-  return gg;
-}
-
-
 bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile,
                                       const char* targetDirectory,
                                       const char *config)
@@ -1027,6 +1020,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile,
   this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE");
   this->UicExecutable = makefile->GetSafeDefinition("AM_QT_UIC_EXECUTABLE");
   this->RccExecutable = makefile->GetSafeDefinition("AM_QT_RCC_EXECUTABLE");
+  {
   std::string compileDefsPropOrig = "AM_MOC_COMPILE_DEFINITIONS";
   std::string compileDefsProp = compileDefsPropOrig;
   if(config)
@@ -1037,6 +1031,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile,
   const char *compileDefs = makefile->GetDefinition(compileDefsProp.c_str());
   this->MocCompileDefinitionsStr = compileDefs ? compileDefs
                   : makefile->GetSafeDefinition(compileDefsPropOrig.c_str());
+  }
+  {
   std::string includesPropOrig = "AM_MOC_INCLUDES";
   std::string includesProp = includesPropOrig;
   if(config)
@@ -1047,6 +1043,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile,
   const char *includes = makefile->GetDefinition(includesProp.c_str());
   this->MocIncludesStr = includes ? includes
                       : makefile->GetSafeDefinition(includesPropOrig.c_str());
+  }
   this->MocOptionsStr = makefile->GetSafeDefinition("AM_MOC_OPTIONS");
   this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR");
   this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR");
@@ -1066,7 +1063,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile,
                         = makefile->GetSafeDefinition(uicOptionsProp.c_str());
   cmSystemTools::ExpandListArgument(
       uicTargetOptions ? uicTargetOptions
-                       : makefile->GetSafeDefinition(includesPropOrig.c_str()),
+                    : makefile->GetSafeDefinition(uicOptionsPropOrig.c_str()),
     this->UicTargetOptions);
   const char *uicOptionsOptions
                       = makefile->GetSafeDefinition("AM_UIC_OPTIONS_OPTIONS");
@@ -1412,7 +1409,7 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
   if (!automocCppChanged)
     {
     // compare contents of the _automoc.cpp file
-    const std::string oldContents = this->ReadAll(this->OutMocCppFilename);
+    const std::string oldContents = ReadAll(this->OutMocCppFilename);
     if (oldContents == automocSource)
       {
       // nothing changed: don't touch the _automoc.cpp file
@@ -1440,13 +1437,19 @@ void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename,
               "[\n][ \t]*#[ \t]*include[ \t]+"
               "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
 
-  const std::string contentsString = this->ReadAll(absFilename);
+  const std::string contentsString = ReadAll(absFilename);
   if (contentsString.empty())
     {
     std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n"
               << std::endl;
     return;
     }
+  this->ParseForUic(absFilename, contentsString, includedUis);
+  if (this->MocExecutable.empty())
+    {
+    return;
+    }
+
   const std::string absPath = cmsys::SystemTools::GetFilenamePath(
                    cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/';
   const std::string scannedFileBasename = cmsys::SystemTools::
@@ -1575,7 +1578,6 @@ void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename,
       matchOffset += mocIncludeRegExp.end();
       } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
     }
-  this->ParseForUic(absFilename, contentsString, includedUis);
 
   // In this case, check whether the scanned file itself contains a Q_OBJECT.
   // If this is the case, the moc_foo.cpp should probably be generated from
@@ -1623,13 +1625,19 @@ void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename,
               "[\n][ \t]*#[ \t]*include[ \t]+"
               "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
 
-  const std::string contentsString = this->ReadAll(absFilename);
+  const std::string contentsString = ReadAll(absFilename);
   if (contentsString.empty())
     {
     std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n"
               << std::endl;
     return;
     }
+  this->ParseForUic(absFilename, contentsString, includedUis);
+  if (this->MocExecutable.empty())
+    {
+    return;
+    }
+
   const std::string absPath = cmsys::SystemTools::GetFilenamePath(
                    cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/';
   const std::string scannedFileBasename = cmsys::SystemTools::
@@ -1708,7 +1716,6 @@ void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename,
       matchOffset += mocIncludeRegExp.end();
       } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
     }
-  this->ParseForUic(absFilename, contentsString, includedUis);
 
   // In this case, check whether the scanned file itself contains a Q_OBJECT.
   // If this is the case, the moc_foo.cpp should probably be generated from
@@ -1736,7 +1743,7 @@ void cmQtAutoGenerators::ParseForUic(const std::string& absFilename,
     {
     return;
     }
-  const std::string contentsString = this->ReadAll(absFilename);
+  const std::string contentsString = ReadAll(absFilename);
   if (contentsString.empty())
     {
     std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n"
@@ -1831,9 +1838,10 @@ void cmQtAutoGenerators::ParseHeaders(const std::set<std::string>& absHeaders,
       ++hIt)
     {
     const std::string& headerName = *hIt;
-    const std::string contents = this->ReadAll(headerName);
+    const std::string contents = ReadAll(headerName);
 
-    if (includedMocs.find(headerName) == includedMocs.end())
+    if (!this->MocExecutable.empty()
+        && includedMocs.find(headerName) == includedMocs.end())
       {
       if (this->Verbose)
         {
@@ -1956,7 +1964,6 @@ bool cmQtAutoGenerators::GenerateUi(const std::string& uiFileName)
     std::vector<cmStdString> command;
     command.push_back(this->UicExecutable);
 
-    std::string options;
     std::vector<std::string> opts = this->UicTargetOptions;
     std::map<std::string, std::string>::const_iterator optionIt
             = this->UicOptions.find(ui_input_file);
@@ -2031,7 +2038,6 @@ bool cmQtAutoGenerators::GenerateQrc()
                                                       &sourceNewerThanQrc);
     if (this->GenerateAll || !success || sourceNewerThanQrc >= 0)
       {
-      std::string options;
       std::map<std::string, std::string>::const_iterator optionIt
               = this->RccOptions.find(*si);
       if (optionIt != this->RccOptions.end())
@@ -2112,13 +2118,3 @@ bool cmQtAutoGenerators::EndsWith(const std::string& str,
     }
   return (str.substr(str.length() - with.length(), with.length()) == with);
 }
-
-
-std::string cmQtAutoGenerators::ReadAll(const std::string& filename)
-{
-  cmsys::ifstream file(filename.c_str());
-  cmsys_ios::stringstream stream;
-  stream << file.rdbuf();
-  file.close();
-  return stream.str();
-}

+ 1 - 5
Source/cmQtAutoGenerators.h

@@ -25,6 +25,7 @@ public:
 
   bool InitializeAutogenTarget(cmTarget* target);
   void SetupAutoGenerateTarget(cmTarget const* target);
+  void SetupSourceFiles(cmTarget const* target);
 
 private:
   void SetupAutoMocTarget(cmTarget const* target,
@@ -33,12 +34,8 @@ private:
                           std::map<std::string, std::string> &configDefines);
   void SetupAutoUicTarget(cmTarget const* target,
                         std::map<std::string, std::string> &configUicOptions);
-  void InitializeAutoRccTarget(cmTarget* target);
   void SetupAutoRccTarget(cmTarget const* target);
 
-  cmGlobalGenerator* CreateGlobalGenerator(cmake* cm,
-                                           const char* targetDirectory);
-
   bool ReadAutogenInfoFile(cmMakefile* makefile,
                            const char* targetDirectory,
                            const char *config);
@@ -82,7 +79,6 @@ private:
   std::string Join(const std::vector<std::string>& lst, char separator);
   bool EndsWith(const std::string& str, const std::string& with);
   bool StartsWith(const std::string& str, const std::string& with);
-  std::string ReadAll(const std::string& filename);
 
   void MergeUicOptions(std::vector<std::string> &opts,
                        const std::vector<std::string> &fileOpts, bool isQt5);

+ 13 - 2
Tests/Qt4And5Automoc/CMakeLists.txt

@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12)
 
 project(Qt4And5Automoc)
 
@@ -7,7 +8,17 @@ find_package(Qt5Core REQUIRED)
 set(CMAKE_AUTOMOC ON)
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
-add_executable(qt4_exe main_qt4.cpp)
+macro(generate_main_file VERSION)
+  configure_file("${CMAKE_CURRENT_SOURCE_DIR}/main.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/main_qt${VERSION}.cpp" COPYONLY)
+  file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/main_qt${VERSION}.cpp"
+    "#include \"main_qt${VERSION}.moc\"\n"
+  )
+endmacro()
+
+generate_main_file(4)
+generate_main_file(5)
+
+add_executable(qt4_exe "${CMAKE_CURRENT_BINARY_DIR}/main_qt4.cpp")
 target_link_libraries(qt4_exe Qt4::QtCore)
-add_executable(qt5_exe main_qt5.cpp)
+add_executable(qt5_exe "${CMAKE_CURRENT_BINARY_DIR}/main_qt5.cpp")
 target_link_libraries(qt5_exe Qt5::Core)

+ 0 - 0
Tests/Qt4And5Automoc/main.cpp → Tests/Qt4And5Automoc/main.cpp.in


+ 0 - 4
Tests/Qt4And5Automoc/main_qt4.cpp

@@ -1,4 +0,0 @@
-
-#include "main.cpp"
-
-#include "main_qt4.moc"

+ 0 - 4
Tests/Qt4And5Automoc/main_qt5.cpp

@@ -1,4 +0,0 @@
-
-#include "main.cpp"
-
-#include "main_qt5.moc"

+ 14 - 0
Tests/QtAutogen/CMakeLists.txt

@@ -11,6 +11,11 @@ if (QT_TEST_VERSION STREQUAL 4)
   include(UseQt4)
 
   set(QT_QTCORE_TARGET Qt4::QtCore)
+
+  macro(qtx_wrap_cpp)
+    qt4_wrap_cpp(${ARGN})
+  endmacro()
+
 else()
   if (NOT QT_TEST_VERSION STREQUAL 5)
     message(SEND_ERROR "Invalid Qt version specified.")
@@ -25,6 +30,11 @@ else()
   if(Qt5_POSITION_INDEPENDENT_CODE)
     set(CMAKE_POSITION_INDEPENDENT_CODE ON)
   endif()
+
+  macro(qtx_wrap_cpp)
+    qt5_wrap_cpp(${ARGN})
+  endmacro()
+
 endif()
 
 
@@ -77,3 +87,7 @@ set_target_properties(empty PROPERTIES AUTOMOC TRUE)
 target_link_libraries(empty no_link_language)
 add_library(no_link_language STATIC empty.h)
 set_target_properties(no_link_language PROPERTIES AUTOMOC TRUE)
+
+qtx_wrap_cpp(uicOnlyMoc uiconly.h)
+add_executable(uiconly uiconly.cpp ${uicOnlyMoc})
+target_link_libraries(uiconly ${QT_LIBRARIES})

+ 13 - 0
Tests/QtAutogen/uiconly.cpp

@@ -0,0 +1,13 @@
+
+#include "uiconly.h"
+
+UicOnly::UicOnly(QWidget *parent)
+  : QWidget(parent), ui(new Ui::UicOnly)
+{
+
+}
+
+int main()
+{
+  return 0;
+}

+ 20 - 0
Tests/QtAutogen/uiconly.h

@@ -0,0 +1,20 @@
+
+#ifndef UIC_ONLY_H
+#define UIC_ONLY_H
+
+#include <QWidget>
+#include <memory>
+
+#include "ui_uiconly.h"
+
+class UicOnly : public QWidget
+{
+  Q_OBJECT
+public:
+  explicit UicOnly(QWidget *parent = 0);
+
+private:
+  const std::auto_ptr<Ui::UicOnly> ui;
+};
+
+#endif

+ 24 - 0
Tests/QtAutogen/uiconly.ui

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UicOnly</class>
+ <widget class="QWidget" name="UicOnly">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <item>
+    <widget class="QTreeView" name="treeView"/>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>